mega changes

This commit is contained in:
2025-11-20 11:11:18 +01:00
parent e070c95190
commit 841d79f26b
138 changed files with 21499 additions and 8844 deletions

View File

@@ -22,110 +22,103 @@ router = APIRouter()
async def get_usage_metrics(
hours: int = Query(24, ge=1, le=168, description="Hours to analyze (1-168)"),
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
db: Session = Depends(get_db),
):
"""Get comprehensive usage metrics including costs and budgets"""
try:
analytics = get_analytics_service()
metrics = await analytics.get_usage_metrics(hours=hours, user_id=current_user['id'])
return {
"success": True,
"data": metrics,
"period_hours": hours
}
metrics = await analytics.get_usage_metrics(
hours=hours, user_id=current_user["id"]
)
return {"success": True, "data": metrics, "period_hours": hours}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error getting usage metrics: {str(e)}")
raise HTTPException(
status_code=500, detail=f"Error getting usage metrics: {str(e)}"
)
@router.get("/metrics/system")
async def get_system_metrics(
hours: int = Query(24, ge=1, le=168),
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
db: Session = Depends(get_db),
):
"""Get system-wide metrics (admin only)"""
if not current_user['is_superuser']:
if not current_user["is_superuser"]:
raise HTTPException(status_code=403, detail="Admin access required")
try:
analytics = get_analytics_service()
metrics = await analytics.get_usage_metrics(hours=hours)
return {
"success": True,
"data": metrics,
"period_hours": hours
}
return {"success": True, "data": metrics, "period_hours": hours}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error getting system metrics: {str(e)}")
raise HTTPException(
status_code=500, detail=f"Error getting system metrics: {str(e)}"
)
@router.get("/health")
async def get_system_health(
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
current_user: User = Depends(get_current_user), db: Session = Depends(get_db)
):
"""Get system health status including budget and performance analysis"""
try:
analytics = get_analytics_service()
health = await analytics.get_system_health()
return {
"success": True,
"data": health
}
return {"success": True, "data": health}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error getting system health: {str(e)}")
raise HTTPException(
status_code=500, detail=f"Error getting system health: {str(e)}"
)
@router.get("/costs")
async def get_cost_analysis(
days: int = Query(30, ge=1, le=365, description="Days to analyze (1-365)"),
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
db: Session = Depends(get_db),
):
"""Get detailed cost analysis and trends"""
try:
analytics = get_analytics_service()
analysis = await analytics.get_cost_analysis(days=days, user_id=current_user['id'])
return {
"success": True,
"data": analysis,
"period_days": days
}
analysis = await analytics.get_cost_analysis(
days=days, user_id=current_user["id"]
)
return {"success": True, "data": analysis, "period_days": days}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error getting cost analysis: {str(e)}")
raise HTTPException(
status_code=500, detail=f"Error getting cost analysis: {str(e)}"
)
@router.get("/costs/system")
async def get_system_cost_analysis(
days: int = Query(30, ge=1, le=365),
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
db: Session = Depends(get_db),
):
"""Get system-wide cost analysis (admin only)"""
if not current_user['is_superuser']:
if not current_user["is_superuser"]:
raise HTTPException(status_code=403, detail="Admin access required")
try:
analytics = get_analytics_service()
analysis = await analytics.get_cost_analysis(days=days)
return {
"success": True,
"data": analysis,
"period_days": days
}
return {"success": True, "data": analysis, "period_days": days}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error getting system cost analysis: {str(e)}")
raise HTTPException(
status_code=500, detail=f"Error getting system cost analysis: {str(e)}"
)
@router.get("/endpoints")
async def get_endpoint_stats(
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
current_user: User = Depends(get_current_user), db: Session = Depends(get_db)
):
"""Get endpoint usage statistics"""
try:
analytics = get_analytics_service()
# For now, return the in-memory stats
# In future, this could be enhanced with database queries
return {
@@ -133,74 +126,79 @@ async def get_endpoint_stats(
"data": {
"endpoint_stats": dict(analytics.endpoint_stats),
"status_codes": dict(analytics.status_codes),
"model_stats": dict(analytics.model_stats)
}
"model_stats": dict(analytics.model_stats),
},
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error getting endpoint stats: {str(e)}")
raise HTTPException(
status_code=500, detail=f"Error getting endpoint stats: {str(e)}"
)
@router.get("/usage-trends")
async def get_usage_trends(
days: int = Query(7, ge=1, le=30, description="Days for trend analysis"),
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
db: Session = Depends(get_db),
):
"""Get usage trends over time"""
try:
from datetime import datetime, timedelta
from sqlalchemy import func
from app.models.usage_tracking import UsageTracking
cutoff_time = datetime.utcnow() - timedelta(days=days)
# Daily usage trends
daily_usage = db.query(
func.date(UsageTracking.created_at).label('date'),
func.count(UsageTracking.id).label('requests'),
func.sum(UsageTracking.total_tokens).label('tokens'),
func.sum(UsageTracking.cost_cents).label('cost_cents')
).filter(
UsageTracking.created_at >= cutoff_time,
UsageTracking.user_id == current_user['id']
).group_by(
func.date(UsageTracking.created_at)
).order_by('date').all()
daily_usage = (
db.query(
func.date(UsageTracking.created_at).label("date"),
func.count(UsageTracking.id).label("requests"),
func.sum(UsageTracking.total_tokens).label("tokens"),
func.sum(UsageTracking.cost_cents).label("cost_cents"),
)
.filter(
UsageTracking.created_at >= cutoff_time,
UsageTracking.user_id == current_user["id"],
)
.group_by(func.date(UsageTracking.created_at))
.order_by("date")
.all()
)
trends = []
for date, requests, tokens, cost_cents in daily_usage:
trends.append({
"date": date.isoformat(),
"requests": requests,
"tokens": tokens or 0,
"cost_cents": cost_cents or 0,
"cost_dollars": (cost_cents or 0) / 100
})
return {
"success": True,
"data": {
"trends": trends,
"period_days": days
}
}
trends.append(
{
"date": date.isoformat(),
"requests": requests,
"tokens": tokens or 0,
"cost_cents": cost_cents or 0,
"cost_dollars": (cost_cents or 0) / 100,
}
)
return {"success": True, "data": {"trends": trends, "period_days": days}}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error getting usage trends: {str(e)}")
raise HTTPException(
status_code=500, detail=f"Error getting usage trends: {str(e)}"
)
@router.get("/overview")
async def get_analytics_overview(
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
current_user: User = Depends(get_current_user), db: Session = Depends(get_db)
):
"""Get analytics overview data"""
try:
analytics = get_analytics_service()
# Get basic metrics
metrics = await analytics.get_usage_metrics(hours=24, user_id=current_user['id'])
metrics = await analytics.get_usage_metrics(
hours=24, user_id=current_user["id"]
)
health = await analytics.get_system_health()
return {
"success": True,
"data": {
@@ -210,8 +208,8 @@ async def get_analytics_overview(
"error_rate": metrics.error_rate,
"budget_usage_percentage": metrics.budget_usage_percentage,
"system_health": health.status,
"health_score": health.score
}
"health_score": health.score,
},
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error getting overview: {str(e)}")
@@ -219,16 +217,15 @@ async def get_analytics_overview(
@router.get("/modules")
async def get_module_analytics(
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
current_user: User = Depends(get_current_user), db: Session = Depends(get_db)
):
"""Get analytics data for all modules"""
try:
module_stats = []
for name, module in module_manager.modules.items():
stats = {"name": name, "initialized": getattr(module, "initialized", False)}
# Get module statistics if available
if hasattr(module, "get_stats"):
try:
@@ -240,18 +237,22 @@ async def get_module_analytics(
except Exception as e:
logger.warning(f"Failed to get stats for module {name}: {e}")
stats["error"] = str(e)
module_stats.append(stats)
return {
"success": True,
"data": {
"modules": module_stats,
"total_modules": len(module_stats),
"system_health": "healthy" if all(m.get("initialized", False) for m in module_stats) else "warning"
}
"system_health": "healthy"
if all(m.get("initialized", False) for m in module_stats)
else "warning",
},
}
except Exception as e:
logger.error(f"Failed to get module analytics: {e}")
raise HTTPException(status_code=500, detail="Failed to retrieve module analytics")
raise HTTPException(
status_code=500, detail="Failed to retrieve module analytics"
)