feat: add web dashboard and metadata enrichment daemon
All checks were successful
Deployment / deploy-docker (push) Successful in 4s
All checks were successful
Deployment / deploy-docker (push) Successful in 4s
This commit is contained in:
78
dashboard/server.py
Normal file
78
dashboard/server.py
Normal file
@@ -0,0 +1,78 @@
|
||||
from fastapi import FastAPI, HTTPException, Depends
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.responses import FileResponse
|
||||
import requests
|
||||
import os
|
||||
import pandas as pd
|
||||
|
||||
app = FastAPI(title="Trading Dashboard API")
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"],
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
# Serve static files
|
||||
app.mount("/static", StaticFiles(directory="dashboard/public"), name="static")
|
||||
|
||||
@app.get("/")
|
||||
async def read_index():
|
||||
return FileResponse('dashboard/public/index.html')
|
||||
|
||||
DB_USER = os.getenv("DB_USER", "admin")
|
||||
DB_PASSWORD = os.getenv("DB_PASSWORD", "quest")
|
||||
DB_AUTH = (DB_USER, DB_PASSWORD) if DB_USER and DB_PASSWORD else None
|
||||
DB_HOST = os.getenv("DB_HOST", "questdb")
|
||||
|
||||
@app.get("/api/trades")
|
||||
async def get_trades(isin: str = None, days: int = 7):
|
||||
query = f"select * from trades where timestamp > dateadd('d', -{days}, now())"
|
||||
if isin:
|
||||
query += f" and isin = '{isin}'"
|
||||
query += " order by timestamp asc"
|
||||
|
||||
try:
|
||||
response = requests.get(f"http://{DB_HOST}:9000/exec", params={'query': query}, auth=DB_AUTH)
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
throw_http_error(response)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@app.get("/api/metadata")
|
||||
async def get_metadata():
|
||||
query = "select * from metadata"
|
||||
try:
|
||||
response = requests.get(f"http://{DB_HOST}:9000/exec", params={'query': query}, auth=DB_AUTH)
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
throw_http_error(response)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@app.get("/api/summary")
|
||||
async def get_summary():
|
||||
# Group by continent/country if metadata exists
|
||||
query = """
|
||||
select m.continent, m.country, count(*) as trade_count, sum(t.price * t.quantity) as total_volume
|
||||
from trades t
|
||||
join metadata m on t.isin = m.isin
|
||||
group by m.continent, m.country
|
||||
"""
|
||||
try:
|
||||
response = requests.get(f"http://{DB_HOST}:9000/exec", params={'query': query}, auth=DB_AUTH)
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
throw_http_error(response)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
def throw_http_error(res):
|
||||
raise HTTPException(status_code=res.status_code, detail=f"QuestDB error: {res.text}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||
Reference in New Issue
Block a user