mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-03 07:23:33 +00:00
* feat(usage): show subscription-covered providers and account fees separately * fix(usage): write only the named fee columns and sync the root schema The fee update now writes just the columns the request names, so two admins changing different fields at once both land, and the dashboard edit form sends only what changed. The root schema.prisma carries the new table like the two copies, and a billing period anchored in the calendar's last month ends on December 31, 9999 instead of failing. * fix(usage): register the subscription table span and keep provider logic under llms * fix(subscription_accounts): register the fee routes as management routes and reject an empty account id * fix(usage): run the new tests in CI and close subscription card review gaps Adds the subscription test file to its unit shard, sets the migration lock timeout, rejects infinite fees, keeps the card from rewriting login files, lists each deployment once without aliases, shows the provider badge on entity views, and asks before removing a fee * fix(usage): resolve named-credential ChatGPT accounts and keep admin viewers read-only on the fee card * fix(usage): count a subscription fee only for accounts behind a current deployment Usage listed a fee row for an account no deployment uses while another ChatGPT deployment existed and dropped it when none did. It now lists only accounts behind a current deployment in both cases. Adds a real proxy and Postgres integration test for the fee API and for ChatGPT Responses rows on a deployment's own login, and names the card's multi-component test with the integration suffix. * fix(usage): keep a stored subscription fee listed after its account's deployments are removed The usage route lists every account behind a subscription deployment plus every account carrying a stored fee, and reads the fees on every proxy, so a fee stays visible, counted, and editable for past ranges after its last deployment goes. The integration test now polls every day the calls spanned, so a UTC midnight crossing no longer fails it. --------- Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
173 lines
4.3 KiB
Python
173 lines
4.3 KiB
Python
"""Path allowlist for the UI backend (control plane) component.
|
|
|
|
The backend exposes management/admin endpoints consumed by the UI: keys, users,
|
|
teams, orgs, customers, budgets, tags, workflows, model management, spend &
|
|
analytics, settings (router/cache/cost-tracking/fallbacks), SSO/onboarding,
|
|
audit logs, debug, enterprise admin, and UI bootstrap helpers (logo, favicon,
|
|
.well-known config).
|
|
|
|
Anything LLM data-plane is dropped — those run on the gateway component.
|
|
"""
|
|
|
|
BACKEND_PATH_PREFIXES: tuple[str, ...] = (
|
|
# Identity / access
|
|
"/key/",
|
|
"/v2/key/",
|
|
"/user/",
|
|
"/v2/user/",
|
|
"/team/",
|
|
"/v2/team/",
|
|
"/organization/",
|
|
"/v2/organization/",
|
|
"/customer/",
|
|
"/end_user/",
|
|
"/sso/",
|
|
"/liteadmin/slack/connect/",
|
|
"/moyai/connect/",
|
|
"/login",
|
|
"/v2/login",
|
|
"/v3/login",
|
|
"/logout",
|
|
"/session/logout",
|
|
"/token",
|
|
"/onboarding/",
|
|
"/audit",
|
|
"/telemetry/",
|
|
"/oauth/",
|
|
"/invitation/",
|
|
"/jwt/",
|
|
# Models & routing config
|
|
"/model/",
|
|
"/v1/model/info",
|
|
"/v1/model/deprecations",
|
|
"/v2/model/",
|
|
"/model_group",
|
|
"/model_access_group/",
|
|
"/model_hub/",
|
|
"/v1/access_group",
|
|
"/access_group/",
|
|
"/router/",
|
|
"/router_settings",
|
|
"/adaptive_router/",
|
|
"/auto_router/",
|
|
"/fallback",
|
|
"/fallbacks",
|
|
"/cache_settings",
|
|
"/coordination_redis/",
|
|
"/cost_tracking",
|
|
"/subscription_accounts/",
|
|
"/cost_optimization/",
|
|
"/cost/",
|
|
"/credentials",
|
|
"/credential",
|
|
"/provider/budgets",
|
|
# Tools / agents (registry & policy admin)
|
|
"/v1/tool/",
|
|
"/v1/agents",
|
|
"/agent/daily/activity/",
|
|
# Guardrails admin
|
|
"/v2/guardrails/",
|
|
# MCP server admin + BYOK OAuth flow (UI-initiated) + dynamic per-server endpoints
|
|
"/v1/mcp/",
|
|
"/test/",
|
|
"/{mcp_server_name}/",
|
|
# Budgets / tags / workflows / memory mgmt
|
|
"/budget/",
|
|
"/tag/",
|
|
"/workflow/",
|
|
"/v1/workflows/",
|
|
"/project/",
|
|
"/memory/",
|
|
"/mcp/",
|
|
# Control plane (see the List Endpoints + Tables standard). Every resource
|
|
# eventually moves under this prefix, so allowlist it once rather than
|
|
# per-resource.
|
|
"/management/v1/",
|
|
# Spend / analytics
|
|
"/spend/",
|
|
"/analytics/",
|
|
"/lens/",
|
|
"/v1/traces",
|
|
"/v1/logs",
|
|
"/global/",
|
|
"/user_agent",
|
|
"/usage/",
|
|
"/daily/",
|
|
# Deployment-wide gateway request and error counts. Scoped to the analytics reads rather
|
|
# than all of /gateway/, which stays free for data-plane routes.
|
|
"/gateway/daily/",
|
|
"/gateway/errors/",
|
|
# CloudZero cost-export admin (init / settings / export / dry-run / delete)
|
|
"/cloudzero/",
|
|
# Caching admin
|
|
"/cache/",
|
|
"/caching/",
|
|
# Callbacks / hooks
|
|
"/active/callbacks",
|
|
"/callbacks",
|
|
"/team_callback",
|
|
# Rust data-plane gateway → proxy control-plane API (logging today, auth later)
|
|
"/v1/rust_control_plane/",
|
|
# Alerting / email / IP allowlist
|
|
"/alerting/",
|
|
"/email/",
|
|
"/add/allowed_ip",
|
|
"/delete/allowed_ip",
|
|
"/get/",
|
|
# Enterprise admin
|
|
"/enterprise/",
|
|
# Debug / config / profiling
|
|
"/debug/",
|
|
"/config/",
|
|
"/memory-usage-in-mem-cache",
|
|
"/otel-spans",
|
|
"/lazy/",
|
|
"/in_product_nudges",
|
|
# Admin reload / schedule
|
|
"/reload/",
|
|
"/schedule/",
|
|
"/settings",
|
|
"/update/",
|
|
"/upload/",
|
|
# Dev / admin utilities
|
|
"/utils/",
|
|
# UI bootstrap helpers (assets the dashboard fetches)
|
|
"/get_logo_url",
|
|
"/get_image",
|
|
"/get_favicon",
|
|
"/.well-known/",
|
|
"/litellm/.well-known/",
|
|
"/ui_discovery/",
|
|
"/ui-config",
|
|
"/sso_settings",
|
|
"/public/",
|
|
"/robots.txt",
|
|
# Health (k8s probes)
|
|
"/health",
|
|
# Plugin system
|
|
"/api/plugins",
|
|
"/plugin-proxy/",
|
|
)
|
|
|
|
BACKEND_EXACT_PATHS: frozenset[str] = frozenset(
|
|
{
|
|
"/",
|
|
"/routes",
|
|
"/lens",
|
|
"/openapi.json",
|
|
"/docs",
|
|
"/docs/oauth2-redirect",
|
|
"/redoc",
|
|
"/fallback/login",
|
|
"/mcp", # bare spelling of the aggregate MCP endpoint; /mcp/ prefix covers the rest
|
|
}
|
|
)
|
|
|
|
BACKEND_MOUNT_PATHS: frozenset[str] = frozenset(
|
|
{
|
|
"/admin",
|
|
"/metrics",
|
|
"/swagger", # API documentation static assets belong to the backend
|
|
"/mcp", # lazily-mounted MCP sub-app serves on the backend component
|
|
}
|
|
)
|