diff --git a/mdrsclient/api/base.py b/mdrsclient/api/base.py index 90f0e96..fd08c68 100644 --- a/mdrsclient/api/base.py +++ b/mdrsclient/api/base.py @@ -1,7 +1,7 @@ from abc import ABC import requests -from pydantic import parse_obj_as +from pydantic import TypeAdapter from requests import Response from mdrsclient.connection import MDRSConnection @@ -24,7 +24,7 @@ class BaseApi(ABC): if response.status_code >= 300: if response.status_code < 400 or response.status_code >= 500: raise UnexpectedException(f"Unexpected status code returned: {response.status_code}.") - errors = parse_obj_as(DRFStandardizedErrors, response.json()) + errors = TypeAdapter(DRFStandardizedErrors).validate_python(response.json()) if response.status_code == requests.codes.bad_request: raise BadRequestException(errors.errors[0].detail) elif response.status_code == requests.codes.unauthorized: diff --git a/mdrsclient/api/file.py b/mdrsclient/api/file.py index a9777f2..26b8254 100644 --- a/mdrsclient/api/file.py +++ b/mdrsclient/api/file.py @@ -1,6 +1,6 @@ from typing import Final -from pydantic import parse_obj_as +from pydantic import TypeAdapter from pydantic.dataclasses import dataclass from mdrsclient.api.base import BaseApi @@ -23,7 +23,7 @@ class FileApi(BaseApi): token_check(self.connection) response = self.connection.get(url) self._raise_response_error(response) - return parse_obj_as(File, response.json()) + return TypeAdapter(File).validate_python(response.json()) def create(self, folder_id: str, path: str) -> str: # 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 = parse_obj_as(FileCreateResponse, response.json()) + ret = TypeAdapter(FileCreateResponse).validate_python(response.json()) except OSError: raise UnexpectedException(f"Could not open `{path}` file.") return ret.id diff --git a/mdrsclient/api/folder.py b/mdrsclient/api/folder.py index 103c170..85215a9 100644 --- a/mdrsclient/api/folder.py +++ b/mdrsclient/api/folder.py @@ -1,7 +1,7 @@ from typing import Final import requests -from pydantic import parse_obj_as +from pydantic import TypeAdapter from pydantic.dataclasses import dataclass from mdrsclient.api.base import BaseApi @@ -27,7 +27,7 @@ class FolderApi(BaseApi): self._raise_response_error(response) ret: list[FolderSimple] = [] for data in response.json(): - ret.append(parse_obj_as(FolderSimple, data)) + ret.append(TypeAdapter(FolderSimple).validate_python(data)) return ret def retrieve(self, id: str) -> Folder: @@ -36,7 +36,7 @@ class FolderApi(BaseApi): token_check(self.connection) response = self.connection.get(url) self._raise_response_error(response) - ret = parse_obj_as(Folder, response.json()) + ret = TypeAdapter(Folder).validate_python(response.json()) return ret def create(self, name: str, parent_id: str) -> str: @@ -46,7 +46,7 @@ class FolderApi(BaseApi): token_check(self.connection) response = self.connection.post(url, data=data) self._raise_response_error(response) - ret = parse_obj_as(FolderCreateResponse, response.json()) + ret = TypeAdapter(FolderCreateResponse).validate_python(response.json()) return ret.id def update(self, folder: FolderSimple) -> bool: diff --git a/mdrsclient/api/laboratory.py b/mdrsclient/api/laboratory.py index 4a5e2bf..a4b697f 100644 --- a/mdrsclient/api/laboratory.py +++ b/mdrsclient/api/laboratory.py @@ -1,6 +1,6 @@ from typing import Final -from pydantic import parse_obj_as +from pydantic import TypeAdapter from mdrsclient.api.base import BaseApi from mdrsclient.api.utils import token_check @@ -18,6 +18,6 @@ class LaboratoryApi(BaseApi): self._raise_response_error(response) ret = Laboratories() for data in response.json(): - ret.append(parse_obj_as(Laboratory, data)) + ret.append(TypeAdapter(Laboratory).validate_python(data)) ret.sort() return ret diff --git a/mdrsclient/api/user.py b/mdrsclient/api/user.py index 9b98cd8..d07224a 100644 --- a/mdrsclient/api/user.py +++ b/mdrsclient/api/user.py @@ -1,7 +1,7 @@ from typing import Final import requests -from pydantic import parse_obj_as +from pydantic import TypeAdapter from pydantic.dataclasses import dataclass from mdrsclient.api.base import BaseApi @@ -27,7 +27,7 @@ class UserApi(BaseApi): if response.status_code == requests.codes.unauthorized: raise UnauthorizedException("Invalid username or password.") self._raise_response_error(response) - obj = parse_obj_as(UserAuthResponse, response.json()) + obj = TypeAdapter(UserAuthResponse).validate_python(response.json()) token = Token(access=obj.access, refresh=obj.refresh) laboratory_ids = [obj.lab_id] if obj.lab_id is not None else [] is_reviewer = obj.is_reviewer if obj.is_reviewer is not None else False @@ -42,5 +42,5 @@ class UserApi(BaseApi): if response.status_code == requests.codes.unauthorized: raise UnauthorizedException("Token is invalid or expired.") self._raise_response_error(response) - token = parse_obj_as(Token, response.json()) + token = TypeAdapter(Token).validate_python(response.json()) return token diff --git a/mdrsclient/cache.py b/mdrsclient/cache.py index d9ee219..967d981 100644 --- a/mdrsclient/cache.py +++ b/mdrsclient/cache.py @@ -3,9 +3,8 @@ import hashlib import json import os -from pydantic import ValidationError +from pydantic import TypeAdapter, ValidationError from pydantic.dataclasses import dataclass -from pydantic.tools import parse_obj_as from mdrsclient.exceptions import UnexpectedException from mdrsclient.models import Laboratories, Token, User @@ -108,7 +107,7 @@ class CacheFile: if self.__serial != serial: try: with open(self.__cache_file) as f: - data = parse_obj_as(CacheData, json.load(f)) + data = TypeAdapter(CacheData).validate_python(json.load(f)) if not data.verify_digest(): raise UnexpectedException("Cache data has been broken.") self.__data = data diff --git a/mdrsclient/commands/mkdir.py b/mdrsclient/commands/mkdir.py index cfb0d4f..6bca9d6 100644 --- a/mdrsclient/commands/mkdir.py +++ b/mdrsclient/commands/mkdir.py @@ -1,5 +1,6 @@ import os from argparse import Namespace, _SubParsersAction +from unicodedata import normalize from mdrsclient.api import FolderApi from mdrsclient.commands.base import BaseCommand @@ -25,4 +26,4 @@ class MkdirCommand(BaseCommand): 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.create(r_basename, parent_folder.id) + folder_api.create(normalize("NFC", r_basename), parent_folder.id) diff --git a/mdrsclient/commands/mv.py b/mdrsclient/commands/mv.py index 8d3bf75..ff89604 100644 --- a/mdrsclient/commands/mv.py +++ b/mdrsclient/commands/mv.py @@ -3,7 +3,7 @@ import os from argparse import Namespace, _SubParsersAction from unicodedata import normalize -from pydantic import parse_obj_as +from pydantic import TypeAdapter from mdrsclient.api import FileApi, FolderApi from mdrsclient.commands.base import BaseCommand @@ -52,7 +52,7 @@ class MvCommand(BaseCommand): file_api = FileApi(connection) if s_parent_folder.id != d_parent_folder.id or d_basename != s_basename: d_file_dict = dataclasses.asdict(s_file) | {"name": normalize("NFC", d_basename)} - d_file = parse_obj_as(File, d_file_dict) + d_file = TypeAdapter(File).validate_python(d_file_dict) file_api.move(d_file, d_parent_folder.id) else: s_folder = s_parent_folder.find_sub_folder(s_basename) @@ -71,5 +71,5 @@ class MvCommand(BaseCommand): folder_api.move(s_folder, d_parent_folder.id) if s_basename != d_basename: d_folder_dict = dataclasses.asdict(s_folder) | {"name": normalize("NFC", d_basename)} - d_folder = parse_obj_as(FolderSimple, d_folder_dict) + d_folder = TypeAdapter(FolderSimple).validate_python(d_folder_dict) folder_api.update(d_folder) diff --git a/mdrsclient/models/user.py b/mdrsclient/models/user.py index a968a52..eff7753 100644 --- a/mdrsclient/models/user.py +++ b/mdrsclient/models/user.py @@ -1,7 +1,7 @@ import time import jwt -from pydantic import parse_obj_as +from pydantic import TypeAdapter from pydantic.dataclasses import dataclass @@ -39,7 +39,7 @@ class Token: def __decode(self, token: str) -> DecodedJWT: data = jwt.decode(token, options={"verify_signature": False}) - return parse_obj_as(DecodedJWT, data) + return TypeAdapter(DecodedJWT).validate_python(data) @dataclass(frozen=True)