from __future__ import annotations import os from typing import Any, Dict, Optional from fastapi import FastAPI from pydantic import BaseModel, Field from tg_resume_db.db import connect, init_db from tg_resume_db.agent import agent_search from tg_resume_db.search import search as db_search DB_PATH = os.environ.get("CANDIDATES_DB", "./candidates.db") app = FastAPI(title="Resume Search API", version="1.0") class SearchRequest(BaseModel): query: str = Field(default="") limit: int = Field(default=20, ge=1, le=100) offset: int = Field(default=0, ge=0) remote: Optional[bool] = None location: Optional[str] = None experience_min: Optional[float] = None salary_min: Optional[int] = None salary_max: Optional[int] = None english: Optional[str] = None role: Optional[str] = None skill: Optional[str] = None class AISearchRequest(BaseModel): prompt: str = Field(default="") limit: int = Field(default=20, ge=1, le=100) ai_iters: int = Field(default=2, ge=0, le=5) @app.on_event("startup") def _startup(): con = connect(DB_PATH) init_db(con) con.close() @app.get("/health") def health(): return {"ok": True} @app.post("/search") def search(req: SearchRequest) -> Dict[str, Any]: con = connect(DB_PATH) try: items = db_search(con, query=req.query, filters=req.model_dump(), limit=req.limit, offset=req.offset) return {"items": items, "count": len(items)} finally: con.close() @app.post("/search/ai") def search_ai(req: AISearchRequest) -> Dict[str, Any]: con = connect(DB_PATH) try: res = agent_search( con, user_prompt=req.prompt, max_iters=req.ai_iters, limit=req.limit, ) return { "ai": True, "llm_used": res.get("llm_used", False), "plan": res.get("plan"), "history": res.get("history"), "postfilter": res.get("postfilter"), "items": res.get("items", []), "count": int(res.get("count", 0)), } finally: con.close()