fixed bug to upload large file.

This commit is contained in:
Yoshihiro OKUMURA 2024-07-04 12:33:57 +09:00
parent 55265e69a4
commit 020ef8835a
Signed by: orrisroot
GPG Key ID: 470AA444C92904B2
8 changed files with 53 additions and 23 deletions

View File

@ -1,7 +1,14 @@
{
"version": "0.2",
"language": "en,en-gb",
"ignoreWords": ["followlinks", "getframe", "pycache", "pydantic", "UNLCK"],
"ignoreWords": [
"followlinks",
"getframe",
"pycache",
"pydantic",
"toolbelt",
"UNLCK"
],
"words": [
"chacl",
"kikan",

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2023 Neuroinformatics Unit, RIKEN CBS
Copyright (c) 2023- Neuroinformatics Unit, RIKEN CBS
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -80,6 +80,7 @@ Upload the file or directory
```shell
mdrs upload ./sample.dat neurodata:/NIU/Repository/TEST/
mdrs upload -r ./dataset neurodata:/NIU/Repository/TEST/
mdrs upload -r -s ./dataset neurodata:/NIU/Repository/TEST/
```
### download
@ -115,8 +116,8 @@ mdrs cp -r neurodata:/NIU/Repository/TEST/dataset neurodata:/NIU/Repository/TEST
Remove the file or folder
```shell
mdrs rm neurodata:/NIU/Repository/TEST2/sample2.dat
mdrs rm -r neurodata:/NIU/Repository/TEST2/dataset
mdrs rm neurodata:/NIU/Repository/TEST/sample.dat
mdrs rm -r neurodata:/NIU/Repository/TEST/dataset
```
### chacl
@ -126,7 +127,7 @@ Change the folder access level
```shell
mdrs chacl private neurodata:/NIU/Repository/Private
mdrs chacl cbs_open -r neurodata:/NIU/Repository/CBS_Open
mdrs chacl pw_open -r -p FOLDER_PASSWORD neurodata:/NIU/Repository/PW_Open
mdrs chacl pw_open -r -p PW_OPEN_PASSWORD neurodata:/NIU/Repository/PW_Open
```
### metadata

View File

@ -1 +1 @@
1.3.1
1.3.4

View File

@ -1,8 +1,10 @@
import mimetypes
import os
from typing import Any, Final
from pydantic import TypeAdapter
from pydantic.dataclasses import dataclass
from requests_toolbelt.multipart.encoder import MultipartEncoder
from mdrsclient.api.base import BaseApi
from mdrsclient.api.utils import token_check
@ -17,6 +19,7 @@ class FilesApiCreateResponse:
class FilesApi(BaseApi):
ENTRYPOINT: Final[str] = "v3/files/"
FALLBACK_MIMETYPE: Final[str] = "application/octet-stream"
def retrieve(self, id: str) -> File:
# print(self.__class__.__name__ + "::" + sys._getframe().f_code.co_name)
@ -30,30 +33,42 @@ class FilesApi(BaseApi):
# print(self.__class__.__name__ + "::" + sys._getframe().f_code.co_name)
url = self.ENTRYPOINT
token_check(self.connection)
data: dict[str, str | int] = {"folder_id": folder_id}
data: dict[str, str | int] | MultipartEncoder = {}
try:
with open(os.path.realpath(path), mode="rb") as fp:
response = self.connection.post(url, data=data, files={"file": fp})
data = MultipartEncoder(
fields={"folder_id": folder_id, "file": (os.path.basename(path), fp, self._get_mime_type(path))}
)
response = self.connection.post(url, data=data, headers={"Content-Type": data.content_type})
self._raise_response_error(response)
ret = TypeAdapter(FilesApiCreateResponse).validate_python(response.json())
except OSError:
raise UnexpectedException(f"Could not open `{path}` file.")
except MemoryError:
raise UnexpectedException("Out of memory.")
except Exception as e:
print(e)
raise UnexpectedException(e)
return ret.id
def update(self, file: File, path: str | None) -> bool:
# print(self.__class__.__name__ + "::" + sys._getframe().f_code.co_name)
url = self.ENTRYPOINT + file.id + "/"
token_check(self.connection)
data: dict[str, str | int] | MultipartEncoder = {}
if path is not None:
# update file body
try:
with open(os.path.realpath(path), mode="rb") as fp:
response = self.connection.put(url, files={"file": fp})
data = MultipartEncoder(fields={"file": (os.path.basename(path), fp, self._get_mime_type(path))})
response = self.connection.put(url, data=data, headers={"Content-Type": data.content_type})
except OSError:
raise UnexpectedException(f"Could not open `{path}` file.")
except MemoryError:
raise UnexpectedException("Out of memory.")
else:
# update metadata
data: dict[str, str | int] = {"name": file.name, "description": file.description}
data = {"name": file.name, "description": file.description}
response = self.connection.put(url, data=data)
self._raise_response_error(response)
return True
@ -106,3 +121,9 @@ class FilesApi(BaseApi):
except PermissionError:
print(f"Cannot create file `{path}`: Permission denied.")
return True
def _get_mime_type(self, path: str) -> str:
mt = mimetypes.guess_type(path)
if mt:
return mt[0] or self.FALLBACK_MIMETYPE
return self.FALLBACK_MIMETYPE

View File

@ -106,4 +106,4 @@ class UploadCommand(BaseCommand):
file_api.update(file, info.path)
print(os.path.join(info.folder.path, basename))
except MDRSException as e:
print(f"API Error: {e}")
print(f"Error: {e}")

View File

@ -1,9 +1,9 @@
import platform
import threading
from io import BufferedReader
from typing import TypedDict
from requests import Response, Session
from requests_toolbelt.multipart.encoder import MultipartEncoder
# Unpack is new in 3.11
from typing_extensions import Unpack
@ -21,14 +21,14 @@ class _KwArgsMDRSConnectionGet(TypedDict, total=False):
class _KwArgsMDRSConnectionPost(TypedDict, total=False):
params: dict[str, str | int]
data: dict[str, str | int]
files: dict[str, BufferedReader]
data: dict[str, str | int] | MultipartEncoder
headers: dict[str, str]
class _KwArgsMDRSConnectionPut(TypedDict, total=False):
params: dict[str, str | int]
data: dict[str, str | int]
files: dict[str, BufferedReader]
data: dict[str, str | int] | MultipartEncoder
headers: dict[str, str]
class _KwArgsMDRSConnectionDelete(TypedDict, total=False):

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "mdrs-client-python"
version = "1.3.3"
version = "1.3.4"
description = "The mdrs-client-python is python library and a command-line client for up- and downloading files to and from MDRS based repository."
authors = ["Yoshihiro OKUMURA <yoshihiro.okumura@riken.jp>"]
license = "MIT"
@ -22,19 +22,20 @@ packages = [
[tool.poetry.dependencies]
python = "^3.10"
requests = "^2.31.0"
requests = "^2.32.3"
requests-toolbelt = "^1.0.0"
python-dotenv = "^1.0.1"
pydantic = "^2.6.1"
pydantic-settings = "^2.1.0"
pydantic = "^2.8.2"
pydantic-settings = "^2.3.4"
PyJWT = "^2.8.0"
validators = "^0.22.0"
[tool.poetry.group.dev.dependencies]
black = "^24.2.0"
flake8 = "^7.0.0"
black = "^24.2.2"
flake8 = "^7.1.0"
Flake8-pyproject = "^1.2.3"
isort = "^5.13.2"
pyright = "^1.1.350"
pyright = "^1.1.370"
[tool.poetry.scripts]
mdrs = 'mdrsclient.__main__:main'