spb/uqo-research-db
Public
1# ============================================================2# SPID — optional FastAPI service3#4# uvicorn spid.api:app --reload --port 80885#6# Read-only HTTP layer over the project DB: structured search,7# semantic search, project detail, analytics.8# ============================================================9from __future__ import annotations1011try:12 from fastapi import FastAPI, Query13except ImportError as e: # pragma: no cover14 raise SystemExit("FastAPI not installed. `pip install fastapi uvicorn`.") from e1516from spid import analytics17from spid.embed import semantic_search18from spid.search import get_project, search_projects19from spid.store import Store2021app = FastAPI(title="SPID — SEC Project Intelligence", version="0.1.0")222324def _store() -> Store:25 return Store(read_only=True)262728@app.get("/health")29def health():30 s = _store()31 try:32 return {"status": "ok", "projects": s.count("projects"),33 "mentions": s.count("project_mentions")}34 finally:35 s.close()363738@app.get("/projects")39def projects(q: str | None = None, type: str | None = None, sector: str | None = None,40 tech: str | None = None, location: str | None = None, ticker: str | None = None,41 min_amount: float | None = None, status: str | None = None,42 year_from: int | None = None, year_to: int | None = None,43 limit: int = Query(25, le=200)):44 s = _store()45 try:46 return search_projects(s, keyword=q, project_type=type, sector=sector, technology=tech,47 location=location, ticker=ticker, min_amount=min_amount,48 status=status, year_from=year_from, year_to=year_to, limit=limit)49 finally:50 s.close()515253@app.get("/projects/{project_id}")54def project_detail(project_id: str):55 s = _store()56 try:57 return get_project(s, project_id) or {"error": "not found"}58 finally:59 s.close()606162@app.get("/semantic")63def semantic(q: str, limit: int = Query(10, le=100)):64 s = _store()65 try:66 return semantic_search(s, q, k=limit)67 finally:68 s.close()697071@app.get("/analytics")72def analytics_report():73 s = _store()74 try:75 return analytics.full_report(s)76 finally:77 s.close()78