filter products

This commit is contained in:
Piotr Domański 2023-04-01 20:13:11 +02:00
parent 03d1bcb40b
commit 71ef6cd954
5 changed files with 32 additions and 7 deletions

View file

@ -1,6 +1,17 @@
from fastapi import FastAPI from fastapi import FastAPI
from .router import router from .router import router
from .settings import Settings
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI(title="Fooder") app = FastAPI(title="Fooder")
app.include_router(router) app.include_router(router)
app.add_middleware(
CORSMiddleware,
allow_origins=Settings().ALLOWED_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)

View file

@ -1,4 +1,4 @@
from typing import AsyncIterator from typing import AsyncIterator, Optional
from fastapi import HTTPException from fastapi import HTTPException
@ -24,9 +24,11 @@ class CreateProduct(AuthorizedController):
class ListProduct(AuthorizedController): class ListProduct(AuthorizedController):
async def call(self, limit: int, offset: int) -> AsyncIterator[Product]: async def call(
self, limit: int, offset: int, q: Optional[str]
) -> AsyncIterator[Product]:
async with self.async_session() as session: async with self.async_session() as session:
async for product in DBProduct.list_all( async for product in DBProduct.list_all(
session, limit=limit, offset=offset session, limit=limit, offset=offset, q=q
): ):
yield Product.from_orm(product) yield Product.from_orm(product)

View file

@ -1,7 +1,7 @@
from sqlalchemy.orm import Mapped from sqlalchemy.orm import Mapped
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from typing import AsyncIterator from typing import AsyncIterator, Optional
from .base import Base, CommonMixin from .base import Base, CommonMixin
@ -24,8 +24,15 @@ class Product(Base, CommonMixin):
return self.protein * 4 + self.carb * 4 + self.fat * 9 return self.protein * 4 + self.carb * 4 + self.fat * 9
@classmethod @classmethod
async def list_all(cls, session: AsyncSession, offset: int, limit: int): async def list_all(
query = select(cls).offset(offset).limit(limit) cls, session: AsyncSession, offset: int, limit: int, q: Optional[str] = None
) -> AsyncIterator["Product"]:
query = select(cls)
if q:
query = query.filter(cls.name.ilike(f"%{q.lower()}%"))
query = query.offset(offset).limit(limit)
stream = await session.stream_scalars(query.order_by(cls.id)) stream = await session.stream_scalars(query.order_by(cls.id))
async for row in stream: async for row in stream:
yield row yield row

View file

@ -1,4 +1,5 @@
from pydantic import BaseSettings from pydantic import BaseSettings
from typing import List
class Settings(BaseSettings): class Settings(BaseSettings):
@ -10,3 +11,5 @@ class Settings(BaseSettings):
SECRET_KEY: str SECRET_KEY: str
ALGORITHM: str = "HS256" ALGORITHM: str = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES: int = 30 ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
ALLOWED_ORIGINS: List[str] = ["*"]

View file

@ -1,6 +1,7 @@
from fastapi import APIRouter, Depends, Request from fastapi import APIRouter, Depends, Request
from ..model.product import Product, CreateProductPayload, ListProductPayload from ..model.product import Product, CreateProductPayload, ListProductPayload
from ..controller.product import ListProduct, CreateProduct from ..controller.product import ListProduct, CreateProduct
from typing import Optional
router = APIRouter(tags=["product"]) router = APIRouter(tags=["product"])
@ -12,9 +13,10 @@ async def list_product(
controller: ListProduct = Depends(ListProduct), controller: ListProduct = Depends(ListProduct),
limit: int = 10, limit: int = 10,
offset: int = 0, offset: int = 0,
q: Optional[str] = None,
): ):
return ListProductPayload( return ListProductPayload(
products=[p async for p in controller.call(limit=limit, offset=offset)] products=[p async for p in controller.call(limit=limit, offset=offset, q=q)]
) )