From ebe75b6dc3c85557d8f0edcac227560f6a446503 Mon Sep 17 00:00:00 2001 From: pi3c Date: Fri, 9 Feb 2024 02:57:34 +0300 Subject: [PATCH] =?UTF-8?q?upd:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=80=D0=BE=D1=83=D1=82=20summary=20=D1=81=20=D0=B2?= =?UTF-8?q?=D1=8B=D0=B2=D0=BE=D0=B4=D0=BE=D0=BC=20=D0=B2=D0=BC=D0=B5=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=BC=D0=B5=D0=BD=D1=8E=20=D1=81=D0=BE=20=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin/Menu.xlsx | Bin 0 -> 12978 bytes fastfood/app.py | 2 + fastfood/repository/redis.py | 1 + fastfood/repository/summary.py | 19 + fastfood/routers/summary.py | 17 + fastfood/schemas.py | 8 + fastfood/service/summary.py | 54 ++ openapi.json | 1204 +++++++++++++++++++++++++++++++- 8 files changed, 1304 insertions(+), 1 deletion(-) create mode 100644 admin/Menu.xlsx create mode 100644 fastfood/repository/summary.py create mode 100644 fastfood/routers/summary.py create mode 100644 fastfood/service/summary.py diff --git a/admin/Menu.xlsx b/admin/Menu.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..a76c3264630d2c253cac4f84eedc30c7f7ea79cc GIT binary patch literal 12978 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 FastAPI: @@ -15,6 +16,7 @@ def create_app() -> FastAPI: app.include_router(menu_router) app.include_router(submenu_router) app.include_router(dish_router) + app.include_router(summary_router) def custom_openapi(): with open('openapi.json') as openapi: diff --git a/fastfood/repository/redis.py b/fastfood/repository/redis.py index a560efd..a32bdd4 100644 --- a/fastfood/repository/redis.py +++ b/fastfood/repository/redis.py @@ -63,3 +63,4 @@ class RedisRepository: async def invalidate(self, key: str, bg_task: BackgroundTasks) -> None: await self.clear_cache(f'{key}*', bg_task) await self.clear_cache(f'{get_key("menus")}*', bg_task) + await self.clear_cache('summary', bg_task) diff --git a/fastfood/repository/summary.py b/fastfood/repository/summary.py new file mode 100644 index 0000000..a2fef0a --- /dev/null +++ b/fastfood/repository/summary.py @@ -0,0 +1,19 @@ +from fastapi import Depends +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession +from sqlalchemy.orm import selectinload + +from fastfood.dbase import get_async_session +from fastfood.models import Menu, SubMenu + + +class SummaryRepository: + def __init__(self, session: AsyncSession = Depends(get_async_session)) -> None: + self.db = session + + async def get_data(self): + query = select(Menu).options( + selectinload(Menu.submenus).selectinload(SubMenu.dishes) + ) + data = await self.db.execute(query) + return [x for x in data.scalars().all()] diff --git a/fastfood/routers/summary.py b/fastfood/routers/summary.py new file mode 100644 index 0000000..ee36330 --- /dev/null +++ b/fastfood/routers/summary.py @@ -0,0 +1,17 @@ +from fastapi import APIRouter, BackgroundTasks, Depends + +from fastfood.schemas import MenuSummary +from fastfood.service.summary import SummaryService + +router = APIRouter( + prefix='/api/v1/summary', + tags=['summary'], +) + + +@router.get('/', response_model=list[MenuSummary]) +async def get_summary( + sum: SummaryService = Depends(), + background_tasks: BackgroundTasks = BackgroundTasks(), +) -> list[MenuSummary]: + return await sum.read_data() diff --git a/fastfood/schemas.py b/fastfood/schemas.py index cf14ecb..d068a35 100644 --- a/fastfood/schemas.py +++ b/fastfood/schemas.py @@ -34,3 +34,11 @@ class Dish(DishBase, Menu): class Dish_db(MenuBase): price: float + + +class SubMenuSummary(Menu): + dishes: list[Dish_db] + + +class MenuSummary(Menu): + submenus: list[SubMenuSummary] diff --git a/fastfood/service/summary.py b/fastfood/service/summary.py new file mode 100644 index 0000000..2c1a412 --- /dev/null +++ b/fastfood/service/summary.py @@ -0,0 +1,54 @@ +import redis.asyncio as redis # type: ignore +from fastapi import BackgroundTasks, Depends + +from fastfood.dbase import get_async_redis_client +from fastfood.repository.redis import RedisRepository, get_key +from fastfood.repository.summary import SummaryRepository +from fastfood.schemas import DishBase, MenuSummary, SubMenuSummary + + +class SummaryService: + def __init__( + self, + sum_repo: SummaryRepository = Depends(), + redis_client: redis.Redis = Depends(get_async_redis_client), + background_tasks: BackgroundTasks = None, + ) -> None: + self.sum_repo = sum_repo + self.cache = RedisRepository(redis_client) + self.key = get_key + self.bg_tasks = background_tasks + + async def read_data(self): + def dump_to_schema(schema, obj): + obj = obj.__dict__ + obj = {k: v for k, v in obj.items() if not k.startswith('_')} + if 'price' in obj.keys(): + obj['price'] = str(obj['price']) + return schema(**obj) + + cached_data = await self.cache.get(self.key('summary')) + if cached_data is not None: + return cached_data + + result = [] + data = await self.sum_repo.get_data() + for menu in data: + menus_res = dump_to_schema(MenuSummary, menu) + menus_res.submenus = [] + + for sub in menu.submenus: + sub_res = dump_to_schema(SubMenuSummary, sub) + sub_res.dishes = [] + + for dish in sub.dishes: + dish_res = dump_to_schema(DishBase, dish) + sub_res.dishes.append(dish_res) + + menus_res.submenus.append(sub_res) + + result.append(menus_res) + + await self.cache.set(self.key('summary'), data, self.bg_tasks) + + return result diff --git a/openapi.json b/openapi.json index 25d7b97..7e2baf3 100644 --- a/openapi.json +++ b/openapi.json @@ -1 +1,1203 @@ -{"openapi": "3.1.0", "info": {"title": "Fastfood-API", "description": "\n# \ud83d\udd25\ud83d\udd25\ud83d\udd25Fastfood-API \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0442\u0435\u0431\u0435 \u043f\u043e\u0434\u043a\u0440\u0435\u043f\u0438\u0442\u044c\u0441\u044f \ud83d\udd25\ud83d\udd25\ud83d\udd25\n\n### \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c Menu. \u0422\u044b \u043c\u043e\u0436\u0435\u0448 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0431\u043b\u044e\u0434\u0430 \u0438\u0437 \u043a\u0443\u0445\u043d\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0442\u0435\u0431\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f\n\n## Menu\n\n\u0422\u044b \u043c\u043e\u0436\u0435\u0448\u044c **add menu**.\n\n\u0422\u044b \u043c\u043e\u0436\u0435\u0448\u044c **read menu**.\n\n\u0422\u044b \u043c\u043e\u0436\u0435\u0448\u044c **patch menu**.\n\n\u0422\u044b \u043c\u043e\u0436\u0435\u0448\u044c **delete menu**.\n\n### \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432 SubMenu, \u0433\u0434\u0435 \u0442\u044b \u0441\u043c\u043e\u0436\u0435\u0448\u044c \u043d\u0430\u0439\u0442\u0438\n\u0434\u0435\u0441\u0435\u0440\u0442\u044b/\u043d\u0430\u043f\u0438\u0442\u043a\u0438/\u0441\u0443\u043f\u0447\u0438\u043a\u0438/\u043f\u0440\u043e\u0447\u0438\u0435 \u0432\u043a\u0443\u0441\u043d\u043e\u0441\u0442\u0438\n\n# SubMenu\n\n\u0422\u044b \u043c\u043e\u0436\u0435\u0448\u044c **add submenu into menu**.\n\n\u0422\u044b \u043c\u043e\u0436\u0435\u0448\u044c **read submenu**.\n\n\u0422\u044b \u043c\u043e\u0436\u0435\u0448\u044c **patch submenu**.\n\n\u0422\u044b \u043c\u043e\u0436\u0435\u0448\u044c **delete menu**.\n\n### \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432 Dish, \u0433\u0434\u0435 \u0442\u044b \u0441\u043c\u043e\u0436\u0435\u0448\u044c \u043d\u0430\u0439\u0442\u0438 \u0431\u043b\u044e\u0434\u043e \u043f\u043e \u0432\u043a\u0443\u0441\u0443\n\n# Dish\n\n\u0422\u044b \u043c\u043e\u0436\u0435\u0448\u044c **add dish into submenu**.\n\n\u0422\u044b \u043c\u043e\u0436\u0435\u0448\u044c **read dish**.\n\n\u0422\u044b \u043c\u043e\u0436\u0435\u0448\u044c **patch dish**.\n\n\u0422\u044b \u043c\u043e\u0436\u0435\u0448\u044c **delete dish**.\n\n## \u041f\u0440\u0438\u044f\u0442\u043d\u043e\u0433\u043e \u0430\u043f\u043f\u0435\u0442\u0438\u0442\u0430\n", "contact": {"name": "Sergey Vanyushkin", "url": "http://pi3c.ru/", "email": "pi3c@yandex.ru"}, "license": {"name": "MIT license", "url": "https://mit-license.org/"}, "version": "0.0.3"}, "paths": {"/api/v1/menus/": {"get": {"tags": ["menu"], "summary": "\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043c\u0435\u043d\u044e", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u043c\u0435\u043d\u044e.", "operationId": "get_menus_api_v1_menus__get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/MenuRead"}, "type": "array", "title": "Response Get Menus Api V1 Menus Get"}}}}}}, "post": {"tags": ["menu"], "summary": "\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043c\u0435\u043d\u044e", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043c\u0435\u043d\u044e", "operationId": "add_menu_api_v1_menus__post", "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/MenuBase"}}}, "required": true}, "responses": {"201": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MenuRead"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/v1/menus/{menu_id}": {"get": {"tags": ["menu"], "summary": "\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043c\u0435\u043d\u044e", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043c\u0435\u043d\u044e \u043f\u043e \u0435\u0433\u043e UUID", "operationId": "get_menu_api_v1_menus__menu_id__get", "parameters": [{"name": "menu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Menu Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MenuRead"}}}}, "404": {"description": "Menu not found", "content": {"application/json": {"example": {"detail": "sting"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "patch": {"tags": ["menu"], "summary": "\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043c\u0435\u043d\u044e", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043c\u0435\u043d\u044e \u043f\u043e \u0435\u0433\u043e UUID", "operationId": "update_menu_api_v1_menus__menu_id__patch", "parameters": [{"name": "menu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Menu Id"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MenuBase"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MenuRead"}}}}, "404": {"description": "Menu not found", "content": {"application/json": {"example": {"detail": "string"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "delete": {"tags": ["menu"], "summary": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043c\u0435\u043d\u044e", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043c\u0435\u043d\u044e \u043f\u043e \u0435\u0433\u043e UUID", "operationId": "delete_menu_api_v1_menus__menu_id__delete", "parameters": [{"name": "menu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Menu Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/v1/menus/{menu_id}/submenus/": {"get": {"tags": ["submenu"], "summary": "\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u0434\u043c\u0435\u043d\u044e", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u0434\u043c\u0435\u043d\u044e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u044e \u043f\u043e UUID \u043c\u0435\u043d\u044e", "operationId": "get_submenus_api_v1_menus__menu_id__submenus__get", "parameters": [{"name": "menu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Menu Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"type": "array", "items": {"$ref": "#/components/schemas/SubMenuRead"}, "title": "Response Get Submenus Api V1 Menus Menu Id Submenus Get"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "post": {"tags": ["submenu"], "summary": "\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e\u0434\u043c\u0435\u043d\u044e", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e\u0434\u043c\u0435\u043d\u044e \u043f\u043e UUID \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u0441\u043a\u043e\u0433\u043e \u043c\u0435\u043d\u044e", "operationId": "create_submenu_item_api_v1_menus__menu_id__submenus__post", "parameters": [{"name": "menu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Menu Id"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MenuBase"}}}}, "responses": {"201": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SubMenuRead"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/v1/menus/{menu_id}/submenus/{submenu_id}": {"get": {"tags": ["submenu"], "summary": "\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u043c\u0435\u043d\u044e", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u043c\u0435\u043d\u044e \u043f\u043e \u0435\u0433\u043e UUID \u0438 UUID \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043c\u0435\u043d\u044e", "operationId": "get_submenu_api_v1_menus__menu_id__submenus__submenu_id__get", "parameters": [{"name": "menu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Menu Id"}}, {"name": "submenu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Submenu Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SubMenuRead"}}}}, "404": {"description": "Submenu not found", "content": {"application/json": {"example": {"detail": "string"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "patch": {"tags": ["submenu"], "summary": "\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u043c\u0435\u043d\u044e", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u043c\u0435\u043d\u044e \u043f\u043e \u0435\u0433\u043e UUID \u0438 UUID \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043c\u0435\u043d\u044e", "operationId": "update_submenu_api_v1_menus__menu_id__submenus__submenu_id__patch", "parameters": [{"name": "menu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Menu Id"}}, {"name": "submenu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Submenu Id"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MenuBase"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SubMenuRead"}}}}, "404": {"description": "Submenu not found", "content": {"application/json": {"example": {"detail": "string"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "delete": {"tags": ["submenu"], "summary": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u043e\u0434\u043c\u0435\u043d\u044e", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u043e\u0434\u043c\u0435\u043d\u044e \u043f\u043e \u0435\u0433\u043e UUID", "operationId": "delete_submenu_api_v1_menus__menu_id__submenus__submenu_id__delete", "parameters": [{"name": "menu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Menu Id"}}, {"name": "submenu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Submenu Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/v1/menus/{menu_id}/submenus/{submenu_id}/dishes/": {"get": {"tags": ["dish"], "summary": "\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0431\u043b\u044e\u0434", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0431\u043b\u044e\u0434\u0430 \u043f\u043e UUID \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043c\u0435\u043d\u044e \u0438 \u043f\u043e\u0434\u043c\u0435\u043d\u044e", "operationId": "get_dishes_api_v1_menus__menu_id__submenus__submenu_id__dishes__get", "parameters": [{"name": "menu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Menu Id"}}, {"name": "submenu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Submenu Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"type": "array", "items": {"$ref": "#/components/schemas/Dish"}, "title": "Response Get Dishes Api V1 Menus Menu Id Submenus Submenu Id Dishes Get"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "post": {"tags": ["dish"], "summary": "\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u043b\u044e\u0434\u043e", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u043b\u044e\u0434\u043e \u043f\u043e UUID\u0435\u0433\u043e \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043c\u0435\u043d\u044e \u0438 \u043f\u043e\u0434\u043c\u0435\u043d\u044e", "operationId": "create_dish_api_v1_menus__menu_id__submenus__submenu_id__dishes__post", "parameters": [{"name": "menu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Menu Id"}}, {"name": "submenu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Submenu Id"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DishBase"}}}}, "responses": {"201": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Dish"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/v1/menus/{menu_id}/submenus/{submenu_id}/dishes/{dish_id}": {"get": {"tags": ["dish"], "summary": "\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u043b\u044e\u0434\u043e", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u043b\u044e\u0434\u043e \u043f\u043e \u0435\u0433\u043e UUID \u0438 UUID \u0435\u0433\u043e \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043c\u0435\u043d\u044e", "operationId": "get_dish_api_v1_menus__menu_id__submenus__submenu_id__dishes__dish_id__get", "parameters": [{"name": "menu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Menu Id"}}, {"name": "submenu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Submenu Id"}}, {"name": "dish_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Dish Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Dish"}}}}, "404": {"description": "Dish not found", "content": {"application/json": {"example": {"detail": "string"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "patch": {"tags": ["dish"], "summary": "\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0431\u043b\u044e\u0434\u043e", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0431\u043b\u044e\u0434\u043e \u043f\u043e \u0435\u0433\u043e UUID \u0438 UUID \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043c\u0435\u043d\u044e", "operationId": "update_dish_api_v1_menus__menu_id__submenus__submenu_id__dishes__dish_id__patch", "parameters": [{"name": "menu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Menu Id"}}, {"name": "submenu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Submenu Id"}}, {"name": "dish_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Dish Id"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DishBase"}}}}, "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Dish"}}}}, "404": {"description": "Dish not found", "content": {"application/json": {"example": {"detail": "string"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "delete": {"tags": ["dish"], "summary": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0431\u043b\u044e\u0434\u043e", "description": "\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0431\u043b\u044e\u0434\u043e \u043f\u043e \u0435\u0433\u043e UUID \u0438 UUID \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043c\u0435\u043d\u044e", "operationId": "delete_dish_api_v1_menus__menu_id__submenus__submenu_id__dishes__dish_id__delete", "parameters": [{"name": "menu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Menu Id"}}, {"name": "submenu_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Submenu Id"}}, {"name": "dish_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid", "title": "Dish Id"}}], "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}}, "components": {"schemas": {"Dish": {"properties": {"title": {"type": "string", "title": "Title"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "id": {"type": "string", "format": "uuid", "title": "Id"}, "price": {"type": "string", "title": "Price"}}, "type": "object", "required": ["title", "description", "id", "price"], "title": "Dish"}, "DishBase": {"properties": {"title": {"type": "string", "title": "Title"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "price": {"type": "string", "title": "Price"}}, "type": "object", "required": ["title", "description", "price"], "title": "DishBase"}, "HTTPValidationError": {"properties": {"detail": {"items": {"$ref": "#/components/schemas/ValidationError"}, "type": "array", "title": "Detail"}}, "type": "object", "title": "HTTPValidationError"}, "MenuBase": {"properties": {"title": {"type": "string", "title": "Title"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}}, "type": "object", "required": ["title", "description"], "title": "MenuBase"}, "MenuRead": {"properties": {"title": {"type": "string", "title": "Title"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "id": {"type": "string", "format": "uuid", "title": "Id"}, "submenus_count": {"type": "integer", "title": "Submenus Count"}, "dishes_count": {"type": "integer", "title": "Dishes Count"}}, "type": "object", "required": ["title", "description", "id", "submenus_count", "dishes_count"], "title": "MenuRead"}, "SubMenuRead": {"properties": {"title": {"type": "string", "title": "Title"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "id": {"type": "string", "format": "uuid", "title": "Id"}, "dishes_count": {"type": "integer", "title": "Dishes Count"}}, "type": "object", "required": ["title", "description", "id", "dishes_count"], "title": "SubMenuRead"}, "ValidationError": {"properties": {"loc": {"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, "type": "array", "title": "Location"}, "msg": {"type": "string", "title": "Message"}, "type": {"type": "string", "title": "Error Type"}}, "type": "object", "required": ["loc", "msg", "type"], "title": "ValidationError"}}}, "tags": [{"name": "menu", "description": "\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441 \u043c\u0435\u043d\u044e."}, {"name": "submenu", "description": "\u041f\u043e\u0434\u043c\u0435\u043d\u044e \u0438 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u043d\u0438\u043c"}, {"name": "dish", "description": "\u0411\u043b\u044e\u0434\u0430 \u0438 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u043d\u0438\u043c\u0438"}]} +{ + "openapi": "3.1.0", + "info": { + "title": "Fastfood-API", + "description": "\n# 🔥🔥🔥Fastfood-API поможет тебе подкрепиться 🔥🔥🔥\n\n### У нас есть Menu. Ты можеш выбрать блюда из кухни, которая тебе нравится\n\n## Menu\n\nТы можешь **add menu**.\n\nТы можешь **read menu**.\n\nТы можешь **patch menu**.\n\nТы можешь **delete menu**.\n\n### У нас есть в SubMenu, где ты сможешь найти\nдесерты/напитки/супчики/прочие вкусности\n\n# SubMenu\n\nТы можешь **add submenu into menu**.\n\nТы можешь **read submenu**.\n\nТы можешь **patch submenu**.\n\nТы можешь **delete menu**.\n\n### У нас есть в Dish, где ты сможешь найти блюдо по вкусу\n\n# Dish\n\nТы можешь **add dish into submenu**.\n\nТы можешь **read dish**.\n\nТы можешь **patch dish**.\n\nТы можешь **delete dish**.\n\n# Summary\n\nМожеш посмотреть все меню целиком\n\n## Приятного аппетита\n", + "contact": { + "name": "Sergey Vanyushkin", + "url": "http://pi3c.ru/", + "email": "pi3c@yandex.ru" + }, + "license": { + "name": "MIT license", + "url": "https://mit-license.org/" + }, + "version": "0.0.3" + }, + "paths": { + "/api/v1/menus/": { + "get": { + "tags": [ + "menu" + ], + "summary": "Получить список меню", + "description": "Этот метод позволяет получить все меню.", + "operationId": "get_menus_api_v1_menus__get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/MenuRead" + }, + "type": "array", + "title": "Response Get Menus Api V1 Menus Get" + } + } + } + } + } + }, + "post": { + "tags": [ + "menu" + ], + "summary": "Создать меню", + "description": "Этот метод позволяет создать меню", + "operationId": "add_menu_api_v1_menus__post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MenuBase" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MenuRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/menus/{menu_id}": { + "get": { + "tags": [ + "menu" + ], + "summary": "Получить меню", + "description": "Этот метод позволяет получить меню по его UUID", + "operationId": "get_menu_api_v1_menus__menu_id__get", + "parameters": [ + { + "name": "menu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Menu Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MenuRead" + } + } + } + }, + "404": { + "description": "Menu not found", + "content": { + "application/json": { + "example": { + "detail": "sting" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "patch": { + "tags": [ + "menu" + ], + "summary": "Обновить меню", + "description": "Этот метод позволяет изменить меню по его UUID", + "operationId": "update_menu_api_v1_menus__menu_id__patch", + "parameters": [ + { + "name": "menu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Menu Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MenuBase" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MenuRead" + } + } + } + }, + "404": { + "description": "Menu not found", + "content": { + "application/json": { + "example": { + "detail": "string" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "menu" + ], + "summary": "Удалить меню", + "description": "Этот метод позволяет удалить меню по его UUID", + "operationId": "delete_menu_api_v1_menus__menu_id__delete", + "parameters": [ + { + "name": "menu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Menu Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/menus/{menu_id}/submenus/": { + "get": { + "tags": [ + "submenu" + ], + "summary": "Получить список подменю", + "description": "Этот метод позволяет получить список подменю основного меню по UUID меню", + "operationId": "get_submenus_api_v1_menus__menu_id__submenus__get", + "parameters": [ + { + "name": "menu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Menu Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SubMenuRead" + }, + "title": "Response Get Submenus Api V1 Menus Menu Id Submenus Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "submenu" + ], + "summary": "Создать подменю", + "description": "Этот метод позволяет создать подменю по UUID родителского меню", + "operationId": "create_submenu_item_api_v1_menus__menu_id__submenus__post", + "parameters": [ + { + "name": "menu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Menu Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MenuBase" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubMenuRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/menus/{menu_id}/submenus/{submenu_id}": { + "get": { + "tags": [ + "submenu" + ], + "summary": "Получить подменю", + "description": "Этот метод позволяет получить подменю по его UUID и UUID родительского меню", + "operationId": "get_submenu_api_v1_menus__menu_id__submenus__submenu_id__get", + "parameters": [ + { + "name": "menu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Menu Id" + } + }, + { + "name": "submenu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Submenu Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubMenuRead" + } + } + } + }, + "404": { + "description": "Submenu not found", + "content": { + "application/json": { + "example": { + "detail": "string" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "patch": { + "tags": [ + "submenu" + ], + "summary": "Обновить подменю", + "description": "Этот метод позволяет обновить подменю по его UUID и UUID родительского меню", + "operationId": "update_submenu_api_v1_menus__menu_id__submenus__submenu_id__patch", + "parameters": [ + { + "name": "menu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Menu Id" + } + }, + { + "name": "submenu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Submenu Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MenuBase" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubMenuRead" + } + } + } + }, + "404": { + "description": "Submenu not found", + "content": { + "application/json": { + "example": { + "detail": "string" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "submenu" + ], + "summary": "Удалить подменю", + "description": "Этот метод позволяет удалить подменю по его UUID", + "operationId": "delete_submenu_api_v1_menus__menu_id__submenus__submenu_id__delete", + "parameters": [ + { + "name": "menu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Menu Id" + } + }, + { + "name": "submenu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Submenu Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/menus/{menu_id}/submenus/{submenu_id}/dishes/": { + "get": { + "tags": [ + "dish" + ], + "summary": "Получить список блюд", + "description": "Этот метод позволяет получить список всех блюда по UUID родительских меню и подменю", + "operationId": "get_dishes_api_v1_menus__menu_id__submenus__submenu_id__dishes__get", + "parameters": [ + { + "name": "menu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Menu Id" + } + }, + { + "name": "submenu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Submenu Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Dish" + }, + "title": "Response Get Dishes Api V1 Menus Menu Id Submenus Submenu Id Dishes Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "dish" + ], + "summary": "Создать блюдо", + "description": "Этот метод позволяет создать блюдо по UUIDего родительских меню и подменю", + "operationId": "create_dish_api_v1_menus__menu_id__submenus__submenu_id__dishes__post", + "parameters": [ + { + "name": "menu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Menu Id" + } + }, + { + "name": "submenu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Submenu Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DishBase" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Dish" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/menus/{menu_id}/submenus/{submenu_id}/dishes/{dish_id}": { + "get": { + "tags": [ + "dish" + ], + "summary": "Получить блюдо", + "description": "Этот метод позволяет получить блюдо по его UUID и UUID его родительских меню", + "operationId": "get_dish_api_v1_menus__menu_id__submenus__submenu_id__dishes__dish_id__get", + "parameters": [ + { + "name": "menu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Menu Id" + } + }, + { + "name": "submenu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Submenu Id" + } + }, + { + "name": "dish_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Dish Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Dish" + } + } + } + }, + "404": { + "description": "Dish not found", + "content": { + "application/json": { + "example": { + "detail": "string" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "patch": { + "tags": [ + "dish" + ], + "summary": "Обновить блюдо", + "description": "Этот метод позволяет обновить блюдо по его UUID и UUID родительских меню", + "operationId": "update_dish_api_v1_menus__menu_id__submenus__submenu_id__dishes__dish_id__patch", + "parameters": [ + { + "name": "menu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Menu Id" + } + }, + { + "name": "submenu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Submenu Id" + } + }, + { + "name": "dish_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Dish Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DishBase" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Dish" + } + } + } + }, + "404": { + "description": "Dish not found", + "content": { + "application/json": { + "example": { + "detail": "string" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "dish" + ], + "summary": "Удалить блюдо", + "description": "Этот метод позволяет удалить блюдо по его UUID и UUID родительских меню", + "operationId": "delete_dish_api_v1_menus__menu_id__submenus__submenu_id__dishes__dish_id__delete", + "parameters": [ + { + "name": "menu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Menu Id" + } + }, + { + "name": "submenu_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Submenu Id" + } + }, + { + "name": "dish_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Dish Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/v1/summary/": { + "get": { + "tags": [ + "summary" + ], + "summary": "Получить все меню", + "description": "Этот метод позволяет получить полную структуру меню состоящую из меню, подменю и блюд", + "operationId": "get_summary_api_v1_summary__get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/MenuSummary" + }, + "type": "array", + "title": "Response Get Summary Api V1 Summary Get" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Dish": { + "properties": { + "title": { + "type": "string", + "title": "Title" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "price": { + "type": "string", + "title": "Price" + } + }, + "type": "object", + "required": [ + "title", + "description", + "id", + "price" + ], + "title": "Dish" + }, + "DishBase": { + "properties": { + "title": { + "type": "string", + "title": "Title" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "price": { + "type": "string", + "title": "Price" + } + }, + "type": "object", + "required": [ + "title", + "description", + "price" + ], + "title": "DishBase" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "MenuBase": { + "properties": { + "title": { + "type": "string", + "title": "Title" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + } + }, + "type": "object", + "required": [ + "title", + "description" + ], + "title": "MenuBase" + }, + "MenuRead": { + "properties": { + "title": { + "type": "string", + "title": "Title" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "submenus_count": { + "type": "integer", + "title": "Submenus Count" + }, + "dishes_count": { + "type": "integer", + "title": "Dishes Count" + } + }, + "type": "object", + "required": [ + "title", + "description", + "id", + "submenus_count", + "dishes_count" + ], + "title": "MenuRead" + }, + "SubMenuRead": { + "properties": { + "title": { + "type": "string", + "title": "Title" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "dishes_count": { + "type": "integer", + "title": "Dishes Count" + } + }, + "type": "object", + "required": [ + "title", + "description", + "id", + "dishes_count" + ], + "title": "SubMenuRead" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "MenuSummary": { + "properties": { + "title": { + "type": "string", + "title": "Title" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "submenus": { + "items": { + "$ref": "#/components/schemas/SubMenuSummary" + }, + "type": "array", + "title": "Submenus" + } + }, + "type": "object", + "required": [ + "title", + "description", + "id", + "submenus" + ], + "title": "MenuSummary" + }, + "SubMenuSummary": { + "properties": { + "title": { + "type": "string", + "title": "Title" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "dishes": { + "items": { + "$ref": "#/components/schemas/DishBase" + }, + "type": "array", + "title": "Dishes" + } + }, + "type": "object", + "required": [ + "title", + "description", + "id", + "dishes" + ], + "title": "SubMenuSummary" + } + } + }, + "tags": [ + { + "name": "menu", + "description": "Операции с меню." + }, + { + "name": "submenu", + "description": "Подменю и работа с ним" + }, + { + "name": "dish", + "description": "Блюда и работа с ними" + }, + { + "name": "summary", + "description": "Вывод всей структуры меню" + } + ] +}