chatty / app /api /endpoints /words.py
GitHub Action
Deploy to Hugging Face Space
3470cf9
Raw
History Blame Contribute Delete
2.42 kB
from __future__ import annotations
import asyncio
import logging
from fastapi import APIRouter, Depends
from app.api.auth import get_current_user_id
from app.api.schemas import WordCreate, WordResponse
from app.db.session import get_session_factory
from app.pipelines.define import define_word
from app.services.dictionary import delete_word, list_words, save_word
from app.services.user import get_or_create_user
router = APIRouter(prefix="/words", tags=["dictionary"])
log = logging.getLogger(__name__)
async def _fill_meaning(user_id: int, word: str, level: str, lang: str = "ru") -> None:
"""Generate and store a definition for a word saved without one (background)."""
meaning = await define_word(word, level, lang)
if not meaning:
return
factory = get_session_factory()
async with factory() as s:
await save_word(s, user_id, word, meaning)
log.info("auto-defined word %r for user %s", word, user_id)
@router.get("", response_model=list[WordResponse])
async def get_words(user_id: int = Depends(get_current_user_id)) -> list[WordResponse]:
"""List saved words."""
factory = get_session_factory()
async with factory() as s:
words = await list_words(s, user_id)
return [WordResponse(word=w.word, meaning=w.meaning, created_at=w.created_at) for w in words]
@router.post("", response_model=dict[str, str])
async def add_word(
body: WordCreate,
user_id: int = Depends(get_current_user_id),
) -> dict[str, str]:
"""Save a word. If no meaning is given, save instantly and fill a definition in the background."""
word = body.word.lower().strip()
context = body.context.strip() if body.context else None
meaning = body.meaning.strip() if body.meaning else None
factory = get_session_factory()
async with factory() as s:
user = await get_or_create_user(s, user_id)
await save_word(s, user_id, word, meaning or "", context)
if not meaning:
asyncio.create_task(_fill_meaning(user_id, word, user.level, user.interface_language))
return {"status": "saved"}
@router.delete("/{word}")
async def remove_word(
word: str,
user_id: int = Depends(get_current_user_id),
) -> dict[str, bool]:
"""Delete a word from dictionary."""
factory = get_session_factory()
async with factory() as s:
deleted = await delete_word(s, user_id, word)
return {"deleted": deleted}