filter products
This commit is contained in:
		
							parent
							
								
									03d1bcb40b
								
							
						
					
					
						commit
						71ef6cd954
					
				
					 5 changed files with 32 additions and 7 deletions
				
			
		| 
						 | 
					@ -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=["*"],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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] = ["*"]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)]
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue