from typing import Annotated import asyncpg from dishka.integrations.fastapi import DishkaRoute, FromDishka from fastapi import APIRouter, File, Form, HTTPException, UploadFile, status from pydantic import BaseModel from api.saved import MAX_UPLOAD_BYTES, SavedResult, forward, send_new from utils.storage import ContentAddressedStorage router = APIRouter(prefix="/api/saved", tags=["saved"], route_class=DishkaRoute) class ForwardRequest(BaseModel): account_id: int chat_id: int message_id: int @router.post("") async def send_to_saved( pool: FromDishka[asyncpg.Pool], storage: FromDishka[ContentAddressedStorage], account_id: Annotated[int, Form()], text: Annotated[str | None, Form()] = None, voice: Annotated[bool, Form()] = False, file: Annotated[UploadFile | None, File()] = None, ) -> SavedResult: upload = None if file is not None: if file.size is not None and file.size > MAX_UPLOAD_BYTES: raise HTTPException(status.HTTP_413_CONTENT_TOO_LARGE, "file too large") data = await file.read() upload = (data, file.filename or "file", file.content_type) if upload is None and not text: raise HTTPException(status.HTTP_400_BAD_REQUEST, "text or file is required") return await send_new(pool, storage, account_id, text, upload, voice=voice) @router.post("/forward") async def forward_to_saved( pool: FromDishka[asyncpg.Pool], body: ForwardRequest ) -> SavedResult: return await forward(pool, body.account_id, body.chat_id, body.message_id)