79 lines
3 KiB
Python
79 lines
3 KiB
Python
from fastapi import APIRouter, Depends, HTTPException
|
||
from datetime import datetime, timezone
|
||
from typing import List
|
||
import random
|
||
|
||
from app.database import get_db
|
||
from app.models.pronunciation import PronunciationDB
|
||
from app.services.gemini_service import get_word_pronunciation
|
||
|
||
router = APIRouter(prefix="/api/pronunciation", tags=["pronunciation"])
|
||
|
||
TECH_TERMS = [
|
||
"Kubernetes", "PostgreSQL", "Nginx", "Polymorphism", "Encapsulation",
|
||
"Asynchronous", "Concurrency", "Django", "Vue", "TypeScript",
|
||
"GraphQL", "Docker", "Microservices", "Idempotent", "Heuristic",
|
||
"Tuple", "Boolean", "JSON", "YAML", "Ubuntu",
|
||
"Vite", "Pinia", "Axios", "FastAPI", "Uvicorn",
|
||
"OAuth", "JWT", "PyMuPDF", "GridFS", "MongoDB",
|
||
"Motor", "Asynchronous", "Middleware", "Interceptor", "Composition",
|
||
"Component", "Reactive", "Computed", "State", "Mutation",
|
||
"Action", "Getter", "Router", "Guard", "Plugin"
|
||
]
|
||
|
||
@router.get("/tech-terms", response_model=List[str])
|
||
async def get_tech_terms():
|
||
"""Returns a list of 50 common tech terms to prepopulate the UI."""
|
||
return TECH_TERMS
|
||
|
||
@router.get("/word-of-the-day")
|
||
async def get_word_of_the_day(db=Depends(get_db)):
|
||
"""Returns a random word from the DB, or a default one if DB is empty."""
|
||
count = await db["pronunciations"].count_documents({})
|
||
if count == 0:
|
||
return {"word": "Polymorphism", "phonetic": "/ˌpɒlɪˈmɔːfɪzəm/", "definition": "The provision of a single interface to entities of different types."}
|
||
|
||
# Pick a random document
|
||
import random
|
||
random_skip = random.randint(0, count - 1)
|
||
doc = await db["pronunciations"].find().skip(random_skip).limit(1).to_list(length=1)
|
||
|
||
if doc:
|
||
return {
|
||
"word": doc[0]["word"],
|
||
"phonetic": doc[0]["phonetic"],
|
||
"definition": doc[0]["definition"]
|
||
}
|
||
return {"word": "Polymorphism", "phonetic": "/ˌpɒlɪˈmɔːfɪzəm/", "definition": "The provision of a single interface to entities of different types."}
|
||
|
||
@router.get("/{word}", response_model=PronunciationDB)
|
||
async def get_pronunciation(word: str, db=Depends(get_db)):
|
||
"""Fetches pronunciation info from MongoDB or Gemini."""
|
||
word_lower = word.lower().strip()
|
||
|
||
# 1. Check DB Cache
|
||
existing = await db["pronunciations"].find_one({"word_lower": word_lower})
|
||
if existing:
|
||
existing["id"] = str(existing.pop("_id"))
|
||
return existing
|
||
|
||
# 2. Call Gemini
|
||
try:
|
||
data = await get_word_pronunciation(word)
|
||
except Exception as e:
|
||
raise HTTPException(status_code=500, detail=str(e))
|
||
|
||
# 3. Store in DB
|
||
now = datetime.now(timezone.utc)
|
||
doc = {
|
||
"word": data["word"],
|
||
"word_lower": word_lower,
|
||
"phonetic": data["phonetic"],
|
||
"syllables": data["syllables"],
|
||
"definition": data["definition"],
|
||
"created_at": now
|
||
}
|
||
|
||
result = await db["pronunciations"].insert_one(doc)
|
||
doc["id"] = str(result.inserted_id)
|
||
return doc
|