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:
+63
-1
@@ -2,6 +2,7 @@ import dataclasses
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from typing import Protocol, runtime_checkable
|
||||
|
||||
from pydantic import TypeAdapter, ValidationError
|
||||
from pydantic.dataclasses import dataclass
|
||||
@@ -16,7 +17,7 @@ from mdrsclient.utils import FileLock
|
||||
class CacheData:
|
||||
user: User | None = None
|
||||
token: Token | None = None
|
||||
laboratories: Laboratories = Laboratories()
|
||||
laboratories: Laboratories = dataclasses.field(default_factory=Laboratories)
|
||||
digest: str = ""
|
||||
|
||||
def clear(self) -> None:
|
||||
@@ -43,6 +44,67 @@ class CacheData:
|
||||
).hexdigest()
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class CacheInterface(Protocol):
|
||||
@property
|
||||
def token(self) -> Token | None: ...
|
||||
@token.setter
|
||||
def token(self, token: Token) -> None: ...
|
||||
@token.deleter
|
||||
def token(self) -> None: ...
|
||||
|
||||
@property
|
||||
def user(self) -> User | None: ...
|
||||
@user.setter
|
||||
def user(self, user: User) -> None: ...
|
||||
@user.deleter
|
||||
def user(self) -> None: ...
|
||||
|
||||
@property
|
||||
def laboratories(self) -> Laboratories: ...
|
||||
@laboratories.setter
|
||||
def laboratories(self, laboratories: Laboratories) -> None: ...
|
||||
|
||||
|
||||
class InMemoryCache:
|
||||
def __init__(self) -> None:
|
||||
self.__data = CacheData()
|
||||
|
||||
@property
|
||||
def token(self) -> Token | None:
|
||||
return self.__data.token
|
||||
|
||||
@token.setter
|
||||
def token(self, token: Token) -> None:
|
||||
self.__data.token = token
|
||||
|
||||
@token.deleter
|
||||
def token(self) -> None:
|
||||
if self.__data.token is not None:
|
||||
self.__data.token = None
|
||||
|
||||
@property
|
||||
def user(self) -> User | None:
|
||||
return self.__data.user
|
||||
|
||||
@user.setter
|
||||
def user(self, user: User) -> None:
|
||||
self.__data.user = user
|
||||
|
||||
@user.deleter
|
||||
def user(self) -> None:
|
||||
if self.__data.user is not None:
|
||||
self.__data.user = None
|
||||
|
||||
@property
|
||||
def laboratories(self) -> Laboratories:
|
||||
return self.__data.laboratories
|
||||
|
||||
@laboratories.setter
|
||||
def laboratories(self, laboratories: Laboratories) -> None:
|
||||
self.__data.laboratories = laboratories
|
||||
|
||||
|
||||
class CacheFile:
|
||||
__serial: int
|
||||
__cache_dir: str
|
||||
|
||||
Reference in New Issue
Block a user