models + refactor
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
from typing import Annotated, List
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from fastapi.security import OAuth2PasswordBearer
|
||||
@@ -54,7 +54,7 @@ class UserResponse(BaseModel):
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
@router.get("/approvals", response_model=List[UserResponse])
|
||||
@router.get("/approvals", response_model=list[UserResponse])
|
||||
async def list_pending_users(
|
||||
admin: Annotated[dict, Depends(get_current_admin)],
|
||||
repo: Annotated[UsersRepo, Depends(get_users_repo)]
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from typing import List, Optional
|
||||
from fastapi import APIRouter, HTTPException, status, Request
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -13,18 +12,18 @@ router = APIRouter(prefix="/api/albums", tags=["Albums"])
|
||||
|
||||
class AlbumCreateRequest(BaseModel):
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
description: str | None = None
|
||||
|
||||
class AlbumUpdateRequest(BaseModel):
|
||||
name: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
name: str | None = None
|
||||
description: str | None = None
|
||||
|
||||
class AlbumResponse(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
generation_ids: List[str] = []
|
||||
cover_asset_id: Optional[str] = None # Not implemented yet
|
||||
description: str | None = None
|
||||
generation_ids: list[str] = []
|
||||
cover_asset_id: str | None = None # Not implemented yet
|
||||
|
||||
@router.post("", response_model=AlbumResponse)
|
||||
async def create_album(request: Request, album_in: AlbumCreateRequest):
|
||||
@@ -32,7 +31,7 @@ async def create_album(request: Request, album_in: AlbumCreateRequest):
|
||||
album = await service.create_album(name=album_in.name, description=album_in.description)
|
||||
return AlbumResponse(**album.model_dump())
|
||||
|
||||
@router.get("", response_model=List[AlbumResponse])
|
||||
@router.get("", response_model=list[AlbumResponse])
|
||||
async def get_albums(request: Request, limit: int = 10, offset: int = 0):
|
||||
service: AlbumService = request.app.state.album_service
|
||||
albums = await service.get_albums(limit=limit, offset=offset)
|
||||
@@ -77,7 +76,7 @@ async def remove_generation_from_album(request: Request, album_id: str, generati
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Album or Generation not found")
|
||||
return {"status": "success"}
|
||||
|
||||
@router.get("/{album_id}/generations", response_model=List[GenerationResponse])
|
||||
@router.get("/{album_id}/generations", response_model=list[GenerationResponse])
|
||||
async def get_album_generations(request: Request, album_id: str, limit: int = 10, offset: int = 0):
|
||||
service: AlbumService = request.app.state.album_service
|
||||
generations = await service.get_generations_by_album(album_id, limit=limit, offset=offset)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import List, Optional, Dict, Any
|
||||
from typing import Any
|
||||
|
||||
from aiogram.types import BufferedInputFile
|
||||
from bson import ObjectId
|
||||
@@ -135,22 +135,22 @@ async def delete_orphan_assets_from_minio(
|
||||
*,
|
||||
assets_collection: str = "assets",
|
||||
generations_collection: str = "generations",
|
||||
asset_type: Optional[str] = "generated",
|
||||
project_id: Optional[str] = None,
|
||||
asset_type: str | None = "generated",
|
||||
project_id: str | None = None,
|
||||
dry_run: bool = True,
|
||||
mark_assets_deleted: bool = False,
|
||||
batch_size: int = 500,
|
||||
) -> Dict[str, Any]:
|
||||
) -> dict[str, Any]:
|
||||
db = mongo['bot_db'] # БД уже выбрана в get_mongo_client
|
||||
assets = db[assets_collection]
|
||||
|
||||
match_assets: Dict[str, Any] = {}
|
||||
match_assets: dict[str, Any] = {}
|
||||
if asset_type is not None:
|
||||
match_assets["type"] = asset_type
|
||||
if project_id is not None:
|
||||
match_assets["project_id"] = project_id
|
||||
|
||||
pipeline: List[Dict[str, Any]] = [
|
||||
pipeline: list[dict[str, Any]] = [
|
||||
{"$match": match_assets} if match_assets else {"$match": {}},
|
||||
{
|
||||
"$lookup": {
|
||||
@@ -192,8 +192,8 @@ async def delete_orphan_assets_from_minio(
|
||||
|
||||
deleted_objects = 0
|
||||
deleted_assets = 0
|
||||
errors: List[Dict[str, Any]] = []
|
||||
orphan_asset_ids: List[ObjectId] = []
|
||||
errors: list[dict[str, Any]] = []
|
||||
orphan_asset_ids: list[ObjectId] = []
|
||||
|
||||
async for asset in cursor:
|
||||
aid = asset["_id"]
|
||||
@@ -259,7 +259,7 @@ async def delete_asset(
|
||||
|
||||
|
||||
@router.get("", dependencies=[Depends(get_current_user)])
|
||||
async def get_assets(request: Request, dao: DAO = Depends(get_dao), type: Optional[str] = None, limit: int = 10, offset: int = 0, current_user: dict = Depends(get_current_user), project_id: Optional[str] = Depends(get_project_id)) -> AssetsResponse:
|
||||
async def get_assets(request: Request, dao: DAO = Depends(get_dao), type: str | None = None, limit: int = 10, offset: int = 0, current_user: dict = Depends(get_current_user), project_id: str | None = Depends(get_project_id)) -> AssetsResponse:
|
||||
logger.info(f"get_assets called. Limit: {limit}, Offset: {offset}")
|
||||
|
||||
user_id_filter = current_user["id"]
|
||||
@@ -286,10 +286,10 @@ async def get_assets(request: Request, dao: DAO = Depends(get_dao), type: Option
|
||||
@router.post("/upload", response_model=AssetResponse, status_code=status.HTTP_201_CREATED)
|
||||
async def upload_asset(
|
||||
file: UploadFile = File(...),
|
||||
linked_char_id: Optional[str] = Form(None),
|
||||
linked_char_id: str | None = Form(None),
|
||||
dao: DAO = Depends(get_dao),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
project_id: Optional[str] = Depends(get_project_id)
|
||||
project_id: str | None = Depends(get_project_id)
|
||||
):
|
||||
logger.info(f"upload_asset called. Filename: {file.filename}, ContentType: {file.content_type}, LinkedCharId: {linked_char_id}")
|
||||
if not file.content_type:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import List, Any, Coroutine, Optional
|
||||
from typing import Any, Coroutine
|
||||
|
||||
from fastapi import APIRouter, Depends
|
||||
from pydantic import BaseModel
|
||||
@@ -23,15 +23,15 @@ from api.dependency import get_project_id
|
||||
router = APIRouter(prefix="/api/characters", tags=["Characters"], dependencies=[Depends(get_current_user)])
|
||||
|
||||
|
||||
@router.get("/", response_model=List[Character])
|
||||
@router.get("/", response_model=list[Character])
|
||||
async def get_characters(
|
||||
request: Request,
|
||||
dao: DAO = Depends(get_dao),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
project_id: Optional[str] = Depends(get_project_id),
|
||||
project_id: str | None = Depends(get_project_id),
|
||||
limit: int = 100,
|
||||
offset: int = 0
|
||||
) -> List[Character]:
|
||||
) -> list[Character]:
|
||||
logger.info(f"get_characters called. Limit: {limit}, Offset: {offset}")
|
||||
|
||||
user_id_filter = str(current_user["_id"])
|
||||
@@ -102,7 +102,7 @@ async def get_character_by_id(character_id: str, request: Request, dao: DAO = De
|
||||
@router.post("/", response_model=Character)
|
||||
async def create_character(
|
||||
char_req: CharacterCreateRequest,
|
||||
project_id: Optional[str] = Depends(get_project_id),
|
||||
project_id: str | None = Depends(get_project_id),
|
||||
dao: DAO = Depends(get_dao),
|
||||
current_user: dict = Depends(get_current_user)
|
||||
) -> Character:
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import logging
|
||||
from typing import List, Optional
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from starlette import status
|
||||
|
||||
@@ -50,7 +49,7 @@ async def create_environment(
|
||||
return created_env
|
||||
|
||||
|
||||
@router.get("/character/{character_id}", response_model=List[Environment])
|
||||
@router.get("/character/{character_id}", response_model=list[Environment])
|
||||
async def get_character_environments(
|
||||
character_id: str,
|
||||
dao: DAO = Depends(get_dao),
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import logging
|
||||
import json
|
||||
from typing import List, Optional
|
||||
|
||||
from fastapi import APIRouter, UploadFile, File, Form, Header, HTTPException
|
||||
from fastapi.params import Depends
|
||||
@@ -30,7 +29,7 @@ logger = logging.getLogger(__name__)
|
||||
router = APIRouter(prefix='/api/generations', tags=["Generation"])
|
||||
|
||||
|
||||
async def check_project_access(project_id: Optional[str], current_user: dict, dao: DAO):
|
||||
async def check_project_access(project_id: str | None, current_user: dict, dao: DAO):
|
||||
"""Helper to check if user has access to project."""
|
||||
if not project_id:
|
||||
return
|
||||
@@ -46,31 +45,36 @@ async def ask_prompt_assistant(
|
||||
current_user: dict = Depends(get_current_user)
|
||||
) -> PromptResponse:
|
||||
logger.info(f"ask_prompt_assistant: {len(prompt_request.prompt)} chars")
|
||||
generated_prompt = await generation_service.ask_prompt_assistant(prompt_request.prompt, prompt_request.linked_assets)
|
||||
generated_prompt = await generation_service.ask_prompt_assistant(
|
||||
prompt_request.prompt,
|
||||
prompt_request.linked_assets,
|
||||
prompt_request.model
|
||||
)
|
||||
return PromptResponse(prompt=generated_prompt)
|
||||
|
||||
|
||||
@router.post("/prompt-from-image", response_model=PromptResponse)
|
||||
async def prompt_from_image(
|
||||
prompt: Optional[str] = Form(None),
|
||||
images: List[UploadFile] = File(...),
|
||||
prompt: str | None = Form(None),
|
||||
model: str = Form("gemini-3.1-pro-preview"),
|
||||
images: list[UploadFile] = File(...),
|
||||
generation_service: GenerationService = Depends(get_generation_service),
|
||||
current_user: dict = Depends(get_current_user)
|
||||
) -> PromptResponse:
|
||||
images_bytes = [await img.read() for img in images]
|
||||
generated_prompt = await generation_service.generate_prompt_from_images(images_bytes, prompt)
|
||||
generated_prompt = await generation_service.generate_prompt_from_images(images_bytes, prompt, model)
|
||||
return PromptResponse(prompt=generated_prompt)
|
||||
|
||||
|
||||
@router.get("", response_model=GenerationsResponse)
|
||||
async def get_generations(
|
||||
character_id: Optional[str] = None,
|
||||
character_id: str | None = None,
|
||||
limit: int = 10,
|
||||
offset: int = 0,
|
||||
only_liked: bool = False,
|
||||
generation_service: GenerationService = Depends(get_generation_service),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
project_id: Optional[str] = Depends(get_project_id),
|
||||
project_id: str | None = Depends(get_project_id),
|
||||
dao: DAO = Depends(get_dao)
|
||||
):
|
||||
await check_project_access(project_id, current_user, dao)
|
||||
@@ -92,10 +96,10 @@ async def get_generations(
|
||||
|
||||
@router.get("/usage", response_model=FinancialReport)
|
||||
async def get_usage_report(
|
||||
breakdown: Optional[str] = None, # "user" or "project"
|
||||
breakdown: str | None = None, # "user" or "project"
|
||||
generation_service: GenerationService = Depends(get_generation_service),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
project_id: Optional[str] = Depends(get_project_id),
|
||||
project_id: str | None = Depends(get_project_id),
|
||||
dao: DAO = Depends(get_dao)
|
||||
) -> FinancialReport:
|
||||
await check_project_access(project_id, current_user, dao)
|
||||
@@ -120,7 +124,7 @@ async def post_generation(
|
||||
generation: GenerationRequest,
|
||||
generation_service: GenerationService = Depends(get_generation_service),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
project_id: Optional[str] = Depends(get_project_id),
|
||||
project_id: str | None = Depends(get_project_id),
|
||||
dao: DAO = Depends(get_dao)
|
||||
) -> GenerationGroupResponse:
|
||||
await check_project_access(project_id, current_user, dao)
|
||||
@@ -137,7 +141,7 @@ async def post_generation(
|
||||
async def get_running_generations(
|
||||
generation_service: GenerationService = Depends(get_generation_service),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
project_id: Optional[str] = Depends(get_project_id),
|
||||
project_id: str | None = Depends(get_project_id),
|
||||
dao: DAO = Depends(get_dao)
|
||||
):
|
||||
await check_project_access(project_id, current_user, dao)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from typing import List, Optional
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, Body
|
||||
from api.dependency import get_idea_service, get_project_id, get_generation_service
|
||||
from api.endpoints.auth import get_current_user
|
||||
@@ -14,7 +13,7 @@ router = APIRouter(prefix="/api/ideas", tags=["ideas"])
|
||||
@router.post("", response_model=Idea)
|
||||
async def create_idea(
|
||||
request: IdeaCreateRequest,
|
||||
project_id: Optional[str] = Depends(get_project_id),
|
||||
project_id: str | None = Depends(get_project_id),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
idea_service: IdeaService = Depends(get_idea_service)
|
||||
):
|
||||
@@ -28,9 +27,9 @@ async def create_idea(
|
||||
inspiration_id=request.inspiration_id
|
||||
)
|
||||
|
||||
@router.get("", response_model=List[IdeaResponse])
|
||||
@router.get("", response_model=list[IdeaResponse])
|
||||
async def get_ideas(
|
||||
project_id: Optional[str] = Depends(get_project_id),
|
||||
project_id: str | None = Depends(get_project_id),
|
||||
limit: int = 20,
|
||||
offset: int = 0,
|
||||
current_user: dict = Depends(get_current_user),
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from typing import List, Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from api.dependency import get_inspiration_service, get_project_id
|
||||
@@ -13,7 +12,7 @@ router = APIRouter(prefix="/api/inspirations", tags=["Inspirations"])
|
||||
@router.post("", response_model=InspirationResponse, status_code=status.HTTP_201_CREATED)
|
||||
async def create_inspiration(
|
||||
request: InspirationCreateRequest,
|
||||
project_id: Optional[str] = Depends(get_project_id),
|
||||
project_id: str | None = Depends(get_project_id),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
service: InspirationService = Depends(get_inspiration_service)
|
||||
):
|
||||
@@ -30,7 +29,7 @@ async def create_inspiration(
|
||||
|
||||
@router.get("", response_model=InspirationListResponse)
|
||||
async def get_inspirations(
|
||||
project_id: Optional[str] = Depends(get_project_id),
|
||||
project_id: str | None = Depends(get_project_id),
|
||||
limit: int = 20,
|
||||
offset: int = 0,
|
||||
current_user: dict = Depends(get_current_user),
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from typing import List, Optional
|
||||
from datetime import datetime
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
|
||||
@@ -14,7 +13,7 @@ router = APIRouter(prefix="/api/posts", tags=["posts"])
|
||||
@router.post("", response_model=Post)
|
||||
async def create_post(
|
||||
request: PostCreateRequest,
|
||||
project_id: Optional[str] = Depends(get_project_id),
|
||||
project_id: str | None = Depends(get_project_id),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
post_service: PostService = Depends(get_post_service),
|
||||
):
|
||||
@@ -28,13 +27,13 @@ async def create_post(
|
||||
)
|
||||
|
||||
|
||||
@router.get("", response_model=List[Post])
|
||||
@router.get("", response_model=list[Post])
|
||||
async def get_posts(
|
||||
project_id: Optional[str] = Depends(get_project_id),
|
||||
project_id: str | None = Depends(get_project_id),
|
||||
limit: int = 200,
|
||||
offset: int = 0,
|
||||
date_from: Optional[datetime] = None,
|
||||
date_to: Optional[datetime] = None,
|
||||
date_from: datetime | None = None,
|
||||
date_to: datetime | None = None,
|
||||
current_user: dict = Depends(get_current_user),
|
||||
post_service: PostService = Depends(get_post_service),
|
||||
):
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from typing import List, Optional
|
||||
|
||||
from bson import ObjectId
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
@@ -12,7 +11,7 @@ router = APIRouter(prefix="/api/projects", tags=["Projects"])
|
||||
|
||||
class ProjectCreate(BaseModel):
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
description: str | None = None
|
||||
|
||||
class ProjectMemberResponse(BaseModel):
|
||||
id: str
|
||||
@@ -21,9 +20,9 @@ class ProjectMemberResponse(BaseModel):
|
||||
class ProjectResponse(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
description: str | None = None
|
||||
owner_id: str
|
||||
members: List[ProjectMemberResponse]
|
||||
members: list[ProjectMemberResponse]
|
||||
is_owner: bool = False
|
||||
|
||||
async def _get_project_response(project: Project, current_user_id: str, dao: DAO) -> ProjectResponse:
|
||||
@@ -78,7 +77,7 @@ async def create_project(
|
||||
|
||||
return await _get_project_response(new_project, user_id, dao)
|
||||
|
||||
@router.get("", response_model=List[ProjectResponse])
|
||||
@router.get("", response_model=list[ProjectResponse])
|
||||
async def get_my_projects(
|
||||
dao: DAO = Depends(get_dao),
|
||||
current_user: dict = Depends(get_current_user)
|
||||
|
||||
Reference in New Issue
Block a user