litellm/tests/test_litellm
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
..
a2a_protocol fix(a2a): preserve JSON-RPC envelope for AgentCore A2A-native agents (#25092) 2026-04-03 20:25:32 -07:00
anthropic_interface/exceptions
caching Litellm ishaan march 20 (#24303) 2026-03-21 12:40:11 -07:00
completion_extras feat(openai): round-trip Responses API reasoning_items in chat completions 2026-03-27 20:25:08 +05:30
containers
enterprise Revert "[Fix] Populate _hidden_params.model_id in batch terminal-state shortcut path" 2026-03-13 12:21:39 -07:00
expected_fine_tuning_api refactor: refactor testing 2026-03-28 18:39:32 -07:00
expected_responses_api_request
experimental_mcp_client feat(mcp): add token authentication support for MCP servers 2026-03-10 18:33:08 +02:00
google_genai Revert "QA: improve gpt-5.4 code/bugs" 2026-03-13 10:15:47 -07:00
images Root cause fix - migrate all logging update to use 1 function - for centralized kwarg updates (#23659) 2026-03-15 23:21:01 -07:00
integrations Litellm fix update bedrock models (#24947) 2026-04-01 19:22:54 -07:00
interactions [Staging] - Ishaan March 17th (#23903) 2026-03-18 15:09:01 -07:00
litellm_core_utils Litellm fix update bedrock models (#24947) 2026-04-01 19:22:54 -07:00
llms feat(teams): per-member model scope + team default_team_member_models (#24950) 2026-04-06 13:48:43 -07:00
ocr Enable local file support for OCR (#22133) 2026-02-27 10:50:02 -08:00
passthrough Litellm fix update bedrock models (#24947) 2026-04-01 19:22:54 -07:00
proxy feat: multiple concurrent budget windows per API key and team (#24883) (#25109) 2026-04-06 14:02:04 -07:00
responses Litellm ishaan march23 - MCP Toolsets + GCP Caching fix (#25146) (#25155) 2026-04-04 16:23:21 -07:00
router_strategy Litellm ishaan march30 (#24887) (#25151) 2026-04-04 14:44:07 -07:00
router_utils Litellm ishaan april4 2 (#25150) 2026-04-04 23:09:42 +00:00
secret_managers fix(tests): isolate flaky files endpoint tests from global proxy state (#21788) 2026-02-21 11:20:32 -08:00
test_router fix: use atomic increment-first pattern for model RPM rate limiting 2026-02-24 09:55:07 -03:00
types Litellm ishaan april4 2 (#25150) 2026-04-04 23:09:42 +00:00
vector_stores
__init__.py
conftest.py Fix test isolation: clear litellm.callbacks and model_fallbacks between tests 2026-03-15 16:43:15 -07:00
log.txt
readme.md
test_a2a_registry_lookup.py
test_acompletion_session_reuse_e2e.py
test_add_deployment_no_master_key.py
test_aembedding_session_reuse_e2e.py
test_anthropic_beta_headers_filtering.py Litellm fix update bedrock models (#24947) 2026-04-01 19:22:54 -07:00
test_anthropic_skills_transformation.py Clean up skills test: remove duplicate imports, parameterize mock HTTP method (#23360) 2026-03-11 22:10:27 +05:30
test_azure_video_router.py
test_chat_ui_responses_session.py [Docs] Fix "Page Not Found" link for Anthropic endpoint (#23349) 2026-03-11 20:17:41 +05:30
test_claude_haiku_4_5_config.py
test_claude_opus_4_6_config.py Fix the Pricing changes for claude models 2026-03-27 22:44:40 +05:30
test_constants.py Fix test 2026-03-27 21:21:43 +05:30
test_container_router.py
test_cost_calculation_log_level.py fix(tests): use record.getMessage() instead of record.message for LogRecord 2026-02-18 11:46:32 -03:00
test_cost_calculator.py Revert "fix(whisper): correct output_cost_per_second pricing and cost calcula…" 2026-03-21 20:44:52 +05:30
test_count_tokens_public_api.py merge: resolve conflicts between main and litellm_oss_staging_03_11_2026 2026-03-12 09:38:31 -03:00
test_deepseek_model_metadata.py
test_eager_tiktoken_load.py Fix test isolation: run eager tiktoken tests in subprocesses 2026-03-15 17:32:31 -07:00
test_exception_exports.py
test_exception_header_preservation.py Update test to righ place 2026-02-26 13:26:51 -08:00
test_exception_mapping_request_attribute.py
test_filter_out_litellm_params.py
test_get_blog_posts.py feat: fetch blog posts from docs RSS feed instead of static JSON on GitHub 2026-03-16 15:55:16 -07:00
test_gpt_image_cost_calculator.py
test_groq_streaming_encoding.py
test_lazy_imports.py
test_litellm_params_reserved_keys.py fix(snowflake): transform tool_choice string to object format (#23268) 2026-03-11 01:41:24 +05:30
test_logging.py
test_lowest_latency_zero_tokens.py
test_main.py Litellm fix update bedrock models (#24947) 2026-04-01 19:22:54 -07:00
test_model_cost_aliases.py [Feat] - Ishaan main merge branch (#23596) 2026-03-14 09:40:00 -07:00
test_model_param_helper.py
test_model_response_normalization.py fix(types): remove StreamingChoices from ModelResponse, use ModelResponseStream 2026-02-20 17:47:42 -03:00
test_nested_drop_params.py
test_project_alias_tracking.py feat(proxy): add project_alias tracking through callback metadata pipeline 2026-03-23 10:44:17 -07:00
test_project_tags_pydantic.py fix: req changes 2026-02-27 13:33:34 +05:30
test_redis.py Litellm ishaan march23 - MCP Toolsets + GCP Caching fix (#25146) (#25155) 2026-04-04 16:23:21 -07:00
test_register_model_custom_pricing.py test: fix misleading precedence test per review feedback 2026-03-02 08:31:33 +00:00
test_responses_api_bridge_non_stream.py
test_responses_id_security.py Fix responses ID security test for new request_cache parameter 2026-03-04 11:29:51 -03:00
test_router.py Litellm ishaan april4 2 (#25150) 2026-04-04 23:09:42 +00:00
test_router_google_genai.py
test_router_model_cost_isolation.py
test_router_order_fallback.py Merge pull request #24611 from Sameerlite/Sameerlite/order-fallback2 2026-03-27 20:15:30 +05:30
test_router_per_deployment_num_retries.py
test_router_redis_init.py
test_router_retry_non_retryable_errors.py Reapply "feat: add model_cost aliases expansion support" 2026-03-12 13:36:57 -03:00
test_router_silent_experiment.py Update tests/test_litellm/test_router_silent_experiment.py 2026-03-14 16:47:56 +05:30
test_secret_redaction.py Litellm ishaan march30 (#24887) (#25151) 2026-04-04 14:44:07 -07:00
test_service_logger.py
test_setup_wizard.py test: test 2026-03-28 19:17:38 -07:00
test_shared_session_integration.py
test_ssl_verify_unit.py
test_stream_chunk_builder_annotations.py fix: merge annotations from all streaming chunks in stream_chunk_builder 2026-03-15 14:20:45 +05:30
test_streaming_connection_cleanup.py
test_system_message_format_bug.py
test_utils.py Litellm ishaan april1 try2 (#25110) 2026-04-03 14:57:44 -07:00
test_uuid_helper.py
test_video_generation.py Add new videos transformation 2026-03-16 17:56:21 +05:30
test_xai_responses_auto_routing.py

Testing for litellm/

This directory 1:1 maps the the litellm/ directory, and can only contain mocked tests.

The point of this is to:

  1. Increase test coverage of litellm/
  2. Make it easy for contributors to add tests for the litellm/ package and easily run tests without needing LLM API keys.

File name conventions

  • litellm/proxy/test_caching_routes.py maps to litellm/proxy/caching_routes.py
  • test_<filename>.py maps to litellm/<filename>.py