webui fixes
This commit is contained in:
@ -4,7 +4,7 @@ REST API server for COBY system.
|
||||
|
||||
from fastapi import FastAPI, HTTPException, Request, Query, Path, WebSocket, WebSocketDisconnect
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.responses import JSONResponse, HTMLResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from typing import Optional, List
|
||||
import asyncio
|
||||
@ -77,8 +77,6 @@ def create_app(config_obj=None) -> FastAPI:
|
||||
redoc_url="/redoc"
|
||||
)
|
||||
|
||||
# We'll mount static files AFTER defining all API routes to avoid conflicts
|
||||
|
||||
# Add CORS middleware
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
@ -98,58 +96,94 @@ def create_app(config_obj=None) -> FastAPI:
|
||||
|
||||
@app.websocket("/ws/dashboard")
|
||||
async def websocket_endpoint(websocket: WebSocket):
|
||||
"""WebSocket endpoint for dashboard real-time updates"""
|
||||
"""WebSocket endpoint for real-time dashboard updates"""
|
||||
await connection_manager.connect(websocket)
|
||||
try:
|
||||
while True:
|
||||
# Send periodic updates
|
||||
await asyncio.sleep(5) # Update every 5 seconds
|
||||
|
||||
# Gather system status
|
||||
system_data = {
|
||||
# Send periodic status updates
|
||||
status_data = {
|
||||
"type": "status",
|
||||
"timestamp": time.time(),
|
||||
"performance": {
|
||||
"cpu_usage": 25.5, # Stub data
|
||||
"memory_usage": 45.2,
|
||||
"throughput": 1250,
|
||||
"avg_latency": 12.3
|
||||
},
|
||||
"exchanges": {
|
||||
"binance": "connected",
|
||||
"coinbase": "connected",
|
||||
"kraken": "disconnected",
|
||||
"bybit": "connected"
|
||||
},
|
||||
"processing": {
|
||||
"active": True,
|
||||
"total_processed": 15420
|
||||
}
|
||||
"connections": len(connection_manager.active_connections),
|
||||
"system": "healthy"
|
||||
}
|
||||
|
||||
await connection_manager.send_personal_message(
|
||||
json.dumps(system_data),
|
||||
websocket
|
||||
json.dumps(status_data), websocket
|
||||
)
|
||||
|
||||
await asyncio.sleep(30) # Send update every 30 seconds
|
||||
except WebSocketDisconnect:
|
||||
connection_manager.disconnect(websocket)
|
||||
except Exception as e:
|
||||
logger.error(f"WebSocket error: {e}")
|
||||
connection_manager.disconnect(websocket)
|
||||
|
||||
|
||||
@app.get("/api/health")
|
||||
async def api_health_check():
|
||||
"""API Health check endpoint for dashboard"""
|
||||
try:
|
||||
# Check Redis connection
|
||||
redis_healthy = await redis_manager.ping()
|
||||
|
||||
health_data = {
|
||||
'status': 'healthy' if redis_healthy else 'degraded',
|
||||
'redis': 'connected' if redis_healthy else 'disconnected',
|
||||
'version': '1.0.0',
|
||||
'timestamp': time.time()
|
||||
}
|
||||
|
||||
return response_formatter.status_response(health_data)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Health check failed: {e}")
|
||||
return JSONResponse(
|
||||
status_code=503,
|
||||
content=response_formatter.error("Service unavailable", "HEALTH_CHECK_FAILED")
|
||||
)
|
||||
|
||||
@app.get("/health")
|
||||
async def health_check():
|
||||
"""Health check endpoint"""
|
||||
return response_formatter.health(healthy=True, components={
|
||||
"api": {"healthy": True},
|
||||
"cache": {"healthy": redis_manager.is_connected()},
|
||||
"database": {"healthy": True} # Stub
|
||||
})
|
||||
try:
|
||||
# Check Redis connection
|
||||
redis_healthy = await redis_manager.ping()
|
||||
|
||||
health_data = {
|
||||
'status': 'healthy' if redis_healthy else 'degraded',
|
||||
'redis': 'connected' if redis_healthy else 'disconnected',
|
||||
'version': '1.0.0'
|
||||
}
|
||||
|
||||
return response_formatter.status_response(health_data)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Health check failed: {e}")
|
||||
return JSONResponse(
|
||||
status_code=503,
|
||||
content=response_formatter.error("Service unavailable", "HEALTH_CHECK_FAILED")
|
||||
)
|
||||
|
||||
@app.get("/")
|
||||
@app.get("/", response_class=HTMLResponse)
|
||||
async def root():
|
||||
"""Root endpoint - serve dashboard"""
|
||||
return {"message": "COBY Multi-Exchange Data Aggregation System", "status": "running"}
|
||||
"""Root endpoint - serve dashboard HTML"""
|
||||
static_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "web", "static")
|
||||
index_path = os.path.join(static_path, "index.html")
|
||||
|
||||
if os.path.exists(index_path):
|
||||
with open(index_path, 'r', encoding='utf-8') as f:
|
||||
return HTMLResponse(content=f.read())
|
||||
else:
|
||||
# Fallback if index.html doesn't exist
|
||||
return HTMLResponse(content="""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title>COBY System</title></head>
|
||||
<body>
|
||||
<h1>COBY Multi-Exchange Data Aggregation System</h1>
|
||||
<p>System is running. Dashboard files not found.</p>
|
||||
<p><a href="/api/health">Health Check</a></p>
|
||||
</body>
|
||||
</html>
|
||||
""")
|
||||
|
||||
@app.middleware("http")
|
||||
async def rate_limit_middleware(request: Request, call_next):
|
||||
@ -203,53 +237,6 @@ def create_app(config_obj=None) -> FastAPI:
|
||||
except Exception as e:
|
||||
logger.error(f"API server shutdown error: {e}")
|
||||
|
||||
# API Health check endpoint (for dashboard)
|
||||
@app.get("/api/health")
|
||||
async def api_health_check():
|
||||
"""API Health check endpoint for dashboard"""
|
||||
try:
|
||||
# Check Redis connection
|
||||
redis_healthy = await redis_manager.ping()
|
||||
|
||||
health_data = {
|
||||
'status': 'healthy' if redis_healthy else 'degraded',
|
||||
'redis': 'connected' if redis_healthy else 'disconnected',
|
||||
'version': '1.0.0',
|
||||
'timestamp': time.time()
|
||||
}
|
||||
|
||||
return response_formatter.status_response(health_data)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Health check failed: {e}")
|
||||
return JSONResponse(
|
||||
status_code=503,
|
||||
content=response_formatter.error("Service unavailable", "HEALTH_CHECK_FAILED")
|
||||
)
|
||||
|
||||
# Health check endpoint
|
||||
@app.get("/health")
|
||||
async def health_check():
|
||||
"""Health check endpoint"""
|
||||
try:
|
||||
# Check Redis connection
|
||||
redis_healthy = await redis_manager.ping()
|
||||
|
||||
health_data = {
|
||||
'status': 'healthy' if redis_healthy else 'degraded',
|
||||
'redis': 'connected' if redis_healthy else 'disconnected',
|
||||
'version': '1.0.0'
|
||||
}
|
||||
|
||||
return response_formatter.status_response(health_data)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Health check failed: {e}")
|
||||
return JSONResponse(
|
||||
status_code=503,
|
||||
content=response_formatter.error("Service unavailable", "HEALTH_CHECK_FAILED")
|
||||
)
|
||||
|
||||
# Heatmap endpoints
|
||||
@app.get("/api/v1/heatmap/{symbol}")
|
||||
async def get_heatmap(
|
||||
@ -519,8 +506,7 @@ def create_app(config_obj=None) -> FastAPI:
|
||||
static_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "web", "static")
|
||||
if os.path.exists(static_path):
|
||||
app.mount("/static", StaticFiles(directory=static_path), name="static")
|
||||
# Serve index.html at root for dashboard, but this should be last
|
||||
app.mount("/", StaticFiles(directory=static_path, html=True), name="dashboard")
|
||||
# Don't mount at root to avoid conflicts with WebSocket and API routes
|
||||
|
||||
return app
|
||||
|
||||
|
Reference in New Issue
Block a user