From fe5065deaf44cd7f586ad7718960b1d5240349b1 Mon Sep 17 00:00:00 2001 From: Roman Reznikov Date: Sat, 9 Jul 2022 14:31:06 +0400 Subject: [PATCH] #22: WIP: feat: add API endpoint for creating new film reviews --- src/ugc/api/v1/handlers/ugc.py | 20 +++++++++++++++++--- src/ugc/api/v1/openapi.py | 15 +++++++++++++++ src/ugc/api/v1/routes.py | 10 +++++++++- src/ugc/api/v1/serializers.py | 17 +++++++++++++++++ 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/ugc/api/v1/handlers/ugc.py b/src/ugc/api/v1/handlers/ugc.py index d459669..940447b 100644 --- a/src/ugc/api/v1/handlers/ugc.py +++ b/src/ugc/api/v1/handlers/ugc.py @@ -11,13 +11,13 @@ from ugc.api.security import get_user_id_from_jwt from ugc.api.utils import orjson_response -from ugc.api.v1 import openapi -from ugc.api.v1.serializers import FilmProgressCreate +from ugc.api.v1 import openapi, serializers from ugc.containers import Container if TYPE_CHECKING: from ugc.domain.bookmarks import BookmarkDispatcherService, BookmarkService from ugc.domain.progress import ProgressDispatcherService, ProgressService + from ugc.domain.reviews import ReviewService @docs(**openapi.add_film_bookmark) @@ -55,7 +55,7 @@ async def get_user_films_bookmarks( @docs(**openapi.track_film_progress) -@request_schema(FilmProgressCreate) +@request_schema(serializers.FilmProgressCreate) @inject async def track_film_progress( request: web.Request, *, @@ -83,6 +83,20 @@ async def get_film_progress( return orjson_response(progress, status=HTTPStatus.OK) +@docs(**openapi.create_film_review) +@request_schema(serializers.FilmReviewCreate) +@inject +async def create_film_review( + request: web.Request, *, + review_service: ReviewService = Provide[Container.review_service], +) -> web.Response: + """Создание новой рецензии на фильм от авторизированного пользователя.""" + film_id: UUID = request.match_info["film_id"] # noqa: F841 + user_id = get_user_id_from_jwt(request.headers) # noqa: F841 + review = await review_service.create_review() + return orjson_response(review, status=HTTPStatus.CREATED) + + async def _handle_film_bookmark( request: web.Request, bookmark_dispatcher: BookmarkDispatcherService, *, diff --git a/src/ugc/api/v1/openapi.py b/src/ugc/api/v1/openapi.py index c13ebbf..9d2be89 100644 --- a/src/ugc/api/v1/openapi.py +++ b/src/ugc/api/v1/openapi.py @@ -63,3 +63,18 @@ HTTPStatus.INTERNAL_SERVER_ERROR: {"description": "Ошибка сервера."}, }, } + +create_film_review = { + "tags": ["review"], + "summary": "Создать пользовательскую рецензию на фильм.", + "security": [{"JWT": []}], + "responses": { + HTTPStatus.CREATED: { + "description": "Рецензия создана.", + "schema": serializers.FilmReviewDetail, + }, + HTTPStatus.UNAUTHORIZED: {"description": "Пользователь не авторизован."}, + HTTPStatus.BAD_REQUEST: {"description": "Ошибка в теле запроса."}, + HTTPStatus.INTERNAL_SERVER_ERROR: {"description": "Ошибка сервера."}, + }, +} diff --git a/src/ugc/api/v1/routes.py b/src/ugc/api/v1/routes.py index e786db1..c3a1d3a 100644 --- a/src/ugc/api/v1/routes.py +++ b/src/ugc/api/v1/routes.py @@ -5,7 +5,7 @@ def setup_routes_v1(app: web.Application) -> None: app.add_routes([ - # UGC + # Bookmarks web.post( path="/users/me/bookmarks/films/{film_id}", handler=ugc.add_film_bookmark, @@ -19,6 +19,8 @@ def setup_routes_v1(app: web.Application) -> None: handler=ugc.get_user_films_bookmarks, allow_head=False, ), + + # Progress web.post( path="/users/me/progress/films/{film_id}", handler=ugc.track_film_progress, @@ -29,6 +31,12 @@ def setup_routes_v1(app: web.Application) -> None: allow_head=False, ), + # Reviews + web.post( + path="/users/me/reviews/films/{film_id}", + handler=ugc.create_film_review, + ), + # Miscellaneous web.get( path="/health", diff --git a/src/ugc/api/v1/serializers.py b/src/ugc/api/v1/serializers.py index 8c09b82..851e161 100644 --- a/src/ugc/api/v1/serializers.py +++ b/src/ugc/api/v1/serializers.py @@ -25,3 +25,20 @@ class FilmProgressDetail(Schema): user_id = fields.UUID() film_id = fields.UUID() viewed_frame = fields.Integer() + + +class FilmReviewCreate(Schema): + """Сериалайзер для создания рецензии на фильм.""" + + title = fields.Str(strict=True, required=True) + review = fields.Str(strict=True, required=True) + + +class FilmReviewDetail(Schema): + """Сериалайзер рецензии на фильм.""" + + id = fields.Str() # noqa: VNE003 + user_id = fields.UUID() + film_id = fields.UUID() + title = fields.Str() + review = fields.Str()