feat: Add pagination with total count to generation listings and enable filtering assets by type.

This commit is contained in:
xds
2026-02-08 02:13:59 +03:00
parent aa50b1cc03
commit 31893414eb
14 changed files with 30 additions and 9 deletions

Binary file not shown.

View File

@@ -66,9 +66,9 @@ async def delete_asset(
@router.get("")
async def get_assets(request: Request, dao: DAO = Depends(get_dao), limit: int = 10, offset: int = 0) -> AssetsResponse:
async def get_assets(request: Request, dao: DAO = Depends(get_dao), type: Optional[str] = None, limit: int = 10, offset: int = 0) -> AssetsResponse:
logger.info(f"get_assets called. Limit: {limit}, Offset: {offset}")
assets = await dao.assets.get_assets(limit, offset)
assets = await dao.assets.get_assets(type, limit, offset)
# assets = await dao.assets.get_assets() # This line seemed redundant/conflicting in original code
total_count = await dao.assets.get_asset_count()

View File

@@ -7,7 +7,7 @@ from starlette.requests import Request
from api import service
from api.dependency import get_generation_service
from api.models.GenerationRequest import GenerationResponse, GenerationRequest, PromptResponse, PromptRequest
from api.models.GenerationRequest import GenerationResponse, GenerationRequest, GenerationsResponse, PromptResponse, PromptRequest
from api.service.generation_service import GenerationService
from models.Generation import Generation
@@ -43,7 +43,7 @@ async def prompt_from_image(
return PromptResponse(prompt=generated_prompt)
@router.get("", response_model=List[GenerationResponse])
@router.get("", response_model=GenerationsResponse)
async def get_generations(character_id: Optional[str] = None, limit: int = 10, offset: int = 0,
generation_service: GenerationService = Depends(get_generation_service)):
logger.info(f"get_generations called. CharacterId: {character_id}, Limit: {limit}, Offset: {offset}")

View File

@@ -18,6 +18,11 @@ class GenerationRequest(BaseModel):
assets_list: List[str]
class GenerationsResponse(BaseModel):
generations: List["GenerationResponse"]
total_count: int
class GenerationResponse(BaseModel):
id: str
status: GenerationStatus

View File

@@ -9,7 +9,7 @@ from aiogram import Bot
from aiogram.types import BufferedInputFile
from adapters.Exception import GoogleGenerationException
from adapters.google_adapter import GoogleAdapter
from api.models.GenerationRequest import GenerationRequest, GenerationResponse
from api.models.GenerationRequest import GenerationRequest, GenerationResponse, GenerationsResponse
# Импортируйте ваши модели DAO, Asset, Generation корректно
from models.Asset import Asset, AssetType, AssetContentType
from models.Generation import Generation, GenerationStatus
@@ -94,7 +94,10 @@ class GenerationService:
async def get_generations(self, character_id: Optional[str] = None, limit: int = 10, offset: int = 0) -> List[
Generation]:
return await self.dao.generations.get_generations(character_id = character_id,limit=limit, offset=offset)
generations = await self.dao.generations.get_generations(character_id = character_id,limit=limit, offset=offset)
total_count = await self.dao.generations.count_generations(character_id = character_id)
generations = [GenerationResponse(**gen.model_dump()) for gen in generations]
return GenerationsResponse(generations=generations, total_count=total_count)
async def get_generation(self, generation_id: str) -> Optional[GenerationResponse]:
gen = await self.dao.generations.get_generation(generation_id)

View File

@@ -51,7 +51,8 @@ ADMIN_ID = int(os.getenv("ADMIN_ID", 0))
def setup_logging():
logging.basicConfig(level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s")
format="%(asctime)s [%(levelname)s] %(name)s (%(filename)s:%(lineno)d): %(message)s",
force=True)
# --- ИНИЦИАЛИЗАЦИЯ ЗАВИСИМОСТЕЙ ---
@@ -115,6 +116,7 @@ gen_router.message.middleware(AlbumMiddleware(latency=0.8))
@asynccontextmanager
async def lifespan(app: FastAPI):
# --- STARTUP ---
setup_logging()
print("🚀 Starting up...")
# 1. Настройка DAO для FastAPI

View File

@@ -46,7 +46,10 @@ class AssetsRepo:
res = await self.collection.insert_one(asset.model_dump())
return str(res.inserted_id)
async def get_assets(self, limit: int = 10, offset: int = 0, with_data: bool = False) -> List[Asset]:
async def get_assets(self, asset_type: Optional[str] = None, limit: int = 10, offset: int = 0, with_data: bool = False) -> List[Asset]:
filter = {}
if asset_type:
filter["type"] = asset_type
args = {}
if not with_data:
args["data"] = 0
@@ -68,7 +71,7 @@ class AssetsRepo:
# So list DOES NOT return thumbnails by default.
args["thumbnail"] = 0
res = await self.collection.find({}, args).sort("created_at", -1).skip(offset).limit(limit).to_list(None)
res = await self.collection.find(filter, args).sort("created_at", -1).skip(offset).limit(limit).to_list(None)
assets = []
for doc in res:
doc["id"] = str(doc.pop("_id"))

View File

@@ -39,5 +39,13 @@ class GenerationRepo:
generations.append(Generation(**generation))
return generations
async def count_generations(self, character_id: Optional[str] = None, status: Optional[GenerationStatus] = None) -> int:
args = {}
if character_id is not None:
args["linked_character_id"] = character_id
if status is not None:
args["status"] = status
return await self.collection.count_documents(args)
async def update_generation(self, generation: Generation, ):
res = await self.collection.update_one({"_id": ObjectId(generation.id)}, {"$set": generation.model_dump()})