diff --git a/fastfood/app.py b/fastfood/app.py index 202ef5f..980a822 100644 --- a/fastfood/app.py +++ b/fastfood/app.py @@ -1,11 +1,53 @@ -import json - 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 +description = """ +# 🔥🔥🔥Fastfood-API поможет тебе подкрепиться 🔥🔥🔥 + +### У нас есть Menu. Ты можеш выбрать блюда из кухни, которая тебе нравится + +## Menu + +Ты можешь **add menu**. + +Ты можешь **read menu**. + +Ты можешь **patch menu**. + +Ты можешь **delete menu**. + +### У нас есть в SubMenu, где ты сможешь найти +десерты/напитки/супчики/прочие вкусности + +# SubMenu + +Ты можешь **add submenu into menu**. + +Ты можешь **read submenu**. + +Ты можешь **patch submenu**. + +Ты можешь **delete menu**. + +### У нас есть в Dish, где ты сможешь найти блюдо по вкусу + +# Dish + +Ты можешь **add dish into submenu**. + +Ты можешь **read dish**. + +Ты можешь **patch dish**. + +Ты можешь **delete dish**. + +## Приятного аппетита +""" + + tags_metadata = [ { 'name': 'menu', @@ -23,13 +65,10 @@ def create_app(redis=None) -> FastAPI: """ Фабрика FastAPI. """ - with open('openapi.json') as f: - js = json.load(f) - app = FastAPI( - title=js['info']['title'], - description=js['info']['description'], - version=js['info']['version'], + title='Fastfood-API', + description=description, + version='0.0.3', contact={ 'name': 'Sergey Vanyushkin', 'url': 'http://pi3c.ru', diff --git a/fastfood/repository/dish.py b/fastfood/repository/dish.py index b7cf10b..37e5c29 100644 --- a/fastfood/repository/dish.py +++ b/fastfood/repository/dish.py @@ -49,13 +49,13 @@ class DishRepository: submenu_id: UUID, dish_id: UUID, dish_data: Dish_db, - ) -> Dish: + ) -> Dish | None: query = update(Dish).where(Dish.id == dish_id).values(**dish_data.model_dump()) await self.db.execute(query) await self.db.commit() qr = select(Dish).where(Dish.id == dish_id) updated_submenu = await self.db.execute(qr) - return updated_submenu.scalars().one() + return updated_submenu.scalar_one_or_none() async def delete_dish_item( self, diff --git a/fastfood/repository/menu.py b/fastfood/repository/menu.py index 3e18964..8d7843a 100644 --- a/fastfood/repository/menu.py +++ b/fastfood/repository/menu.py @@ -50,13 +50,13 @@ class MenuRepository: self, menu_id: UUID, menu: schemas.MenuBase, - ) -> Menu: + ) -> Menu | None: query = update(Menu).where(Menu.id == menu_id).values(**menu.model_dump()) await self.db.execute(query) await self.db.commit() qr = select(Menu).where(Menu.id == menu_id) updated_menu = await self.db.execute(qr) - return updated_menu.scalar_one() + return updated_menu.scalar_one_or_none() async def delete_menu_item(self, menu_id: UUID) -> None: query = delete(Menu).where(Menu.id == menu_id) diff --git a/fastfood/repository/redis.py b/fastfood/repository/redis.py index f3732cd..a560efd 100644 --- a/fastfood/repository/redis.py +++ b/fastfood/repository/redis.py @@ -31,7 +31,7 @@ class RedisRepository: pool: redis.Redis = Depends(get_redis_pool), ) -> None: self.pool = pool - self.ttl = 2 + self.ttl = 1800 async def get(self, key: str) -> Any | None: data = await self.pool.get(key) diff --git a/fastfood/repository/submenu.py b/fastfood/repository/submenu.py index 5115930..28695fc 100644 --- a/fastfood/repository/submenu.py +++ b/fastfood/repository/submenu.py @@ -59,7 +59,7 @@ class SubMenuRepository: menu_id: UUID, submenu_id: UUID, submenu_data: MenuBase, - ) -> SubMenu: + ) -> SubMenu | None: query = ( update(SubMenu) .where(SubMenu.id == submenu_id) @@ -69,7 +69,7 @@ class SubMenuRepository: await self.db.commit() qr = select(SubMenu).where(SubMenu.id == submenu_id) updated_submenu = await self.db.execute(qr) - return updated_submenu.scalar_one() + return updated_submenu.scalar_one_or_none() async def delete_submenu_item(self, menu_id: UUID, submenu_id: UUID) -> None: query = delete(SubMenu).where( diff --git a/fastfood/routers/dish.py b/fastfood/routers/dish.py index c438e92..7fd50a7 100644 --- a/fastfood/routers/dish.py +++ b/fastfood/routers/dish.py @@ -11,7 +11,13 @@ router = APIRouter( ) -@router.get('/', response_model=list[Dish]) +@router.get( + '/', + response_model=list[Dish], + summary='Получить список блюд', + description='Этот метод позволяет получить список всех блюда по UUID' + ' родительских меню и подменю', +) async def get_dishes( menu_id: UUID, submenu_id: UUID, @@ -22,7 +28,14 @@ async def get_dishes( return result -@router.post('/', status_code=201, response_model=Dish) +@router.post( + '/', + status_code=201, + response_model=Dish, + summary='Создать блюдо', + description='Этот метод позволяет создать блюдо по UUID' + 'его родительских меню и подменю', +) async def create_dish( menu_id: UUID, submenu_id: UUID, @@ -37,7 +50,19 @@ async def create_dish( ) -@router.get('/{dish_id}', response_model=Dish) +@router.get( + '/{dish_id}', + response_model=Dish, + summary='Получить блюдо', + description='Этот метод позволяет получить блюдо по его UUID' + ' и UUID его родительских меню', + responses={ + 404: { + 'description': 'Dish not found', + 'content': {'application/json': {'example': {'detail': 'string'}}}, + }, + }, +) async def get_dish( menu_id: UUID, submenu_id: UUID, @@ -51,11 +76,26 @@ async def get_dish( dish_id, ) if not result: - raise HTTPException(status_code=404, detail='dish not found') + raise HTTPException( + status_code=404, + detail=f'Блюдо c UUID={dish_id} не существует, доступ невозможен', + ) return result -@router.patch('/{dish_id}', response_model=Dish) +@router.patch( + '/{dish_id}', + response_model=Dish, + summary='Обновить блюдо', + description='Этот метод позволяет обновить блюдо по его UUID' + ' и UUID родительских меню', + responses={ + 404: { + 'description': 'Dish not found', + 'content': {'application/json': {'example': {'detail': 'string'}}}, + }, + }, +) async def update_dish( menu_id: UUID, submenu_id: UUID, @@ -70,10 +110,20 @@ async def update_dish( dish_id, dish_data, ) + if not result: + raise HTTPException( + status_code=404, + detail=f'Блюдо c UUID={dish_id} не существует, обновление невозможно', + ) return result -@router.delete('/{dish_id}') +@router.delete( + '/{dish_id}', + summary='Удалить блюдо', + description='Этот метод позволяет удалить блюдо по его UUID' + ' и UUID родительских меню', +) async def delete_dish( menu_id: UUID, submenu_id: UUID, diff --git a/fastfood/routers/menu.py b/fastfood/routers/menu.py index 3ed743e..f42b27b 100644 --- a/fastfood/routers/menu.py +++ b/fastfood/routers/menu.py @@ -11,7 +11,13 @@ router = APIRouter( ) -@router.get('/', response_model=list[MenuRead]) +@router.get( + '/', + status_code=200, + response_model=list[MenuRead], + summary='Получить список меню', + description='Этот метод позволяет получить все меню.', +) async def get_menus( menu: MenuService = Depends(), background_tasks: BackgroundTasks = BackgroundTasks(), @@ -19,7 +25,13 @@ async def get_menus( return await menu.read_menus() -@router.post('/', status_code=201, response_model=MenuRead) +@router.post( + '/', + status_code=201, + response_model=MenuRead, + summary='Создать меню', + description='Этот метод позволяет создать меню', +) async def add_menu( menu: MenuBase, responce: MenuService = Depends(), @@ -28,7 +40,18 @@ async def add_menu( return await responce.create_menu(menu) -@router.get('/{menu_id}', response_model=MenuRead) +@router.get( + '/{menu_id}', + response_model=MenuRead, + summary='Получить меню', + description='Этот метод позволяет получить меню по его UUID', + responses={ + 404: { + 'description': 'Menu not found', + 'content': {'application/json': {'example': {'detail': 'sting'}}}, + }, + }, +) async def get_menu( menu_id: UUID, responce: MenuService = Depends(), @@ -37,11 +60,25 @@ async def get_menu( result = await responce.read_menu(menu_id=menu_id) if not result: - raise HTTPException(status_code=404, detail='menu not found') + raise HTTPException( + status_code=404, + detail=f'Меню c UUID={menu_id} не существует, доступ невозможен', + ) return result -@router.patch('/{menu_id}', response_model=MenuRead) +@router.patch( + '/{menu_id}', + response_model=MenuRead, + summary='Обновить меню', + description='Этот метод позволяет изменить меню по его UUID', + responses={ + 404: { + 'description': 'Menu not found', + 'content': {'application/json': {'example': {'detail': 'string'}}}, + }, + }, +) async def update_menu( menu_id: UUID, menu: MenuBase, @@ -52,10 +89,21 @@ async def update_menu( menu_id=menu_id, menu_data=menu, ) + if not result: + raise HTTPException( + status_code=404, + detail=f'Меню c UUID={menu_id} не существует, Обновление невозможно', + ) + return result -@router.delete('/{menu_id}') +@router.delete( + '/{menu_id}', + status_code=200, + summary='Удалить меню', + description='Этот метод позволяет удалить меню по его UUID', +) async def delete_menu( menu_id: UUID, menu: MenuService = Depends(), diff --git a/fastfood/routers/submenu.py b/fastfood/routers/submenu.py index 55e1060..c30fb3f 100644 --- a/fastfood/routers/submenu.py +++ b/fastfood/routers/submenu.py @@ -11,7 +11,13 @@ router = APIRouter( ) -@router.get('/', response_model=list[SubMenuRead]) +@router.get( + '/', + response_model=list[SubMenuRead], + summary='Получить список подменю', + description='Этот метод позволяет получить список подменю основного меню' + ' по UUID меню', +) async def get_submenus( menu_id: UUID, submenu: SubmenuService = Depends(), @@ -21,7 +27,13 @@ async def get_submenus( return result -@router.post('/', status_code=201, response_model=SubMenuRead) +@router.post( + '/', + status_code=201, + response_model=SubMenuRead, + summary='Создать подменю', + description='Этот метод позволяет создать подменю по UUID родителского меню', +) async def create_submenu_item( menu_id: UUID, submenu_data: MenuBase, @@ -35,7 +47,19 @@ async def create_submenu_item( return result -@router.get('/{submenu_id}', response_model=SubMenuRead) +@router.get( + '/{submenu_id}', + response_model=SubMenuRead, + summary='Получить подменю', + description='Этот метод позволяет получить подменю по его UUID' + ' и UUID родительского меню', + responses={ + 404: { + 'description': 'Submenu not found', + 'content': {'application/json': {'example': {'detail': 'string'}}}, + }, + }, +) async def get_submenu( menu_id: UUID, submenu_id: UUID, @@ -47,13 +71,25 @@ async def get_submenu( submenu_id=submenu_id, ) if not result: - raise HTTPException(status_code=404, detail='submenu not found') + raise HTTPException( + status_code=404, + detail=f'Подменю c UUID={submenu_id} не существует, доступ невозможен', + ) return result @router.patch( '/{submenu_id}', response_model=SubMenuRead, + summary='Обновить подменю', + description='Этот метод позволяет обновить подменю по его UUID' + ' и UUID родительского меню', + responses={ + 404: { + 'description': 'Submenu not found', + 'content': {'application/json': {'example': {'detail': 'string'}}}, + }, + }, ) async def update_submenu( menu_id: UUID, @@ -67,10 +103,20 @@ async def update_submenu( submenu_id=submenu_id, submenu_data=submenu_data, ) + if not result: + raise HTTPException( + status_code=404, + detail=f'Gjlvеню c UUID={submenu_id} не существует, обновление невозможно', + ) + return result -@router.delete('/{submenu_id}') +@router.delete( + '/{submenu_id}', + summary='Удалить подменю', + description='Этот метод позволяет удалить подменю по его UUID', +) async def delete_submenu( menu_id: UUID, submenu_id: UUID, diff --git a/fastfood/service/dish.py b/fastfood/service/dish.py index 4ea3fe9..689f4f0 100644 --- a/fastfood/service/dish.py +++ b/fastfood/service/dish.py @@ -103,14 +103,19 @@ class DishService: async def update_dish( self, menu_id: UUID, submenu_id: UUID, dish_id, dish_data: DishBase - ) -> Dish: + ) -> Dish | None: dish_db = Dish_db(**dish_data.model_dump()) data = await self.dish_repo.update_dish_item( menu_id, submenu_id, dish_id, dish_db ) + + if data is None: + return None + dish = data.__dict__ dish['price'] = str(dish['price']) dish = Dish(**dish) + await self.cache.set( self.key( 'dish', diff --git a/fastfood/service/menu.py b/fastfood/service/menu.py index d9c26e9..5fc8e0a 100644 --- a/fastfood/service/menu.py +++ b/fastfood/service/menu.py @@ -87,8 +87,10 @@ class MenuService: ) return menu - async def update_menu(self, menu_id: UUID, menu_data) -> MenuRead: + async def update_menu(self, menu_id: UUID, menu_data) -> MenuRead | None: data = await self.menu_repo.update_menu_item(menu_id, menu_data) + if data is None: + return None menu = data.__dict__ menu = {k: v for k, v in menu.items() if not k.startswith('_')} dishes_conter = 0 diff --git a/fastfood/service/submenu.py b/fastfood/service/submenu.py index 68aefc1..d020434 100644 --- a/fastfood/service/submenu.py +++ b/fastfood/service/submenu.py @@ -89,14 +89,18 @@ class SubmenuService: async def update_submenu( self, menu_id: UUID, submenu_id: UUID, submenu_data: MenuBase - ) -> SubMenuRead: + ) -> SubMenuRead | None: data = await self.submenu_repo.update_submenu_item( menu_id, submenu_id, submenu_data ) + if data is None: + return None + submenu = data.__dict__ submenu = {k: v for k, v in submenu.items() if not k.startswith('_')} submenu['dishes_count'] = len(submenu.pop('dishes')) submenu = SubMenuRead(**submenu) + await self.cache.set( self.key('submenu', menu_id=str(menu_id), submenu_id=str(submenu_id)), submenu, diff --git a/manage.py b/manage.py index f204f65..3859784 100644 --- a/manage.py +++ b/manage.py @@ -1,11 +1,33 @@ import asyncio +import json import sys import uvicorn +from fastapi.openapi.utils import get_openapi +from fastfood.app import create_app from fastfood.repository import create_db_and_tables +def create_openapi(): + app = create_app() + + with open('openapi.json', 'w') as f: + json.dump( + get_openapi( + title=app.title, + version=app.version, + openapi_version=app.openapi_version, + description=app.description, + routes=app.routes, + contact=app.contact, + license_info=app.license_info, + tags=app.openapi_tags, + ), + f, + ) + + def run_app(): """ Запуск FastAPI @@ -32,3 +54,6 @@ if __name__ == '__main__': if '--run-test-server' in sys.argv: asyncio.run(recreate()) run_app() + + if 'dump' in sys.argv: + create_openapi() diff --git a/openapi.json b/openapi.json index e41830d..25d7b97 100644 --- a/openapi.json +++ b/openapi.json @@ -1 +1 @@ -{"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", "version": "0.0.1"}, "paths": {"/api/v1/menus/": {"get": {"tags": ["menu"], "summary": "Get Menus", "operationId": "get_menus_api_v1_menus__get", "responses": {"200": {"description": "Successful Response", "content": {"application/json": {"schema": {"anyOf": [{"items": {"$ref": "#/components/schemas/Menu"}, "type": "array"}, {"type": "null"}], "title": "Response Get Menus Api V1 Menus Get"}}}}}}, "post": {"tags": ["menu"], "summary": "Add Menu", "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/Menu"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}}, "/api/v1/menus/{menu_id}": {"get": {"tags": ["menu"], "summary": "Get Menu", "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"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "patch": {"tags": ["menu"], "summary": "Update Menu", "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"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "delete": {"tags": ["menu"], "summary": "Delete Menu", "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": "Get Submenus", "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": {"anyOf": [{"type": "array", "items": {"$ref": "#/components/schemas/SubMenuRead"}}, {"type": "null"}], "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": "Create Submenu Item", "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": "Get Submenu", "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"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "patch": {"tags": ["submenu"], "summary": "Update Submenu", "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/MenuBase"}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "delete": {"tags": ["submenu"], "summary": "Delete Submenu", "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": "Get Dishes", "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": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "post": {"tags": ["dish"], "summary": "Create Dish", "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": {}}}}, "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": "Get Dish", "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": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "patch": {"tags": ["dish"], "summary": "Update Dish", "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": {}}}}, "422": {"description": "Validation Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/HTTPValidationError"}}}}}}, "delete": {"tags": ["dish"], "summary": "Delete Dish", "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": {"DishBase": {"properties": {"title": {"type": "string", "title": "Title"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "price": {"type": "number", "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"}, "Menu": {"properties": {"title": {"type": "string", "title": "Title"}, "description": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Description"}, "id": {"type": "string", "format": "uuid", "title": "Id"}}, "type": "object", "required": ["title", "description", "id"], "title": "Menu"}, "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"}}}} +{"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"}]}