diff --git a/admin/Menu.xlsx b/admin/Menu.xlsx new file mode 100644 index 0000000..a76c326 Binary files /dev/null and b/admin/Menu.xlsx differ diff --git a/fastfood/app.py b/fastfood/app.py index 2e1f6cf..a2e57c3 100644 --- a/fastfood/app.py +++ b/fastfood/app.py @@ -5,6 +5,7 @@ from fastapi import FastAPI from fastfood.routers.dish import router as dish_router from fastfood.routers.menu import router as menu_router from fastfood.routers.submenu import router as submenu_router +from fastfood.routers.summary import router as summary_router def create_app() -> 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": "Вывод всей структуры меню" + } + ] +}