Files
ai-char-bot/api/endpoints/assets.py
2026-02-03 23:16:18 +03:00

93 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from typing import List, Optional
from aiogram.types import BufferedInputFile
from fastapi import APIRouter, UploadFile, File, Form
from fastapi.openapi.models import MediaType
from starlette.exceptions import HTTPException
from starlette.requests import Request
from starlette.responses import Response, JSONResponse
from models.Asset import Asset, AssetType
from repos.dao import DAO
router = APIRouter(prefix="/api/assets", tags=["Assets"])
@router.get("/{asset_id}")
async def get_asset(asset_id: str, request: Request) -> Response:
dao = request.app.state.dao
asset = await dao.assets.get_asset(asset_id)
# 2. Проверка на существование
if not asset:
raise HTTPException(status_code=404, detail="Asset not found")
headers = {
# Кэшировать на 1 год (31536000 сек)
"Cache-Control": "public, max-age=31536000, immutable"
}
return Response(content=asset.data, media_type="image/png", headers=headers)
@router.get("")
async def get_assets(request: Request) -> List[Asset]:
dao: DAO = request.app.state.dao
assets = await dao.assets.get_assets()
return assets
@router.post("/upload", response_model=Asset)
async def upload_asset(
request: Request,
# Файл обязателен
file: UploadFile = File(...),
# Остальные поля принимаем как Form-data (не JSON!)
name: str = Form(...),
type: AssetType = Form(...),
linked_char_id: Optional[str] = Form(None)
):
"""
Загружает файл, отправляет его в ТГ (для получения ID) и сохраняет в БД.
"""
# 1. Читаем байты файла
file_content = await file.read()
if not file_content:
raise HTTPException(status_code=400, detail="File is empty")
# 2. Получаем необходимые зависимости из state
bot = request.app.state.bot # Бот нужен, чтобы получить tg_file_id
admin_id = request.app.state.admin_id # Куда отправлять файл "на хранение"
dao = request.app.state.assets_dao
# 3. Отправляем файл в Telegram, чтобы получить tg_doc_file_id
# (Это обязательно, так как ваша модель требует этот ID)
try:
tg_msg = await bot.send_document(
chat_id=admin_id,
document=BufferedInputFile(file_content, filename=file.filename),
caption=f"📥 Uploaded via API: {name}"
)
# Получаем ID документа из ответа ТГ
tg_doc_id = tg_msg.document.file_id
# Если это картинка, можно попытаться достать и photo_id (для превью)
# Но send_document обычно возвращает именно документ.
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to upload to Telegram: {e}")
# 4. Создаем объект Asset
# Pydantic сам подставит created_at и вычислит link
new_asset = Asset(
name=name,
type=type,
linked_char_id=linked_char_id,
data=file_content, # Сохраняем байты в БД
tg_doc_file_id=tg_doc_id # ID из телеграма
)
# 5. Сохраняем через DAO
saved_asset = await dao.save_asset(new_asset)
return saved_asset