Ritabanm commited on
Commit
32fb143
·
verified ·
1 Parent(s): 94b06be

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -16
app.py CHANGED
@@ -1,23 +1,31 @@
1
  from fastapi import FastAPI, HTTPException
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from pydantic import BaseModel
 
 
 
4
 
5
  from agent.graph import AgentGraph
6
  from agent.tools import FetchTools
7
  from ingest.sec import fetch_recent_filings_by_cik
8
  from settings import INDEX_DIR
9
 
 
 
10
  app = FastAPI(title="DeepDive IR Agent")
11
 
12
- # CORS so the Next.js frontend can call this later
13
  app.add_middleware(
14
  CORSMiddleware,
15
- allow_origins=["*"], # DEV: allow all
16
  allow_credentials=True,
17
  allow_methods=["*"],
18
  allow_headers=["*"],
19
  )
20
 
 
 
 
21
  graph = AgentGraph(index_dir=INDEX_DIR)
22
  tools = FetchTools()
23
 
@@ -32,25 +40,60 @@ class AskRequest(BaseModel):
32
  def root():
33
  return {"ok": True, "msg": "DeepDive IR Agent API"}
34
 
 
 
 
 
35
  @app.post("/ingest")
36
  async def ingest(req: IngestRequest):
37
- filings = await fetch_recent_filings_by_cik(req.cik)
38
- docs = []
39
- for form, url, title in filings:
40
- text = await tools.get_text_from_url(url)
41
- docs.append({"title": title, "url": url, "text": text})
42
- if req.ir_url:
43
- ir_text = await tools.get_text_from_url(req.ir_url)
44
- docs.append({"title": "IR site", "url": req.ir_url, "text": ir_text})
45
- if not docs:
46
- raise HTTPException(400, "No documents fetched.")
47
- graph.build_index(docs)
48
- return {"ok": True, "num_docs": len(docs)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  @app.post("/ask")
51
  def ask(req: AskRequest):
52
- return graph.answer(req.question)
 
 
 
 
53
 
54
  @app.get("/brief")
55
  def brief():
56
- return graph.brief()
 
 
 
 
 
1
  from fastapi import FastAPI, HTTPException
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from pydantic import BaseModel
4
+ from pathlib import Path
5
+ import logging
6
+ import traceback
7
 
8
  from agent.graph import AgentGraph
9
  from agent.tools import FetchTools
10
  from ingest.sec import fetch_recent_filings_by_cik
11
  from settings import INDEX_DIR
12
 
13
+ log = logging.getLogger("uvicorn.error")
14
+
15
  app = FastAPI(title="DeepDive IR Agent")
16
 
17
+ # CORS tighten later once your Vercel URL is final
18
  app.add_middleware(
19
  CORSMiddleware,
20
+ allow_origins=["*"], # for debugging; later: ["https://<your-vercel>.vercel.app", "http://localhost:3000"]
21
  allow_credentials=True,
22
  allow_methods=["*"],
23
  allow_headers=["*"],
24
  )
25
 
26
+ # Ensure index path exists (and is persistent on HF: set INDEX_DIR="/data/index" in settings)
27
+ Path(INDEX_DIR).mkdir(parents=True, exist_ok=True)
28
+
29
  graph = AgentGraph(index_dir=INDEX_DIR)
30
  tools = FetchTools()
31
 
 
40
  def root():
41
  return {"ok": True, "msg": "DeepDive IR Agent API"}
42
 
43
+ @app.get("/healthz")
44
+ def healthz():
45
+ return {"ok": True}
46
+
47
  @app.post("/ingest")
48
  async def ingest(req: IngestRequest):
49
+ try:
50
+ # SEC wants a *10-digit, zero-padded* CIK string. Keep as string to preserve leading zeros.
51
+ cik = req.cik.strip()
52
+ if not cik.isdigit():
53
+ raise HTTPException(status_code=400, detail="CIK must be digits only.")
54
+ if len(cik) > 10:
55
+ raise HTTPException(status_code=400, detail="CIK too long; use 10 digits.")
56
+ cik = cik.zfill(10)
57
+
58
+ filings = await fetch_recent_filings_by_cik(cik) # must send a real User-Agent inside!
59
+ docs = []
60
+ for form, url, title in filings:
61
+ text = await tools.get_text_from_url(url) # must send a real User-Agent inside!
62
+ if not text:
63
+ log.warning(f"Empty text for {url}")
64
+ continue
65
+ docs.append({"title": title, "url": url, "text": text})
66
+
67
+ if req.ir_url:
68
+ ir_text = await tools.get_text_from_url(req.ir_url)
69
+ if ir_text:
70
+ docs.append({"title": "IR site", "url": req.ir_url, "text": ir_text})
71
+
72
+ if not docs:
73
+ raise HTTPException(status_code=400, detail="No documents fetched.")
74
+
75
+ graph.build_index(docs)
76
+ return {"ok": True, "num_docs": len(docs)}
77
+
78
+ except HTTPException:
79
+ raise
80
+ except Exception as e:
81
+ # Log full traceback for debugging in HF "Logs"
82
+ log.error("Ingest failed: %s\n%s", e, traceback.format_exc())
83
+ raise HTTPException(status_code=502, detail=f"Ingest failed: {type(e).__name__}: {e}")
84
 
85
  @app.post("/ask")
86
  def ask(req: AskRequest):
87
+ try:
88
+ return graph.answer(req.question)
89
+ except Exception as e:
90
+ log.error("Ask failed: %s\n%s", e, traceback.format_exc())
91
+ raise HTTPException(status_code=500, detail=str(e))
92
 
93
  @app.get("/brief")
94
  def brief():
95
+ try:
96
+ return graph.brief()
97
+ except Exception as e:
98
+ log.error("Brief failed: %s\n%s", e, traceback.format_exc())
99
+ raise HTTPException(status_code=500, detail=str(e))