From 292ca1df2762d64dba01fd13ba95b928cacabf88 Mon Sep 17 00:00:00 2001 From: Yoshihiro OKUMURA Date: Tue, 12 Dec 2023 20:05:46 +0900 Subject: [PATCH] changed API endpoint from v2 to v3. --- .vscode/settings.json | 2 +- mdrsclient/api/__init__.py | 12 +++++------ mdrsclient/api/{file.py => files.py} | 10 ++++----- mdrsclient/api/{folder.py => folders.py} | 8 +++---- .../api/{laboratory.py => laboratories.py} | 4 ++-- mdrsclient/api/users.py | 21 +++++++------------ mdrsclient/commands/base.py | 6 +++--- mdrsclient/commands/chacl.py | 4 ++-- mdrsclient/commands/cp.py | 6 +++--- mdrsclient/commands/download.py | 10 ++++----- mdrsclient/commands/file_metadata.py | 4 ++-- mdrsclient/commands/labs.py | 4 ++-- mdrsclient/commands/ls.py | 6 +++--- mdrsclient/commands/metadata.py | 4 ++-- mdrsclient/commands/mkdir.py | 4 ++-- mdrsclient/commands/mv.py | 6 +++--- mdrsclient/commands/rm.py | 6 +++--- mdrsclient/commands/upload.py | 8 +++---- pyproject.toml | 4 ++-- 19 files changed, 61 insertions(+), 68 deletions(-) rename mdrsclient/api/{file.py => files.py} (95%) rename mdrsclient/api/{folder.py => folders.py} (96%) rename mdrsclient/api/{laboratory.py => laboratories.py} (89%) diff --git a/.vscode/settings.json b/.vscode/settings.json index 12ec797..d880423 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { "editor.formatOnSave": true, "editor.codeActionsOnSave": { - "source.organizeImports": true + "source.organizeImports": "explicit" }, "[python]": { "editor.defaultFormatter": "ms-python.black-formatter" diff --git a/mdrsclient/api/__init__.py b/mdrsclient/api/__init__.py index 8041591..88341cc 100644 --- a/mdrsclient/api/__init__.py +++ b/mdrsclient/api/__init__.py @@ -1,11 +1,11 @@ -from mdrsclient.api.file import FileApi -from mdrsclient.api.folder import FolderApi -from mdrsclient.api.laboratory import LaboratoryApi +from mdrsclient.api.files import FilesApi +from mdrsclient.api.folders import FoldersApi +from mdrsclient.api.laboratories import LaboratoriesApi from mdrsclient.api.users import UsersApi __all__ = [ - "FileApi", - "FolderApi", - "LaboratoryApi", + "FilesApi", + "FoldersApi", + "LaboratoriesApi", "UsersApi", ] diff --git a/mdrsclient/api/file.py b/mdrsclient/api/files.py similarity index 95% rename from mdrsclient/api/file.py rename to mdrsclient/api/files.py index ee59ef2..fb5e9e5 100644 --- a/mdrsclient/api/file.py +++ b/mdrsclient/api/files.py @@ -10,12 +10,12 @@ from mdrsclient.models import File @dataclass(frozen=True) -class FileCreateResponse: +class FilesApiCreateResponse: id: str -class FileApi(BaseApi): - ENTRYPOINT: Final[str] = "v2/file/" +class FilesApi(BaseApi): + ENTRYPOINT: Final[str] = "v3/files/" def retrieve(self, id: str) -> File: # print(self.__class__.__name__ + "::" + sys._getframe().f_code.co_name) @@ -34,7 +34,7 @@ class FileApi(BaseApi): with open(path, mode="rb") as fp: response = self.connection.post(url, data=data, files={"file": fp}) self._raise_response_error(response) - ret = TypeAdapter(FileCreateResponse).validate_python(response.json()) + ret = TypeAdapter(FilesApiCreateResponse).validate_python(response.json()) except OSError: raise UnexpectedException(f"Could not open `{path}` file.") return ret.id @@ -93,7 +93,7 @@ class FileApi(BaseApi): def download(self, file: File, path: str) -> bool: # print(self.__class__.__name__ + "::" + sys._getframe().f_code.co_name) - url = "v2/" + file.download_url + url = file.download_url response = self.connection.get(url, stream=True) self._raise_response_error(response) try: diff --git a/mdrsclient/api/folder.py b/mdrsclient/api/folders.py similarity index 96% rename from mdrsclient/api/folder.py rename to mdrsclient/api/folders.py index 0c8f2c8..a19c254 100644 --- a/mdrsclient/api/folder.py +++ b/mdrsclient/api/folders.py @@ -11,12 +11,12 @@ from mdrsclient.models import Folder, FolderSimple @dataclass(frozen=True) -class FolderCreateResponse: +class FoldersApiCreateResponse: id: str -class FolderApi(BaseApi): - ENTRYPOINT: Final[str] = "v2/folder/" +class FoldersApi(BaseApi): + ENTRYPOINT: Final[str] = "v3/folders/" def list(self, laboratory_id: int, path: str) -> list[FolderSimple]: # print(self.__class__.__name__ + "::" + sys._getframe().f_code.co_name) @@ -46,7 +46,7 @@ class FolderApi(BaseApi): token_check(self.connection) response = self.connection.post(url, data=data) self._raise_response_error(response) - ret = TypeAdapter(FolderCreateResponse).validate_python(response.json()) + ret = TypeAdapter(FoldersApiCreateResponse).validate_python(response.json()) return ret.id def update(self, folder: FolderSimple) -> bool: diff --git a/mdrsclient/api/laboratory.py b/mdrsclient/api/laboratories.py similarity index 89% rename from mdrsclient/api/laboratory.py rename to mdrsclient/api/laboratories.py index a4b697f..656f84d 100644 --- a/mdrsclient/api/laboratory.py +++ b/mdrsclient/api/laboratories.py @@ -7,8 +7,8 @@ from mdrsclient.api.utils import token_check from mdrsclient.models import Laboratories, Laboratory -class LaboratoryApi(BaseApi): - ENTRYPOINT: Final[str] = "v2/laboratory/" +class LaboratoriesApi(BaseApi): + ENTRYPOINT: Final[str] = "v3/laboratories/" def list(self) -> Laboratories: # print(self.__class__.__name__ + "::" + sys._getframe().f_code.co_name) diff --git a/mdrsclient/api/users.py b/mdrsclient/api/users.py index 5fa6b76..0d5653f 100644 --- a/mdrsclient/api/users.py +++ b/mdrsclient/api/users.py @@ -1,4 +1,3 @@ -from dataclasses import field from typing import Final import requests @@ -7,13 +6,7 @@ from pydantic.dataclasses import dataclass from mdrsclient.api.base import BaseApi from mdrsclient.exceptions import UnauthorizedException -from mdrsclient.models import Laboratory, Token, User - - -@dataclass(frozen=True) -class UserAuthResponse(Token): - is_reviewer: bool | None = None - laboratories: list[Laboratory] = field(default_factory=list) +from mdrsclient.models import Token, User @dataclass(frozen=True) @@ -24,7 +17,7 @@ class UsersCurrentResponseLaboratory: @dataclass(frozen=True) -class UsersCurrentResponse: +class UsersApiCurrentResponse: id: int username: str full_name: str @@ -39,21 +32,21 @@ class UsersCurrentResponse: class UsersApi(BaseApi): - ENTRYPOINT: Final[str] = "v2/" + ENTRYPOINT: Final[str] = "v3/users/" def current(self) -> User: # print(self.__class__.__name__ + "::" + sys._getframe().f_code.co_name) - url = self.ENTRYPOINT + "users/current/" + url = self.ENTRYPOINT + "current/" response = self.connection.get(url) self._raise_response_error(response) - obj = TypeAdapter(UsersCurrentResponse).validate_python(response.json()) + obj = TypeAdapter(UsersApiCurrentResponse).validate_python(response.json()) laboratory_ids = list(map(lambda x: x.id, obj.laboratories)) user = User(id=obj.id, username=obj.username, laboratory_ids=laboratory_ids, is_reviewer=obj.is_reviewer) return user def token(self, username: str, password: str) -> Token: # print(self.__class__.__name__ + "::" + sys._getframe().f_code.co_name) - url = self.ENTRYPOINT + "users/token/" + url = self.ENTRYPOINT + "token/" data: dict[str, str | int] = {"username": username, "password": password} response = self.connection.post(url, data=data) if response.status_code == requests.codes.unauthorized: @@ -64,7 +57,7 @@ class UsersApi(BaseApi): def tokenRefresh(self, token: Token) -> Token: # print(self.__class__.__name__ + "::" + sys._getframe().f_code.co_name) - url = self.ENTRYPOINT + "users/token/refresh/" + url = self.ENTRYPOINT + "token/refresh/" data: dict[str, str | int] = {"refresh": token.refresh} response = self.connection.post(url, data=data) if response.status_code == requests.codes.unauthorized: diff --git a/mdrsclient/commands/base.py b/mdrsclient/commands/base.py index 1f93ce3..eda67d1 100644 --- a/mdrsclient/commands/base.py +++ b/mdrsclient/commands/base.py @@ -3,7 +3,7 @@ from abc import ABC, abstractmethod from typing import Any from unicodedata import normalize -from mdrsclient.api import FolderApi, LaboratoryApi +from mdrsclient.api import FoldersApi, LaboratoriesApi from mdrsclient.config import ConfigFile from mdrsclient.connection import MDRSConnection from mdrsclient.exceptions import ( @@ -31,7 +31,7 @@ class BaseCommand(ABC): @classmethod def _find_laboratory(cls, connection: MDRSConnection, name: str) -> Laboratory: if connection.laboratories.empty() or connection.token is not None and connection.token.is_expired: - laboratory_api = LaboratoryApi(connection) + laboratory_api = LaboratoriesApi(connection) connection.laboratories = laboratory_api.list() laboratory = connection.laboratories.find_by_name(name) if laboratory is None: @@ -42,7 +42,7 @@ class BaseCommand(ABC): def _find_folder( cls, connection: MDRSConnection, laboratory: Laboratory, path: str, password: str | None = None ) -> Folder: - folder_api = FolderApi(connection) + folder_api = FoldersApi(connection) folders = folder_api.list(laboratory.id, normalize("NFC", path)) if len(folders) != 1: raise UnexpectedException(f"Folder `{path}` not found.") diff --git a/mdrsclient/commands/chacl.py b/mdrsclient/commands/chacl.py index 825f9c0..0ffafb2 100644 --- a/mdrsclient/commands/chacl.py +++ b/mdrsclient/commands/chacl.py @@ -1,7 +1,7 @@ from argparse import Namespace from typing import Any -from mdrsclient.api import FolderApi +from mdrsclient.api import FoldersApi from mdrsclient.commands.base import BaseCommand from mdrsclient.exceptions import IllegalArgumentException from mdrsclient.models import FolderAccessLevel @@ -36,5 +36,5 @@ class ChaclCommand(BaseCommand): connection = cls._create_connection(remote) laboratory = cls._find_laboratory(connection, laboratory_name) folder = cls._find_folder(connection, laboratory, r_path) - folder_api = FolderApi(connection) + folder_api = FoldersApi(connection) folder_api.acl(folder.id, access_level, is_recursive, password) diff --git a/mdrsclient/commands/cp.py b/mdrsclient/commands/cp.py index 6fdd084..78360a8 100644 --- a/mdrsclient/commands/cp.py +++ b/mdrsclient/commands/cp.py @@ -3,7 +3,7 @@ from argparse import Namespace from typing import Any from unicodedata import normalize -from mdrsclient.api import FileApi, FolderApi +from mdrsclient.api import FilesApi, FoldersApi from mdrsclient.commands.base import BaseCommand from mdrsclient.exceptions import IllegalArgumentException @@ -56,7 +56,7 @@ class CpCommand(BaseCommand): d_sub_folder = d_parent_folder.find_sub_folder(d_basename) if d_sub_folder is not None: raise IllegalArgumentException(f"Cannot overwrite non-folder `{d_basename}` with folder `{d_path}`.") - file_api = FileApi(connection) + file_api = FilesApi(connection) if s_parent_folder.id != d_parent_folder.id or d_basename != s_basename: file_api.copy(s_file, d_parent_folder.id, normalize("NFC", d_basename)) else: @@ -73,6 +73,6 @@ class CpCommand(BaseCommand): if d_folder.id == s_folder.id: raise IllegalArgumentException(f"`{s_path}` and `{s_path}` are the same folder.") raise IllegalArgumentException(f"Cannot move `{s_path}` to `{d_path}`: Folder not empty.") - folder_api = FolderApi(connection) + folder_api = FoldersApi(connection) if s_parent_folder.id != d_parent_folder.id or s_basename != d_basename: folder_api.copy(s_folder, d_parent_folder.id, normalize("NFC", d_basename)) diff --git a/mdrsclient/commands/download.py b/mdrsclient/commands/download.py index 35276cd..028f122 100644 --- a/mdrsclient/commands/download.py +++ b/mdrsclient/commands/download.py @@ -5,7 +5,7 @@ from typing import Any from pydantic.dataclasses import dataclass -from mdrsclient.api import FileApi, FolderApi +from mdrsclient.api import FilesApi, FoldersApi from mdrsclient.commands.base import BaseCommand from mdrsclient.connection import MDRSConnection from mdrsclient.exceptions import IllegalArgumentException @@ -62,13 +62,13 @@ class DownloadCommand(BaseCommand): raise IllegalArgumentException(f"File or folder `{r_path}` not found.") if not is_recursive: raise IllegalArgumentException(f"Cannot download `{r_path}`: Is a folder.") - folder_api = FolderApi(connection) + folder_api = FoldersApi(connection) cls.__multiple_download_pickup_recursive_files(folder_api, download_files, folder.id, l_dirname) cls.__multiple_download(connection, download_files) @classmethod def __multiple_download_pickup_recursive_files( - cls, folder_api: FolderApi, infolist: list[DownloadFileInfo], folder_id: str, basedir: str + cls, folder_api: FoldersApi, infolist: list[DownloadFileInfo], folder_id: str, basedir: str ) -> None: folder = folder_api.retrieve(folder_id) dirname = os.path.join(basedir, folder.name) @@ -83,11 +83,11 @@ class DownloadCommand(BaseCommand): @classmethod def __multiple_download(cls, connection: MDRSConnection, infolist: list[DownloadFileInfo]) -> None: - file_api = FileApi(connection) + file_api = FilesApi(connection) with ThreadPoolExecutor(max_workers=CONCURRENT) as pool: pool.map(lambda x: cls.__multiple_download_worker(file_api, x), infolist) @classmethod - def __multiple_download_worker(cls, file_api: FileApi, info: DownloadFileInfo) -> None: + def __multiple_download_worker(cls, file_api: FilesApi, info: DownloadFileInfo) -> None: file_api.download(info.file, info.path) print(info.path) diff --git a/mdrsclient/commands/file_metadata.py b/mdrsclient/commands/file_metadata.py index c279b9a..1101d17 100644 --- a/mdrsclient/commands/file_metadata.py +++ b/mdrsclient/commands/file_metadata.py @@ -3,7 +3,7 @@ import os from argparse import Namespace from typing import Any -from mdrsclient.api import FileApi +from mdrsclient.api import FilesApi from mdrsclient.commands.base import BaseCommand from mdrsclient.exceptions import IllegalArgumentException @@ -34,6 +34,6 @@ class FileMetadataCommand(BaseCommand): file = folder.find_file(r_basename) if file is None: raise IllegalArgumentException(f"File `{r_basename}` not found.") - file_api = FileApi(connection) + file_api = FilesApi(connection) metadata = file_api.metadata(file) print(json.dumps(metadata, ensure_ascii=False)) diff --git a/mdrsclient/commands/labs.py b/mdrsclient/commands/labs.py index 7bbbf03..7861a83 100644 --- a/mdrsclient/commands/labs.py +++ b/mdrsclient/commands/labs.py @@ -1,7 +1,7 @@ from argparse import Namespace from typing import Any -from mdrsclient.api import LaboratoryApi +from mdrsclient.api import LaboratoriesApi from mdrsclient.commands.base import BaseCommand @@ -21,7 +21,7 @@ class LabsCommand(BaseCommand): def labs(cls, remote: str) -> None: remote = cls._parse_remote_host(remote) connection = cls._create_connection(remote) - laboratory_api = LaboratoryApi(connection) + laboratory_api = LaboratoriesApi(connection) laboratories = laboratory_api.list() connection.laboratories = laboratories label = {"id": "ID", "name": "Name", "pi_name": "PI", "full_name": "Laboratory"} diff --git a/mdrsclient/commands/ls.py b/mdrsclient/commands/ls.py index feb6021..79f0906 100644 --- a/mdrsclient/commands/ls.py +++ b/mdrsclient/commands/ls.py @@ -4,7 +4,7 @@ from typing import Any from pydantic.dataclasses import dataclass -from mdrsclient.api import FolderApi +from mdrsclient.api import FoldersApi from mdrsclient.commands.base import BaseCommand from mdrsclient.connection import MDRSConnection from mdrsclient.exceptions import UnauthorizedException @@ -134,7 +134,7 @@ class LsCommand(BaseCommand): if context.is_recursive: print("") for sub_folder in sorted(folder.sub_folders, key=lambda x: x.name): - folder_api = FolderApi(context.connection) + folder_api = FoldersApi(context.connection) try: if sub_folder.lock: folder_api.auth(sub_folder.id, context.password) @@ -157,7 +157,7 @@ class LsCommand(BaseCommand): "updated_at": folder.updated_at, } if isinstance(folder, Folder): - folder_api = FolderApi(context.connection) + folder_api = FoldersApi(context.connection) print(folder.name) data["metadata"] = folder_api.metadata(folder.id) if context.is_recursive: diff --git a/mdrsclient/commands/metadata.py b/mdrsclient/commands/metadata.py index 46c9c19..c75a10f 100644 --- a/mdrsclient/commands/metadata.py +++ b/mdrsclient/commands/metadata.py @@ -2,7 +2,7 @@ import json from argparse import Namespace from typing import Any -from mdrsclient.api import FolderApi +from mdrsclient.api import FoldersApi from mdrsclient.commands.base import BaseCommand @@ -26,6 +26,6 @@ class MetadataCommand(BaseCommand): connection = cls._create_connection(remote) laboratory = cls._find_laboratory(connection, laboratory_name) folder = cls._find_folder(connection, laboratory, r_path, password) - folder_api = FolderApi(connection) + folder_api = FoldersApi(connection) metadata = folder_api.metadata(folder.id) print(json.dumps(metadata, ensure_ascii=False)) diff --git a/mdrsclient/commands/mkdir.py b/mdrsclient/commands/mkdir.py index a5f6e84..e75d8b4 100644 --- a/mdrsclient/commands/mkdir.py +++ b/mdrsclient/commands/mkdir.py @@ -3,7 +3,7 @@ from argparse import Namespace from typing import Any from unicodedata import normalize -from mdrsclient.api import FolderApi +from mdrsclient.api import FoldersApi from mdrsclient.commands.base import BaseCommand from mdrsclient.exceptions import IllegalArgumentException @@ -31,5 +31,5 @@ class MkdirCommand(BaseCommand): parent_folder = cls._find_folder(connection, laboratory, r_dirname) if parent_folder.find_sub_folder(r_basename) is not None or parent_folder.find_file(r_basename) is not None: raise IllegalArgumentException(f"Cannot create folder `{r_path}`: File exists.") - folder_api = FolderApi(connection) + folder_api = FoldersApi(connection) folder_api.create(normalize("NFC", r_basename), parent_folder.id) diff --git a/mdrsclient/commands/mv.py b/mdrsclient/commands/mv.py index df9ce09..776f98f 100644 --- a/mdrsclient/commands/mv.py +++ b/mdrsclient/commands/mv.py @@ -3,7 +3,7 @@ from argparse import Namespace from typing import Any from unicodedata import normalize -from mdrsclient.api import FileApi, FolderApi +from mdrsclient.api import FilesApi, FoldersApi from mdrsclient.commands.base import BaseCommand from mdrsclient.exceptions import IllegalArgumentException @@ -52,7 +52,7 @@ class MvCommand(BaseCommand): d_sub_folder = d_parent_folder.find_sub_folder(d_basename) if d_sub_folder is not None: raise IllegalArgumentException(f"Cannot overwrite non-folder `{d_basename}` with folder `{d_path}`.") - file_api = FileApi(connection) + file_api = FilesApi(connection) if s_parent_folder.id != d_parent_folder.id or d_basename != s_basename: file_api.move(s_file, d_parent_folder.id, normalize("NFC", d_basename)) else: @@ -67,6 +67,6 @@ class MvCommand(BaseCommand): if d_folder.id == s_folder.id: raise IllegalArgumentException(f"`{s_path}` and `{s_path}` are the same folder.") raise IllegalArgumentException(f"Cannot move `{s_path}` to `{d_path}`: Folder not empty.") - folder_api = FolderApi(connection) + folder_api = FoldersApi(connection) if s_parent_folder.id != d_parent_folder.id or d_basename != s_basename: folder_api.move(s_folder, d_parent_folder.id, normalize("NFC", d_basename)) diff --git a/mdrsclient/commands/rm.py b/mdrsclient/commands/rm.py index 9c6397f..f6cd321 100644 --- a/mdrsclient/commands/rm.py +++ b/mdrsclient/commands/rm.py @@ -2,7 +2,7 @@ import os from argparse import Namespace from typing import Any -from mdrsclient.api import FileApi, FolderApi +from mdrsclient.api import FilesApi, FoldersApi from mdrsclient.commands.base import BaseCommand from mdrsclient.exceptions import IllegalArgumentException @@ -34,7 +34,7 @@ class RmCommand(BaseCommand): parent_folder = cls._find_folder(connection, laboratory, r_dirname) file = parent_folder.find_file(r_basename) if file is not None: - file_api = FileApi(connection) + file_api = FilesApi(connection) file_api.destroy(file) else: folder = parent_folder.find_sub_folder(r_basename) @@ -42,5 +42,5 @@ class RmCommand(BaseCommand): raise IllegalArgumentException(f"Cannot remove `{r_path}`: No such file or folder.") if not is_recursive: raise IllegalArgumentException(f"Cannot remove `{r_path}`: Is a folder.") - folder_api = FolderApi(connection) + folder_api = FoldersApi(connection) folder_api.destroy(folder.id, True) diff --git a/mdrsclient/commands/upload.py b/mdrsclient/commands/upload.py index 0ff81aa..5ff258e 100644 --- a/mdrsclient/commands/upload.py +++ b/mdrsclient/commands/upload.py @@ -5,7 +5,7 @@ from typing import Any from pydantic.dataclasses import dataclass -from mdrsclient.api import FileApi, FolderApi +from mdrsclient.api import FilesApi, FoldersApi from mdrsclient.commands.base import BaseCommand from mdrsclient.connection import MDRSConnection from mdrsclient.exceptions import IllegalArgumentException, MDRSException @@ -50,7 +50,7 @@ class UploadCommand(BaseCommand): if os.path.isdir(l_path): if not is_recursive: raise IllegalArgumentException(f"Cannot upload `{local_path}`: Is a directory.") - folder_api = FolderApi(connection) + folder_api = FoldersApi(connection) folder_map: dict[str, Folder] = {} folder_map[r_path] = folder l_basename = os.path.basename(l_path) @@ -82,12 +82,12 @@ class UploadCommand(BaseCommand): @classmethod def __multiple_upload(cls, connection: MDRSConnection, infos: list[UploadFileInfo]) -> None: - file_api = FileApi(connection) + file_api = FilesApi(connection) with ThreadPoolExecutor(max_workers=CONCURRENT) as pool: pool.map(lambda x: cls.__multiple_upload_worker(file_api, x), infos) @classmethod - def __multiple_upload_worker(cls, file_api: FileApi, info: UploadFileInfo) -> None: + def __multiple_upload_worker(cls, file_api: FilesApi, info: UploadFileInfo) -> None: basename = os.path.basename(info.path) file = info.folder.find_file(basename) try: diff --git a/pyproject.toml b/pyproject.toml index afdefbe..afe55d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,10 +30,10 @@ PyJWT = "^2.8.0" validators = "^0.22.0" [tool.poetry.group.dev.dependencies] -black = "^23.11.0" +black = "^23.12.0" flake8 = "^6.1.0" Flake8-pyproject = "^1.2.3" -isort = "^5.12.0" +isort = "^5.13.0" pyright = "^1.1.339" [tool.poetry.scripts]