veriscite / app /api /main.py
minoola's picture
Upload main.py
15f7bcc verified
Raw
History Blame Contribute Delete
2.21 kB
from dotenv import load_dotenv
load_dotenv() # no-op if .env doesn't exist (e.g. on HF Spaces, where env vars are set directly)
import json
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse
from pydantic import BaseModel
from app.graph.build import build_graph
app = FastAPI(title="VeriScite", version="0.1.0")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # tighten to your Vercel domain before deploying
allow_methods=["*"],
allow_headers=["*"],
)
graph = build_graph()
class AuditRequest(BaseModel):
text: str # pasted paper/abstract text
@app.get("/health")
async def health():
return {"status": "ok"}
@app.post("/audit")
async def audit(req: AuditRequest):
initial_state = {
"source_text": req.text,
"claims": [],
"audits": [],
"current_index": 0,
"report": None,
}
final_state = await graph.ainvoke(initial_state)
return final_state["report"]
@app.post("/audit/stream")
async def audit_stream(req: AuditRequest):
"""Server-Sent Events version of /audit — emits a live event after each
graph node (and after each individual tool call inside the escalate
agent loop) completes, rather than only returning at the very end.
Powers the frontend's live agent-workflow visualization.
Event shapes:
{"type": "progress", ...node-specific fields, see nodes.py _writer() calls}
{"type": "final", "report": {...}} -- sent once, at the end
"""
initial_state = {
"source_text": req.text,
"claims": [],
"audits": [],
"current_index": 0,
"report": None,
}
async def event_generator():
async for mode, chunk in graph.astream(initial_state, stream_mode=["custom", "values"]):
if mode == "custom":
yield f"data: {json.dumps({'type': 'progress', **chunk})}\n\n"
elif mode == "values" and chunk.get("report") is not None:
yield f"data: {json.dumps({'type': 'final', 'report': chunk['report']})}\n\n"
return StreamingResponse(event_generator(), media_type="text/event-stream")