litellm/tests/test_litellm/proxy/auth
ishaan-berri 0afffe4366
feat: multiple concurrent budget windows per API key and team (#24883) (#25109)
* feat: multiple concurrent budget windows per API key and team (#24883)

* feat(proxy): add BudgetLimitEntry type and wire budget_limits into key/team models

* feat(schema): add budget_limits Json column to VerificationToken and TeamTable

* feat(migrations): add migration for budget_limits column on keys and teams

* feat(keys): initialize budget_limits windows with reset_at on key create/update

* feat(teams): initialize budget_limits windows with reset_at on team create/update

* feat(auth): add _virtual_key_multi_budget_check and _team_multi_budget_check

* feat(auth): call multi-budget checks from common_checks for keys and teams

* feat(proxy): increment per-window Redis spend counters after each request

* feat(budget): reset individual budget windows on schedule via reset_budget_job

* feat(ui): add hourly option to BudgetDurationDropdown

* feat(ui): add budget_limits field to KeyResponse type

* feat(ui): add Budget Windows editor to key edit view

* feat(ui): add Budget Windows editor to create key form

* fix(proxy): strip budget_limits=None before Prisma upsert to fix login 500

Prisma rejects nullable JSON fields (Json? without @default) when passed as
Python None — it needs the field omitted entirely so the DB stores NULL via
the column's nullable constraint. This was breaking /v2/login because the UI
session key creation path hit the upsert with budget_limits=None.

* ui(key-edit): use antd InputNumber+Button for budget windows, add reset hints

* ui(create-key): use antd InputNumber+Button for budget windows, add reset hints

* docs(users): add multiple budget windows section with API + dashboard walkthrough

* fix: BudgetExceededError returns HTTP 429 instead of 400

- Add status_code=429 to BudgetExceededError class
- auth_exception_handler hardcoded code=400 → code=429

* fix: no-op else branch in multi-budget auth checks causes KeyError

- BudgetLimitEntry objects must be coerced via model_dump() not left as-is
- Move _virtual_key_multi_budget_check into common_checks (was asymmetric
  with _team_multi_budget_check which already lived there)

* fix: len() on JSON string returns char count not window count

Guard with isinstance check + json.loads() before iterating per-window
Redis counters in increment_spend_counters

* fix: silent except:pass hides Redis reset failures in reset_budget_windows

Log Redis counter reset failures as warnings so they are observable

* test: add unit tests for multi-budget window enforcement

5 tests covering: no budget_limits passes, under budget passes,
over hourly window raises 429, over monthly window raises 429,
BudgetLimitEntry objects coerced without KeyError

* fix: key per-window counters stable across reorders (duration key, not index)

* fix: team+key per-window spend increments use duration key, not index

* fix: budget window reset uses duration key; log failures instead of swallowing

* refactor: extract BudgetWindowsEditor to shared component

* refactor: key_edit_view imports BudgetWindowsEditor from shared component

* refactor: create_key_button imports BudgetWindowsEditor from shared component

---------

Co-authored-by: Ishaan Jaffer <ishaanjaffer0324@gmail.com>

* fix(reset_budget_job): extract _reset_expired_window helper to fix PLR0915 too many statements

* feat(skills): Skills Registry & Hub — register skills, browse in AI Hub, public skill hub (#25118)

* feat(skills): add domain and namespace fields to plugin types

* feat(skills): store and return domain/namespace inside manifest_json

* feat(skills): add /public/skill_hub endpoint for unauthenticated access

* feat(skills): whitelist /public/skill_hub from auth requirements

* feat(skills): add domain, namespace to Plugin and RegisterPluginRequest types

* feat(skills): smart URL parser — paste github URL, auto-detect source type and name

* feat(skills): replace enable toggle with Public badge, make rows clickable

* feat(skills): add skill detail view with Overview and How to Use tabs

* feat(skills): add MakeSkillPublicForm modal for publishing skills to the hub

* feat(skills): rename panel to Skills, wire in skill detail view on row click

* feat(skills): add skill hub table columns — name, description, domain, source, status

* feat(skills): add SkillHubDashboard with stats row, domain dropdown filter, and table

* feat(skills): add Skill Hub tab to AI Hub with Select Skills to Make Public button

* feat(skills): move Skills to top-level nav item directly under MCP Servers

* feat(skills): add skillHubPublicCall and NEXT_PUBLIC_BASE_URL support

* feat(skills): add Skill Hub tab to public AI Hub page

* feat(skills): add skills page routing in main app router

* feat(skills): add /skills page route

* chore: update package-lock after npm install

* docs(skills): add Skills Gateway doc page with mermaid architecture diagram

* docs(skills): add Skills Gateway to sidebar under Agent & MCP Gateway

* docs(skills): add loom walkthrough video to Skills Gateway doc

* chore: fixes

---------

Co-authored-by: Ishaan Jaffer <ishaanjaffer0324@gmail.com>
Co-authored-by: Yuneng Jiang <yuneng@berri.ai>
2026-04-06 14:02:04 -07:00
..
test_auth_checks.py fix(proxy): enforce budget limits across multi-pod deployments via Redis-backed spend counters 2026-03-27 20:39:52 +01:00
test_auth_exception_handler.py Litellm fix GitHub action testing (#11163) 2025-05-26 14:41:42 -07:00
test_auth_hot_path_network_requests.py fix: update docker test file to right path 2026-02-19 18:44:28 +05:30
test_auth_utils.py fix: guard empty-dict team limits and malformed int in deployment default limits 2026-03-19 07:40:47 -04:00
test_cli_auth.py Fix team cli auth flow (#19666) 2026-01-28 08:52:52 -08:00
test_custom_auth_end_user_budget.py fix(proxy): make common_checks opt-in for custom auth via custom_auth_run_common_checks 2026-03-03 22:50:34 +05:30
test_handle_jwt.py fix: fix ci/cd + handle oidc jwt tokens 2026-03-30 16:12:58 -07:00
test_info_routes.py test: add unit tests for /v2/user/info endpoint and route checks 2026-03-12 07:46:31 +00:00
test_litellm_license.py Show remaining users on UI (#11568) 2025-06-09 22:04:45 -07:00
test_login_utils.py remove key blocking 2026-01-31 16:46:17 -08:00
test_mcp_ip_filtering.py Return Clear error message why no tools are available / IP Filtering occured 2026-02-26 09:56:44 +05:30
test_model_checks.py Reapply "feat: add model_cost aliases expansion support" 2026-03-12 13:36:57 -03:00
test_model_checks_fallbacks.py feat: extended /v1/models endpoint, now it returns with fallbacks on demand (#12811) 2025-07-22 23:16:46 -07:00
test_multi_budget_windows.py feat: multiple concurrent budget windows per API key and team (#24883) (#25109) 2026-04-06 14:02:04 -07:00
test_object_permission_loading.py Fix:test_get_key_object_loads_object_permission 2026-02-18 19:18:15 +05:30
test_onboarding.py fix(onboarding): prevent invite link reuse for password reset 2026-02-28 17:39:03 -08:00
test_organization_budget_enforcement.py Fix/organization max budget not enforced (#17334) 2025-12-02 22:46:03 -08:00
test_password_hashing.py chore: fixes 2026-03-30 18:36:58 -07:00
test_route_checks.py Litellm ishaan april2 (#25113) 2026-04-04 12:31:49 -07:00
test_team_member_budget.py 3[Fix] CI/CD - logging_testing (#18204) 2025-12-18 10:52:24 -08:00
test_unmapped_model_budget_enforcement.py fix(auth): enforce budget for models not in cost map (#24949) 2026-04-01 19:10:30 -07:00
test_user_api_key_auth.py [Infra] Merge internal dev branch with main (#25036) 2026-04-02 16:38:01 -07:00