mgbam commited on
Commit
448d7a9
·
verified ·
1 Parent(s): f6396c8

Create app/main.py

Browse files
Files changed (1) hide show
  1. app/main.py +62 -0
app/main.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ CryptoSentinel AI – FastAPI entry‑point
3
+ """
4
+ import os
5
+ from fastapi import FastAPI, Request, BackgroundTasks
6
+ from fastapi.responses import HTMLResponse, StreamingResponse, JSONResponse
7
+ from fastapi.staticfiles import StaticFiles
8
+ from apscheduler.schedulers.background import BackgroundScheduler
9
+ from dotenv import load_dotenv
10
+ from price_fetcher import fetch_prices, CURRENT_PRICES
11
+ from sentiment import analyze_sentiment, SentimentCache
12
+ from pathlib import Path
13
+ import json
14
+ import asyncio
15
+
16
+ load_dotenv()
17
+
18
+ app = FastAPI(title="CryptoSentinel AI")
19
+ templ_dir = Path(__file__).parent / "templates"
20
+ app.mount("/static", StaticFiles(directory=Path(__file__).parent / "static"), name="static")
21
+
22
+ scheduler = BackgroundScheduler(daemon=True)
23
+ scheduler.add_job(fetch_prices, "interval", seconds=10) # refresh price cache
24
+ scheduler.start()
25
+
26
+ @app.on_event("shutdown")
27
+ def shutdown_event():
28
+ scheduler.shutdown(wait=False)
29
+
30
+ # ---------- ROUTES -----------------------------------------------------------
31
+
32
+ @app.get("/", response_class=HTMLResponse)
33
+ async def index(request: Request):
34
+ from fastapi.templating import Jinja2Templates
35
+ templates = Jinja2Templates(directory=str(templ_dir))
36
+ return templates.TemplateResponse("index.html", {"request": request})
37
+
38
+ @app.get("/prices")
39
+ async def prices():
40
+ """JSON endpoint for latest cached prices."""
41
+ return JSONResponse(CURRENT_PRICES)
42
+
43
+ @app.post("/sentiment")
44
+ async def sentiment(request: Request, background_tasks: BackgroundTasks):
45
+ body = await request.json()
46
+ text = body.get("text", "")
47
+ # Run expensive inference in background to keep latency low
48
+ background_tasks.add_task(SentimentCache.compute, text)
49
+ return {"status": "processing"}
50
+
51
+ @app.get("/sentiment/stream")
52
+ async def sentiment_stream():
53
+ """Server‑sent events stream – pushes sentiment results."""
54
+ async def event_generator():
55
+ last_id = 0
56
+ while True:
57
+ if SentimentCache.latest_id != last_id:
58
+ last_id = SentimentCache.latest_id
59
+ data = json.dumps(SentimentCache.latest_result)
60
+ yield f"id:{last_id}\ndata:{data}\n\n"
61
+ await asyncio.sleep(1)
62
+ return StreamingResponse(event_generator(), media_type="text/event-stream")