| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 | 
							- from datetime import datetime
 
- from http import HTTPStatus
 
- from typing import Optional
 
- import inject
 
- from clean_python import DoesNotExist
 
- from clean_python import Gateway
 
- from clean_python import Id
 
- from clean_python import Json
 
- from clean_python import Mapper
 
- from clean_python import SyncGateway
 
- from .api_provider import ApiProvider
 
- from .exceptions import ApiException
 
- from .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
 
 
  |