api_gateway.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. from datetime import datetime
  2. from http import HTTPStatus
  3. from typing import Optional
  4. import inject
  5. from clean_python import DoesNotExist
  6. from clean_python import Id
  7. from clean_python import Json
  8. from .. import SyncGateway
  9. from .api_provider import SyncApiProvider
  10. from .exceptions import ApiException
  11. __all__ = ["SyncApiGateway"]
  12. class SyncApiGateway(SyncGateway):
  13. path: str
  14. def __init__(self, provider_override: Optional[SyncApiProvider] = None):
  15. self.provider_override = provider_override
  16. def __init_subclass__(cls, path: str) -> None:
  17. assert not path.startswith("/")
  18. assert "{id}" in path
  19. cls.path = path
  20. super().__init_subclass__()
  21. @property
  22. def provider(self) -> SyncApiProvider:
  23. return self.provider_override or inject.instance(SyncApiProvider)
  24. def get(self, id: Id) -> Optional[Json]:
  25. try:
  26. return self.provider.request("GET", self.path.format(id=id))
  27. except ApiException as e:
  28. if e.status is HTTPStatus.NOT_FOUND:
  29. return None
  30. raise e
  31. def add(self, item: Json) -> Json:
  32. result = self.provider.request("POST", self.path.format(id=""), json=item)
  33. assert result is not None
  34. return result
  35. def remove(self, id: Id) -> bool:
  36. try:
  37. self.provider.request("DELETE", self.path.format(id=id)) is not None
  38. except ApiException as e:
  39. if e.status is HTTPStatus.NOT_FOUND:
  40. return False
  41. raise e
  42. else:
  43. return True
  44. def update(
  45. self, item: Json, if_unmodified_since: Optional[datetime] = None
  46. ) -> Json:
  47. if if_unmodified_since is not None:
  48. raise NotImplementedError("if_unmodified_since not implemented")
  49. item = item.copy()
  50. id_ = item.pop("id", None)
  51. if id_ is None:
  52. raise DoesNotExist("resource", id_)
  53. try:
  54. result = self.provider.request("PATCH", self.path.format(id=id_), json=item)
  55. assert result is not None
  56. return result
  57. except ApiException as e:
  58. if e.status is HTTPStatus.NOT_FOUND:
  59. raise DoesNotExist("resource", id_)
  60. raise e