upd: Добавил роут summary с выводом вмего меню со вложением
parent
3120910552
commit
ebe75b6dc3
Binary file not shown.
|
@ -5,6 +5,7 @@ from fastapi import FastAPI
|
||||||
from fastfood.routers.dish import router as dish_router
|
from fastfood.routers.dish import router as dish_router
|
||||||
from fastfood.routers.menu import router as menu_router
|
from fastfood.routers.menu import router as menu_router
|
||||||
from fastfood.routers.submenu import router as submenu_router
|
from fastfood.routers.submenu import router as submenu_router
|
||||||
|
from fastfood.routers.summary import router as summary_router
|
||||||
|
|
||||||
|
|
||||||
def create_app() -> FastAPI:
|
def create_app() -> FastAPI:
|
||||||
|
@ -15,6 +16,7 @@ def create_app() -> FastAPI:
|
||||||
app.include_router(menu_router)
|
app.include_router(menu_router)
|
||||||
app.include_router(submenu_router)
|
app.include_router(submenu_router)
|
||||||
app.include_router(dish_router)
|
app.include_router(dish_router)
|
||||||
|
app.include_router(summary_router)
|
||||||
|
|
||||||
def custom_openapi():
|
def custom_openapi():
|
||||||
with open('openapi.json') as openapi:
|
with open('openapi.json') as openapi:
|
||||||
|
|
|
@ -63,3 +63,4 @@ class RedisRepository:
|
||||||
async def invalidate(self, key: str, bg_task: BackgroundTasks) -> None:
|
async def invalidate(self, key: str, bg_task: BackgroundTasks) -> None:
|
||||||
await self.clear_cache(f'{key}*', bg_task)
|
await self.clear_cache(f'{key}*', bg_task)
|
||||||
await self.clear_cache(f'{get_key("menus")}*', bg_task)
|
await self.clear_cache(f'{get_key("menus")}*', bg_task)
|
||||||
|
await self.clear_cache('summary', bg_task)
|
||||||
|
|
|
@ -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()]
|
|
@ -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()
|
|
@ -34,3 +34,11 @@ class Dish(DishBase, Menu):
|
||||||
|
|
||||||
class Dish_db(MenuBase):
|
class Dish_db(MenuBase):
|
||||||
price: float
|
price: float
|
||||||
|
|
||||||
|
|
||||||
|
class SubMenuSummary(Menu):
|
||||||
|
dishes: list[Dish_db]
|
||||||
|
|
||||||
|
|
||||||
|
class MenuSummary(Menu):
|
||||||
|
submenus: list[SubMenuSummary]
|
||||||
|
|
|
@ -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
|
1204
openapi.json
1204
openapi.json
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue