from fastapi import APIRouter, HTTPException, Query, Request from app.bars.models import Timeframe router = APIRouter(prefix="/api") @router.get("/health") def health(): return {"status": "ok", "service": "chart"} @router.get("/status") def status(request: Request): runtime = request.app.state.runtime return { "stream": runtime.stream.status, "source": runtime.stream.source.name, "symbol": runtime.stream.symbol, "last_bar_t": runtime.stream.last_bar_t, "bars_held": runtime.store.counts(), "warm": {tf.value: bool(runtime.store.get(tf)) for tf in Timeframe}, } @router.get("/bars") def bars(request: Request, tf: str = "1m", limit: int = Query(500, ge=1, le=5000)): try: timeframe = Timeframe(tf) except ValueError as exc: raise HTTPException(400, "Unknown timeframe") from exc values = request.app.state.runtime.store.get(timeframe, limit) return {"tf": timeframe.value, "bars": [bar.to_dict() for bar in values]} @router.get("/levels") def levels(request: Request, tf: str = "all"): values = request.app.state.runtime.levels if tf != "all": try: timeframe = Timeframe(tf) except ValueError as exc: raise HTTPException(400, "Unknown timeframe") from exc values = [level for level in values if level.tf is timeframe] return {"levels": [level.to_dict() for level in values]} @router.get("/confluence") def confluence(request: Request): runtime = request.app.state.runtime return { "price": runtime.price, "clusters": [cluster.to_dict() for cluster in runtime.clusters], }