refactor: extract MdrsClient service layer for library portability

To improve the tool's portability as a Python library, the core logic
has been decoupled from the CLI interface. This allows developers to
programmatically interact with MDRS without relying on CLI-specific
argument parsing or local file-based caches.

- Introduce `MdrsClient` service layer to handle core operations.
- Abstract authentication state using `CacheInterface` and `InMemoryCache`.
- Migrate all CLI commands to utilize `MdrsClient` for execution.
- Separate `Doi` data model from API responses and move to `models/doi.py`.
- Update `README.md` to include Python API usage examples.
- Bump package version to 1.3.17.
This commit is contained in:
2026-07-02 13:07:18 +09:00
parent 809140dfbc
commit 36cad6db52
28 changed files with 736 additions and 215 deletions
+7 -14
View File
@@ -5,36 +5,29 @@ from pydantic.dataclasses import dataclass
from mdrsclient.api.base import BaseApi
from mdrsclient.api.utils import token_check
from mdrsclient.models.doi import Doi
@dataclass(frozen=True)
class DoiFolderRef:
"""Nested folder reference returned inside a DOI response.
The DOI endpoint only returns the folder ``id``; ``laboratory_id`` must be
obtained by subsequently calling the folder retrieve endpoint.
"""
class DoiRetrieveFolderRef:
id: str
@dataclass(frozen=True)
class DoiResponse:
"""Response from GET v3/doi/{id}/."""
# The internal DOI suffix ID returned as a string (e.g. "20260429-001").
class DoiRetrieveResponse:
id: str
doi: str
folder: DoiFolderRef
folder: DoiRetrieveFolderRef
class DoiApi(BaseApi):
ENTRYPOINT: Final[str] = "v3/doi/"
def retrieve(self, doi_id: str) -> DoiResponse:
def retrieve(self, doi_id: str) -> Doi:
"""Retrieve the folder associated with a DOI suffix ID (GET v3/doi/{id}/)."""
url = self.ENTRYPOINT + doi_id + "/"
token_check(self.connection)
response = self.connection.get(url)
self._raise_response_error(response)
return TypeAdapter(DoiResponse).validate_python(response.json())
api_resp = TypeAdapter(DoiRetrieveResponse).validate_python(response.json())
return Doi(id=api_resp.id, doi=api_resp.doi, folder_id=api_resp.folder.id)