Files
beavergram/backend/src/api/routers/chats.py
T

114 lines
3.2 KiB
Python

from typing import Annotated
import asyncpg
from dishka.integrations.fastapi import DishkaRoute, FromDishka
from fastapi import APIRouter, Query
from pydantic import BaseModel
from utils.jobs import enqueue
from utils.policy import repository
from utils.read import chats
from utils.read.models import (
DEFAULT_LIMIT,
ChatListItem,
MessageVersionView,
MessageView,
Page,
PinnedView,
)
from utils.read.pinned import get_pinned
router = APIRouter(prefix="/api", tags=["chats"], route_class=DishkaRoute)
class EnrichRequest(BaseModel):
account_id: int
AccountId = Annotated[int, Query()]
Limit = Annotated[int, Query()]
Offset = Annotated[int, Query()]
@router.get("/chats")
async def list_chats(
pool: FromDishka[asyncpg.Pool],
account_id: AccountId,
limit: Limit = DEFAULT_LIMIT,
offset: Offset = 0,
folder_id: Annotated[int | None, Query()] = None,
search: Annotated[str | None, Query()] = None,
) -> list[ChatListItem]:
folder = (
await repository.get_folder(pool, account_id, folder_id)
if folder_id is not None
else None
)
return await chats.list_chats(
pool, account_id, Page(limit=limit, offset=offset), folder=folder, search=search
)
@router.get("/chats/{chat_id}")
async def get_chat(
pool: FromDishka[asyncpg.Pool], chat_id: int, account_id: AccountId
) -> ChatListItem | None:
return await chats.get_chat(pool, account_id, chat_id)
@router.get("/chats/{chat_id}/messages")
async def chat_history(
pool: FromDishka[asyncpg.Pool],
chat_id: int,
account_id: AccountId,
limit: Limit = DEFAULT_LIMIT,
offset: Offset = 0,
include_deleted: Annotated[bool, Query()] = True,
before_id: Annotated[int | None, Query()] = None,
after_id: Annotated[int | None, Query()] = None,
) -> list[MessageView]:
return await chats.get_chat_history(
pool,
account_id,
chat_id,
Page(limit=limit, offset=offset),
include_deleted=include_deleted,
before_id=before_id,
after_id=after_id,
)
@router.get("/chats/{chat_id}/pinned")
async def chat_pinned(
pool: FromDishka[asyncpg.Pool], chat_id: int, account_id: AccountId
) -> PinnedView | None:
return await get_pinned(pool, account_id, chat_id)
@router.post("/chats/{chat_id}/enrich")
async def enrich_chat(
pool: FromDishka[asyncpg.Pool], chat_id: int, body: EnrichRequest
) -> dict[str, int]:
job_id = await enqueue(pool, body.account_id, "enrich_chat", {"chat_id": chat_id})
return {"job_id": job_id}
@router.get("/chats/{chat_id}/messages/{message_id}/versions")
async def message_versions(
pool: FromDishka[asyncpg.Pool], chat_id: int, message_id: int, account_id: AccountId
) -> list[MessageVersionView]:
return await chats.get_message_versions(pool, account_id, chat_id, message_id)
@router.get("/deleted")
async def deleted_messages(
pool: FromDishka[asyncpg.Pool],
account_id: AccountId,
chat_id: Annotated[int | None, Query()] = None,
limit: Limit = DEFAULT_LIMIT,
offset: Offset = 0,
) -> list[MessageView]:
return await chats.get_deleted_messages(
pool, account_id, Page(limit=limit, offset=offset), chat_id=chat_id
)