| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 | from datetime import datetimefrom http import HTTPStatusfrom typing import Optionalimport injectfrom clean_python import DoesNotExistfrom clean_python import Gatewayfrom clean_python import Idfrom clean_python import Jsonfrom clean_python import Mapperfrom clean_python import SyncGatewayfrom .api_provider import ApiProviderfrom .exceptions import ApiExceptionfrom .sync_api_provider import SyncApiProvider__all__ = ["ApiGateway", "SyncApiGateway"]class ApiGateway(Gateway):    path: str    mapper = Mapper()    def __init__(self, provider_override: Optional[ApiProvider] = None):        self.provider_override = provider_override    def __init_subclass__(cls, path: str) -> None:        assert not path.startswith("/")        assert "{id}" in path        cls.path = path        super().__init_subclass__()    @property    def provider(self) -> ApiProvider:        return self.provider_override or inject.instance(ApiProvider)    async def get(self, id: Id) -> Optional[Json]:        try:            result = await self.provider.request("GET", self.path.format(id=id))            assert result is not None            return self.mapper.to_internal(result)        except ApiException as e:            if e.status is HTTPStatus.NOT_FOUND:                return None            raise e    async def add(self, item: Json) -> Json:        item = self.mapper.to_external(item)        result = await self.provider.request("POST", self.path.format(id=""), json=item)        assert result is not None        return self.mapper.to_internal(result)    async def remove(self, id: Id) -> bool:        try:            await self.provider.request("DELETE", self.path.format(id=id)) is not None        except ApiException as e:            if e.status is HTTPStatus.NOT_FOUND:                return False            raise e        else:            return True    async def update(        self, item: Json, if_unmodified_since: Optional[datetime] = None    ) -> Json:        if if_unmodified_since is not None:            raise NotImplementedError("if_unmodified_since not implemented")        item = self.mapper.to_external(item)        id_ = item.pop("id", None)        if id_ is None:            raise DoesNotExist("resource", id_)        try:            result = await self.provider.request(                "PATCH", self.path.format(id=id_), json=item            )            assert result is not None            return self.mapper.to_internal(result)        except ApiException as e:            if e.status is HTTPStatus.NOT_FOUND:                raise DoesNotExist("resource", id_)            raise e# This is a copy-paste of ApiGateway:class SyncApiGateway(SyncGateway):    path: str    mapper = Mapper()    def __init__(self, provider_override: Optional[SyncApiProvider] = None):        self.provider_override = provider_override    def __init_subclass__(cls, path: str) -> None:        assert not path.startswith("/")        assert "{id}" in path        cls.path = path        super().__init_subclass__()    @property    def provider(self) -> SyncApiProvider:        return self.provider_override or inject.instance(SyncApiProvider)    def get(self, id: Id) -> Optional[Json]:        try:            result = self.provider.request("GET", self.path.format(id=id))            assert result is not None            return self.mapper.to_internal(result)        except ApiException as e:            if e.status is HTTPStatus.NOT_FOUND:                return None            raise e    def add(self, item: Json) -> Json:        item = self.mapper.to_external(item)        result = self.provider.request("POST", self.path.format(id=""), json=item)        assert result is not None        return self.mapper.to_internal(result)    def remove(self, id: Id) -> bool:        try:            self.provider.request("DELETE", self.path.format(id=id)) is not None        except ApiException as e:            if e.status is HTTPStatus.NOT_FOUND:                return False            raise e        else:            return True    def update(        self, item: Json, if_unmodified_since: Optional[datetime] = None    ) -> Json:        if if_unmodified_since is not None:            raise NotImplementedError("if_unmodified_since not implemented")        item = self.mapper.to_external(item)        id_ = item.pop("id", None)        if id_ is None:            raise DoesNotExist("resource", id_)        try:            result = self.provider.request("PATCH", self.path.format(id=id_), json=item)            assert result is not None            return self.mapper.to_internal(result)        except ApiException as e:            if e.status is HTTPStatus.NOT_FOUND:                raise DoesNotExist("resource", id_)            raise e
 |