presentation.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. from http import HTTPStatus
  2. from typing import Optional
  3. from fastapi import Depends
  4. from fastapi import Form
  5. from fastapi import Response
  6. from fastapi import UploadFile
  7. from clean_python import DoesNotExist
  8. from clean_python import Page
  9. from clean_python import ValueObject
  10. from clean_python.fastapi import delete
  11. from clean_python.fastapi import get
  12. from clean_python.fastapi import patch
  13. from clean_python.fastapi import post
  14. from clean_python.fastapi import RequestQuery
  15. from clean_python.fastapi import Resource
  16. from clean_python.fastapi import v
  17. from .application import ManageBook
  18. from .domain import Author
  19. from .domain import Book
  20. class BookCreate(ValueObject):
  21. author: Author
  22. title: str
  23. class BookUpdate(ValueObject):
  24. author: Optional[Author] = None
  25. title: Optional[str] = None
  26. class V1Books(Resource, version=v(1), name="books"):
  27. def __init__(self):
  28. self.manager = ManageBook()
  29. @get("/books", response_model=Page[Book])
  30. async def list(self, q: RequestQuery = Depends()):
  31. return await self.manager.filter([], q.as_page_options())
  32. @post("/books", status_code=HTTPStatus.CREATED, response_model=Book)
  33. async def create(self, obj: BookCreate):
  34. return await self.manager.create(obj.model_dump())
  35. @get("/books/{id}", response_model=Book)
  36. async def retrieve(self, id: int):
  37. return await self.manager.retrieve(id)
  38. @patch("/books/{id}", response_model=Book)
  39. async def update(self, id: int, obj: BookUpdate):
  40. return await self.manager.update(id, obj.model_dump(exclude_unset=True))
  41. @delete("/books/{id}", status_code=HTTPStatus.NO_CONTENT, response_class=Response)
  42. async def destroy(self, id: int):
  43. if not await self.manager.destroy(id):
  44. raise DoesNotExist("object", id)
  45. @get("/text")
  46. async def text(self):
  47. return Response("foo", media_type="text/plain")
  48. @post("/form", response_model=Author)
  49. async def form(self, name: str = Form()):
  50. return {"name": name}
  51. @post("/file")
  52. async def file(self, file: UploadFile):
  53. return {file.filename: (await file.read()).decode()}