"""sage_datamark 模块初始化 — 统一 Dashboard API""" from ahserver.serverenv import ServerEnv from appPublic.jsonConfig import getConfig from appPublic.log import debug, exception from sqlor.dbpools import DBPools, get_sor_context from .etl import sync_call_fact, aggregate_daily_perf, aggregate_provider_cost, ensure_tables from .dashboards import ( get_today_usage, get_today_amount, get_success_rate, get_fail_count, get_active_users, get_top_models, get_top_providers, get_top_users, get_customer_daily_models, get_customer_monthly_models, get_customer_user_today, get_daily_trend, get_hourly_concurrency, ) MODULE_NAME = "sage_datamark" # ── 性能指标 API ── async def api_model_perf(sor, params_kw=None): model = params_kw.get('model') if params_kw else None stat_date = params_kw.get('date') if params_kw else None sql = "SELECT * FROM dm_model_perf_daily WHERE 1=1" ns = {} if stat_date: sql += " AND stat_date=${stat_date}$" ns['stat_date'] = stat_date if model: sql += " AND model=${model}$" ns['model'] = model sql += " ORDER BY total_calls DESC LIMIT 50" rows = await sor.sqlExe(sql, ns) return [dict(r) for r in rows] async def api_provider_roi(sor, params_kw=None): model = params_kw.get('model') if params_kw else None stat_date = params_kw.get('date') if params_kw else None sql = "SELECT * FROM dm_provider_cost_daily WHERE 1=1" ns = {} if stat_date: sql += " AND stat_date=${stat_date}$" ns['stat_date'] = stat_date if model: sql += " AND model=${model}$" ns['model'] = model sql += " ORDER BY total_amount DESC LIMIT 50" rows = await sor.sqlExe(sql, ns) return [dict(r) for r in rows] # ── 运营指标 API(替代 dashboard_for_sage)── async def api_stats(request): """统计卡片数据 — /sage_datamark/api/stats.dspy""" env = request._run_ns async with get_sor_context(env, MODULE_NAME) as sor: return { 'today_usage': await get_today_usage(env, sor), 'today_amount': await get_today_amount(env, sor), 'success_rate': await get_success_rate(env, sor), 'fail_count': await get_fail_count(env, sor), 'active_users': await get_active_users(env, sor), } async def api_top_models(request): """Top 模型 — /sage_datamark/api/top_models.dspy""" env = request._run_ns async with get_sor_context(env, MODULE_NAME) as sor: return await get_top_models(env, sor) async def api_top_providers(request): """Top 供应商 — /sage_datamark/api/top_providers.dspy""" env = request._run_ns async with get_sor_context(env, MODULE_NAME) as sor: return await get_top_providers(env, sor) async def api_top_users(request): """Top 用户 — /sage_datamark/api/top_users.dspy""" env = request._run_ns async with get_sor_context(env, MODULE_NAME) as sor: return await get_top_users(env, sor) async def api_customer_models(request): """客户用量 — /sage_datamark/api/customer_models.dspy""" env = request._run_ns userorgid = await env.get_userorgid() async with get_sor_context(env, MODULE_NAME) as sor: return { 'daily': await get_customer_daily_models(env, sor, userorgid), 'monthly': await get_customer_monthly_models(env, sor, userorgid), } async def api_daily_trend(request): """7天趋势 — /sage_datamark/api/daily_trend.dspy""" env = request._run_ns async with get_sor_context(env, MODULE_NAME) as sor: return await get_daily_trend(env, sor) async def api_hourly_concurrency(request): """每小时并发 — /sage_datamark/api/hourly_concurrency.dspy""" env = request._run_ns async with get_sor_context(env, MODULE_NAME) as sor: return await get_hourly_concurrency(env, sor) # ── Jinja2 模板函数(给 stat_*.ui 调用)── async def j2_today_usage(request): env = request._run_ns async with get_sor_context(env, MODULE_NAME) as sor: return await get_today_usage(env, sor) async def j2_today_amount(request): env = request._run_ns async with get_sor_context(env, MODULE_NAME) as sor: return await get_today_amount(env, sor) def load_sage_datamark(): env = ServerEnv() env.api_model_perf = api_model_perf env.api_provider_roi = api_provider_roi env.api_stats = api_stats env.api_top_models = api_top_models env.api_top_providers = api_top_providers env.api_top_users = api_top_users env.api_customer_models = api_customer_models env.api_daily_trend = api_daily_trend env.api_hourly_concurrency = api_hourly_concurrency env.j2_today_usage = j2_today_usage env.j2_today_amount = j2_today_amount debug("[sage_datamark] registered all API endpoints")