From 2a5dfcd5bcc0706ba273df360a30270f7df9e5ce Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Thu, 21 May 2026 17:24:18 -0700 Subject: [PATCH] build(deps-dev): bump black to 26.3.1 and apply formatting (#28525) * build(deps-dev): bump black 24.10.0 -> 26.3.1 * style: apply black 26.3.1 formatting * chore: authorize black 26.3.1 license in liccheck.ini --- litellm/_uuid.py | 1 - .../exceptions/exception_mapping_utils.py | 1 - .../exceptions/exceptions.py | 1 - litellm/compression/content_detection.py | 1 - litellm/files/types.py | 1 - litellm/google_genai/adapters/__init__.py | 4 +- .../SlackAlerting/batching_handler.py | 6 +- litellm/integrations/SlackAlerting/utils.py | 2 +- .../integrations/additional_logging_utils.py | 2 +- litellm/integrations/custom_batch_logger.py | 2 +- litellm/integrations/focus/transformer.py | 1 - litellm/integrations/opik/utils.py | 2 +- litellm/integrations/s3_v2.py | 4 +- litellm/interactions/agents/main.py | 1 - litellm/interactions/main.py | 10 +-- litellm/litellm_core_utils/litellm_logging.py | 12 +-- .../prompt_templates/factory.py | 4 +- .../specialty_caches/dynamic_logging_cache.py | 4 +- .../messages/agentic_streaming_iterator.py | 1 - .../azure/chat/o_series_transformation.py | 8 +- .../azure_ai/embed/cohere_transformation.py | 2 +- .../llms/azure_ai/rerank/transformation.py | 2 +- .../bedrock/claude_platform/common_utils.py | 1 - .../embed/amazon_titan_g1_transformation.py | 2 +- .../bedrock/embed/cohere_transformation.py | 2 +- .../bedrock_mantle/chat/transformation.py | 1 - litellm/llms/cohere/embed/handler.py | 2 +- litellm/llms/custom_httpx/mock_transport.py | 1 - litellm/llms/dashscope/cost_calculator.py | 2 +- litellm/llms/datarobot/chat/transformation.py | 2 +- .../llms/deepinfra/rerank/transformation.py | 2 +- litellm/llms/deepseek/cost_calculator.py | 2 +- .../text_to_speech/transformation.py | 1 - litellm/llms/gemini/agents/transformation.py | 1 - litellm/llms/gemini/videos/transformation.py | 2 +- .../llms/infinity/rerank/transformation.py | 2 +- litellm/llms/jina_ai/rerank/transformation.py | 2 +- .../llms/lm_studio/embed/transformation.py | 2 +- litellm/llms/novita/chat/transformation.py | 2 +- .../llms/nvidia_nim/chat/transformation.py | 4 +- litellm/llms/nvidia_nim/embed.py | 2 +- .../openai/chat/o_series_transformation.py | 12 +-- litellm/llms/openai/common_utils.py | 2 +- .../image_generation/transformation.py | 1 - .../sagemaker/completion/transformation.py | 2 +- .../sagemaker/embedding/transformation.py | 2 +- litellm/llms/sap/credentials.py | 2 +- litellm/llms/snowflake/chat/transformation.py | 1 - litellm/llms/together_ai/chat.py | 2 +- litellm/llms/together_ai/embed.py | 2 +- .../llms/together_ai/rerank/transformation.py | 2 +- .../context_caching/transformation.py | 4 +- .../llms/vertex_ai/gemini/transformation.py | 6 +- .../batch_embed_content_transformation.py | 2 +- .../text_to_speech/text_to_speech_handler.py | 2 +- .../llms/vllm/completion/transformation.py | 2 +- .../embedding/transformation_contextual.py | 4 +- .../mcp_server/openapi_to_mcp_generator.py | 2 +- litellm/proxy/auth/model_checks.py | 1 - .../proxy/common_utils/custom_openapi_spec.py | 6 +- .../proxy/common_utils/http_parsing_utils.py | 3 +- .../common_utils/openai_endpoint_utils.py | 2 +- .../pass_through_endpoints.py | 2 +- litellm/proxy/db/create_views.py | 6 +- litellm/proxy/guardrails/_content_utils.py | 1 - .../guardrail_hooks/akto/__init__.py | 1 - .../proxy/hooks/litellm_skills/__init__.py | 2 +- .../budget_management_endpoints.py | 4 +- .../customer_endpoints.py | 4 +- .../model_management_endpoints.py | 2 +- .../sso/custom_microsoft_sso.py | 2 +- .../management_endpoints/team_endpoints.py | 4 +- .../user_agent_analytics_endpoints.py | 2 +- .../cursor_passthrough_logging_handler.py | 1 - litellm/proxy/proxy_cli.py | 11 +-- litellm/proxy/proxy_server.py | 6 +- .../spend_management_endpoints.py | 6 +- litellm/proxy/utils.py | 12 +-- .../vertex_ai_endpoints/langfuse_endpoints.py | 2 +- litellm/router.py | 2 +- .../router_strategy/adaptive_router/hooks.py | 2 +- .../adaptive_router/signals.py | 1 - litellm/router_strategy/budget_limiter.py | 8 +- litellm/router_utils/get_retry_from_policy.py | 2 +- .../router_utils/pattern_match_deployments.py | 2 +- .../track_deployment_metrics.py | 2 +- litellm/secret_managers/aws_secret_manager.py | 2 +- .../secret_managers/aws_secret_manager_v2.py | 2 +- litellm/vector_store_files/utils.py | 4 +- pyproject.toml | 2 +- tests/code_coverage_tests/liccheck.ini | 1 + uv.lock | 76 ++++++++++++++----- 92 files changed, 165 insertions(+), 178 deletions(-) diff --git a/litellm/_uuid.py b/litellm/_uuid.py index 52acf647dd8..2b7c3b82d35 100644 --- a/litellm/_uuid.py +++ b/litellm/_uuid.py @@ -6,7 +6,6 @@ Always uses fastuuid for performance. import fastuuid as _uuid # type: ignore - # Expose a module-like alias so callers can use: uuid.uuid4() uuid = _uuid diff --git a/litellm/anthropic_interface/exceptions/exception_mapping_utils.py b/litellm/anthropic_interface/exceptions/exception_mapping_utils.py index 28020e763f4..4548185bbdc 100644 --- a/litellm/anthropic_interface/exceptions/exception_mapping_utils.py +++ b/litellm/anthropic_interface/exceptions/exception_mapping_utils.py @@ -9,7 +9,6 @@ from typing import Dict, Optional from .exceptions import AnthropicErrorResponse, AnthropicErrorType - # HTTP status code -> Anthropic error type # Source: https://docs.anthropic.com/en/api/errors ANTHROPIC_ERROR_TYPE_MAP: Dict[int, AnthropicErrorType] = { diff --git a/litellm/anthropic_interface/exceptions/exceptions.py b/litellm/anthropic_interface/exceptions/exceptions.py index 984390fa702..b289e493e6b 100644 --- a/litellm/anthropic_interface/exceptions/exceptions.py +++ b/litellm/anthropic_interface/exceptions/exceptions.py @@ -2,7 +2,6 @@ from typing_extensions import Literal, Required, TypedDict - # Known Anthropic error types # Source: https://docs.anthropic.com/en/api/errors AnthropicErrorType = Literal[ diff --git a/litellm/compression/content_detection.py b/litellm/compression/content_detection.py index 0655a42daf5..975117eb608 100644 --- a/litellm/compression/content_detection.py +++ b/litellm/compression/content_detection.py @@ -5,7 +5,6 @@ Auto-detect content type per message: code, JSON, or text. import json import re - _CODE_KEYWORDS = re.compile( r"\b(?:def |function |class |import |from |require\(|#include|fn |func |const |let |var |public |private |static )\b" ) diff --git a/litellm/files/types.py b/litellm/files/types.py index 688bc86f0cf..ba42a39f666 100644 --- a/litellm/files/types.py +++ b/litellm/files/types.py @@ -1,6 +1,5 @@ from typing import AsyncIterator, Dict, Iterator, Literal, NamedTuple, Union - FileContentProvider = Literal[ "openai", "azure", "vertex_ai", "bedrock", "hosted_vllm", "anthropic", "manus" ] diff --git a/litellm/google_genai/adapters/__init__.py b/litellm/google_genai/adapters/__init__.py index bfa9e712678..6fbe7d95a55 100644 --- a/litellm/google_genai/adapters/__init__.py +++ b/litellm/google_genai/adapters/__init__.py @@ -1,10 +1,10 @@ """ Google GenAI Adapters for LiteLLM -This module provides adapters for transforming Google GenAI generate_content requests +This module provides adapters for transforming Google GenAI generate_content requests to/from LiteLLM completion format with full support for: - Text content transformation -- Tool calling (function declarations, function calls, function responses) +- Tool calling (function declarations, function calls, function responses) - Streaming (both regular and tool calling) - Mixed content (text + tool calls) """ diff --git a/litellm/integrations/SlackAlerting/batching_handler.py b/litellm/integrations/SlackAlerting/batching_handler.py index fdce2e04793..828f3eb4175 100644 --- a/litellm/integrations/SlackAlerting/batching_handler.py +++ b/litellm/integrations/SlackAlerting/batching_handler.py @@ -1,9 +1,9 @@ """ -Handles Batching + sending Httpx Post requests to slack +Handles Batching + sending Httpx Post requests to slack -Slack alerts are sent every 10s or when events are greater than X events +Slack alerts are sent every 10s or when events are greater than X events -see custom_batch_logger.py for more details / defaults +see custom_batch_logger.py for more details / defaults """ from typing import TYPE_CHECKING, Any diff --git a/litellm/integrations/SlackAlerting/utils.py b/litellm/integrations/SlackAlerting/utils.py index e695266c88b..e2580768178 100644 --- a/litellm/integrations/SlackAlerting/utils.py +++ b/litellm/integrations/SlackAlerting/utils.py @@ -18,7 +18,7 @@ else: def process_slack_alerting_variables( - alert_to_webhook_url: Optional[Dict[AlertType, Union[List[str], str]]] + alert_to_webhook_url: Optional[Dict[AlertType, Union[List[str], str]]], ) -> Optional[Dict[AlertType, Union[List[str], str]]]: """ process alert_to_webhook_url diff --git a/litellm/integrations/additional_logging_utils.py b/litellm/integrations/additional_logging_utils.py index 795afd81d41..59319140a18 100644 --- a/litellm/integrations/additional_logging_utils.py +++ b/litellm/integrations/additional_logging_utils.py @@ -1,5 +1,5 @@ """ -Base class for Additional Logging Utils for CustomLoggers +Base class for Additional Logging Utils for CustomLoggers - Health Check for the logging util - Get Request / Response Payload for the logging util diff --git a/litellm/integrations/custom_batch_logger.py b/litellm/integrations/custom_batch_logger.py index 86eae0e7954..8f4844501c3 100644 --- a/litellm/integrations/custom_batch_logger.py +++ b/litellm/integrations/custom_batch_logger.py @@ -1,5 +1,5 @@ """ -Custom Logger that handles batching logic +Custom Logger that handles batching logic Use this if you want your logs to be stored in memory and flushed periodically. """ diff --git a/litellm/integrations/focus/transformer.py b/litellm/integrations/focus/transformer.py index b7d28e3dbb9..6f4433b4a05 100644 --- a/litellm/integrations/focus/transformer.py +++ b/litellm/integrations/focus/transformer.py @@ -9,7 +9,6 @@ import polars as pl from .schema import FOCUS_NORMALIZED_SCHEMA - _TAG_KEYS = ( "team_id", "team_alias", diff --git a/litellm/integrations/opik/utils.py b/litellm/integrations/opik/utils.py index b0ab5991c91..43577505c11 100644 --- a/litellm/integrations/opik/utils.py +++ b/litellm/integrations/opik/utils.py @@ -105,7 +105,7 @@ def _remove_nulls(x: Dict[str, Any]) -> Dict[str, Any]: def get_traces_and_spans_from_payload( - payload: List[Dict[str, Any]] + payload: List[Dict[str, Any]], ) -> Tuple[List[Dict[str, Any]], List[Dict[str, Any]]]: """ Separate traces and spans from payload. diff --git a/litellm/integrations/s3_v2.py b/litellm/integrations/s3_v2.py index 332e84dd07d..4ed8a809a13 100644 --- a/litellm/integrations/s3_v2.py +++ b/litellm/integrations/s3_v2.py @@ -1,8 +1,8 @@ """ s3 Bucket Logging Integration -async_log_success_event: Processes the event, stores it in memory for DEFAULT_S3_FLUSH_INTERVAL_SECONDS seconds or until DEFAULT_S3_BATCH_SIZE and then flushes to s3 -async_log_failure_event: Processes the event, stores it in memory for DEFAULT_S3_FLUSH_INTERVAL_SECONDS seconds or until DEFAULT_S3_BATCH_SIZE and then flushes to s3 +async_log_success_event: Processes the event, stores it in memory for DEFAULT_S3_FLUSH_INTERVAL_SECONDS seconds or until DEFAULT_S3_BATCH_SIZE and then flushes to s3 +async_log_failure_event: Processes the event, stores it in memory for DEFAULT_S3_FLUSH_INTERVAL_SECONDS seconds or until DEFAULT_S3_BATCH_SIZE and then flushes to s3 NOTE 1: S3 does not provide a BATCH PUT API endpoint, so we create tasks to upload each element individually """ diff --git a/litellm/interactions/agents/main.py b/litellm/interactions/agents/main.py index 7375fd6273f..f56c6f3ed5e 100644 --- a/litellm/interactions/agents/main.py +++ b/litellm/interactions/agents/main.py @@ -49,7 +49,6 @@ from litellm.types.interactions import InteractionEnvironment from litellm.types.router import GenericLiteLLMParams from litellm.utils import client - # ------------------------------------------------------------------ # # Shared helpers # # ------------------------------------------------------------------ # diff --git a/litellm/interactions/main.py b/litellm/interactions/main.py index c6eca410fa7..d99cc3d11c7 100644 --- a/litellm/interactions/main.py +++ b/litellm/interactions/main.py @@ -8,25 +8,25 @@ Per OpenAPI spec (https://ai.google.dev/static/api/interactions.openapi.json): Usage: import litellm - + # Create an interaction with a model response = litellm.interactions.create( model="gemini-2.5-flash", input="Hello, how are you?" ) - + # Create an interaction with an agent response = litellm.interactions.create( agent="deep-research-pro-preview-12-2025", input="Research the current state of cancer research" ) - + # Async version response = await litellm.interactions.acreate(...) - + # Get an interaction response = litellm.interactions.get(interaction_id="...") - + # Delete an interaction result = litellm.interactions.delete(interaction_id="...") """ diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py index af0460956a6..2ab037afb0d 100644 --- a/litellm/litellm_core_utils/litellm_logging.py +++ b/litellm/litellm_core_utils/litellm_logging.py @@ -994,10 +994,8 @@ class Logging(LiteLLMLoggingBaseClass): try: # [Non-blocking Extra Debug Information in metadata] if turn_off_message_logging is True: - _metadata["raw_request"] = ( - "redacted by litellm. \ + _metadata["raw_request"] = "redacted by litellm. \ 'litellm.turn_off_message_logging=True'" - ) else: curl_command = self._get_request_curl_command( api_base=additional_args.get("api_base", ""), @@ -1031,12 +1029,8 @@ class Logging(LiteLLMLoggingBaseClass): error=str(e), ) ) - _metadata["raw_request"] = ( - "Unable to Log \ - raw request: {}".format( - str(e) - ) - ) + _metadata["raw_request"] = "Unable to Log \ + raw request: {}".format(str(e)) if getattr(self, "logger_fn", None) and callable(self.logger_fn): try: self.logger_fn( diff --git a/litellm/litellm_core_utils/prompt_templates/factory.py b/litellm/litellm_core_utils/prompt_templates/factory.py index a29f5005570..f169f86079a 100644 --- a/litellm/litellm_core_utils/prompt_templates/factory.py +++ b/litellm/litellm_core_utils/prompt_templates/factory.py @@ -5590,9 +5590,7 @@ def default_response_schema_prompt(response_schema: dict) -> str: prompt_str = """Use this JSON schema: ```json {} - ```""".format( - response_schema - ) + ```""".format(response_schema) return prompt_str diff --git a/litellm/litellm_core_utils/specialty_caches/dynamic_logging_cache.py b/litellm/litellm_core_utils/specialty_caches/dynamic_logging_cache.py index 13341f27a61..0a6a4e82c72 100644 --- a/litellm/litellm_core_utils/specialty_caches/dynamic_logging_cache.py +++ b/litellm/litellm_core_utils/specialty_caches/dynamic_logging_cache.py @@ -1,9 +1,9 @@ """ This is a cache for LangfuseLoggers. -Langfuse Python SDK initializes a thread for each client. +Langfuse Python SDK initializes a thread for each client. -This ensures we do +This ensures we do 1. Proper cleanup of Langfuse initialized clients. 2. Re-use created langfuse clients. """ diff --git a/litellm/llms/anthropic/experimental_pass_through/messages/agentic_streaming_iterator.py b/litellm/llms/anthropic/experimental_pass_through/messages/agentic_streaming_iterator.py index d0780c82d06..d693d50b8e5 100644 --- a/litellm/llms/anthropic/experimental_pass_through/messages/agentic_streaming_iterator.py +++ b/litellm/llms/anthropic/experimental_pass_through/messages/agentic_streaming_iterator.py @@ -13,7 +13,6 @@ from typing import Any, AsyncIterator, Dict, List, Optional, cast from litellm._logging import verbose_logger - # --------------------------------------------------------------------------- # SSE parsing helpers (module-level to keep the class lean) # --------------------------------------------------------------------------- diff --git a/litellm/llms/azure/chat/o_series_transformation.py b/litellm/llms/azure/chat/o_series_transformation.py index cae7513245c..0a73597a4e4 100644 --- a/litellm/llms/azure/chat/o_series_transformation.py +++ b/litellm/llms/azure/chat/o_series_transformation.py @@ -4,10 +4,10 @@ Support for o1 and o3 model families https://platform.openai.com/docs/guides/reasoning Translations handled by LiteLLM: -- modalities: image => drop param (if user opts in to dropping param) -- role: system ==> translate to role 'user' -- streaming => faked by LiteLLM -- Tools, response_format => drop param (if user opts in to dropping param) +- modalities: image => drop param (if user opts in to dropping param) +- role: system ==> translate to role 'user' +- streaming => faked by LiteLLM +- Tools, response_format => drop param (if user opts in to dropping param) - Logprobs => drop param (if user opts in to dropping param) - Temperature => drop param (if user opts in to dropping param) """ diff --git a/litellm/llms/azure_ai/embed/cohere_transformation.py b/litellm/llms/azure_ai/embed/cohere_transformation.py index 64433c21b61..bbbfb60fbde 100644 --- a/litellm/llms/azure_ai/embed/cohere_transformation.py +++ b/litellm/llms/azure_ai/embed/cohere_transformation.py @@ -1,5 +1,5 @@ """ -Transformation logic from OpenAI /v1/embeddings format to Azure AI Cohere's /v1/embed. +Transformation logic from OpenAI /v1/embeddings format to Azure AI Cohere's /v1/embed. Why separate file? Make it easy to see how transformation works diff --git a/litellm/llms/azure_ai/rerank/transformation.py b/litellm/llms/azure_ai/rerank/transformation.py index b5993040ea0..f64133afa8b 100644 --- a/litellm/llms/azure_ai/rerank/transformation.py +++ b/litellm/llms/azure_ai/rerank/transformation.py @@ -1,5 +1,5 @@ """ -Translate between Cohere's `/rerank` format and Azure AI's `/rerank` format. +Translate between Cohere's `/rerank` format and Azure AI's `/rerank` format. """ from typing import Optional diff --git a/litellm/llms/bedrock/claude_platform/common_utils.py b/litellm/llms/bedrock/claude_platform/common_utils.py index 121221518c8..3abb8710de7 100644 --- a/litellm/llms/bedrock/claude_platform/common_utils.py +++ b/litellm/llms/bedrock/claude_platform/common_utils.py @@ -4,7 +4,6 @@ import litellm from litellm.llms.bedrock.base_aws_llm import BaseAWSLLM from litellm.secret_managers.main import get_secret_str - CLAUDE_PLATFORM_SERVICE_NAME: Literal["aws-external-anthropic"] = ( "aws-external-anthropic" ) diff --git a/litellm/llms/bedrock/embed/amazon_titan_g1_transformation.py b/litellm/llms/bedrock/embed/amazon_titan_g1_transformation.py index 2747551af81..64a79b73273 100644 --- a/litellm/llms/bedrock/embed/amazon_titan_g1_transformation.py +++ b/litellm/llms/bedrock/embed/amazon_titan_g1_transformation.py @@ -1,5 +1,5 @@ """ -Transformation logic from OpenAI /v1/embeddings format to Bedrock Amazon Titan G1 /invoke format. +Transformation logic from OpenAI /v1/embeddings format to Bedrock Amazon Titan G1 /invoke format. Why separate file? Make it easy to see how transformation works diff --git a/litellm/llms/bedrock/embed/cohere_transformation.py b/litellm/llms/bedrock/embed/cohere_transformation.py index 2c0dc834144..9570ff1a14c 100644 --- a/litellm/llms/bedrock/embed/cohere_transformation.py +++ b/litellm/llms/bedrock/embed/cohere_transformation.py @@ -1,5 +1,5 @@ """ -Transformation logic from OpenAI /v1/embeddings format to Bedrock Cohere /invoke format. +Transformation logic from OpenAI /v1/embeddings format to Bedrock Cohere /invoke format. Why separate file? Make it easy to see how transformation works """ diff --git a/litellm/llms/bedrock_mantle/chat/transformation.py b/litellm/llms/bedrock_mantle/chat/transformation.py index e413bb22b2d..81a56030a5c 100644 --- a/litellm/llms/bedrock_mantle/chat/transformation.py +++ b/litellm/llms/bedrock_mantle/chat/transformation.py @@ -16,7 +16,6 @@ from litellm.secret_managers.main import get_secret_str from ...openai_like.chat.transformation import OpenAILikeChatConfig - BEDROCK_MANTLE_DEFAULT_REGION = "us-east-1" diff --git a/litellm/llms/cohere/embed/handler.py b/litellm/llms/cohere/embed/handler.py index 3ab8baf7ba8..81b6a1c7aec 100644 --- a/litellm/llms/cohere/embed/handler.py +++ b/litellm/llms/cohere/embed/handler.py @@ -1,5 +1,5 @@ """ -Legacy /v1/embedding handler for Bedrock Cohere. +Legacy /v1/embedding handler for Bedrock Cohere. """ import json diff --git a/litellm/llms/custom_httpx/mock_transport.py b/litellm/llms/custom_httpx/mock_transport.py index c9844753e0e..ad93cc134ee 100644 --- a/litellm/llms/custom_httpx/mock_transport.py +++ b/litellm/llms/custom_httpx/mock_transport.py @@ -13,7 +13,6 @@ from typing import Tuple import httpx - # --------------------------------------------------------------------------- # Pre-built response templates # --------------------------------------------------------------------------- diff --git a/litellm/llms/dashscope/cost_calculator.py b/litellm/llms/dashscope/cost_calculator.py index 9b3e3851162..8bb7f605b82 100644 --- a/litellm/llms/dashscope/cost_calculator.py +++ b/litellm/llms/dashscope/cost_calculator.py @@ -1,5 +1,5 @@ """ -Cost calculator for Dashscope Chat models. +Cost calculator for Dashscope Chat models. Handles tiered pricing and prompt caching scenarios. """ diff --git a/litellm/llms/datarobot/chat/transformation.py b/litellm/llms/datarobot/chat/transformation.py index 23ce63c25b2..f81e2420930 100644 --- a/litellm/llms/datarobot/chat/transformation.py +++ b/litellm/llms/datarobot/chat/transformation.py @@ -1,5 +1,5 @@ """ -Support for OpenAI's `/v1/chat/completions` endpoint. +Support for OpenAI's `/v1/chat/completions` endpoint. Calls done in OpenAI/openai.py as DataRobot is openai-compatible. """ diff --git a/litellm/llms/deepinfra/rerank/transformation.py b/litellm/llms/deepinfra/rerank/transformation.py index 276735f4758..e4bfbcb2513 100644 --- a/litellm/llms/deepinfra/rerank/transformation.py +++ b/litellm/llms/deepinfra/rerank/transformation.py @@ -1,5 +1,5 @@ """ -Translate between Cohere's `/rerank` format and Deepinfra's `/rerank` format. +Translate between Cohere's `/rerank` format and Deepinfra's `/rerank` format. """ from typing import Any, Dict, List, Optional, Union diff --git a/litellm/llms/deepseek/cost_calculator.py b/litellm/llms/deepseek/cost_calculator.py index 0f4490cb3df..e652ebeac54 100644 --- a/litellm/llms/deepseek/cost_calculator.py +++ b/litellm/llms/deepseek/cost_calculator.py @@ -1,5 +1,5 @@ """ -Cost calculator for DeepSeek Chat models. +Cost calculator for DeepSeek Chat models. Handles prompt caching scenario. """ diff --git a/litellm/llms/elevenlabs/text_to_speech/transformation.py b/litellm/llms/elevenlabs/text_to_speech/transformation.py index 6a59911701b..612fc687ef9 100644 --- a/litellm/llms/elevenlabs/text_to_speech/transformation.py +++ b/litellm/llms/elevenlabs/text_to_speech/transformation.py @@ -22,7 +22,6 @@ from litellm.types.utils import all_litellm_params from ..common_utils import ElevenLabsException - if TYPE_CHECKING: from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj from litellm.types.llms.openai import HttpxBinaryResponseContent diff --git a/litellm/llms/gemini/agents/transformation.py b/litellm/llms/gemini/agents/transformation.py index 150918c4737..f6e0b95cf28 100644 --- a/litellm/llms/gemini/agents/transformation.py +++ b/litellm/llms/gemini/agents/transformation.py @@ -23,7 +23,6 @@ from litellm.types.agents import ( AgentVersionsResponse, ) - # Keys inside litellm_params that should be forwarded to the Gemini # create-agent body verbatim. _GEMINI_AGENT_BODY_KEYS = ("base_agent", "instructions", "base_environment") diff --git a/litellm/llms/gemini/videos/transformation.py b/litellm/llms/gemini/videos/transformation.py index c7116940b22..9714c8a3923 100644 --- a/litellm/llms/gemini/videos/transformation.py +++ b/litellm/llms/gemini/videos/transformation.py @@ -55,7 +55,7 @@ def _convert_image_to_gemini_format(image_file) -> Dict[str, str]: def _usage_video_resolution_from_parameters( - parameters: Dict[str, Any] + parameters: Dict[str, Any], ) -> Optional[str]: """Normalize Veo ``parameters.resolution`` for usage and cost tracking.""" res = parameters.get("resolution") diff --git a/litellm/llms/infinity/rerank/transformation.py b/litellm/llms/infinity/rerank/transformation.py index 314bf2f8a36..b9804605454 100644 --- a/litellm/llms/infinity/rerank/transformation.py +++ b/litellm/llms/infinity/rerank/transformation.py @@ -1,5 +1,5 @@ """ -Transformation logic from Cohere's /v1/rerank format to Infinity's `/v1/rerank` format. +Transformation logic from Cohere's /v1/rerank format to Infinity's `/v1/rerank` format. Why separate file? Make it easy to see how transformation works """ diff --git a/litellm/llms/jina_ai/rerank/transformation.py b/litellm/llms/jina_ai/rerank/transformation.py index ad4416925a6..56be754fc34 100644 --- a/litellm/llms/jina_ai/rerank/transformation.py +++ b/litellm/llms/jina_ai/rerank/transformation.py @@ -1,5 +1,5 @@ """ -Transformation logic from Cohere's /v1/rerank format to Jina AI's `/v1/rerank` format. +Transformation logic from Cohere's /v1/rerank format to Jina AI's `/v1/rerank` format. Why separate file? Make it easy to see how transformation works diff --git a/litellm/llms/lm_studio/embed/transformation.py b/litellm/llms/lm_studio/embed/transformation.py index 1285550c30f..87f4f6e73d5 100644 --- a/litellm/llms/lm_studio/embed/transformation.py +++ b/litellm/llms/lm_studio/embed/transformation.py @@ -1,5 +1,5 @@ """ -Transformation logic from OpenAI /v1/embeddings format to LM Studio's `/v1/embeddings` format. +Transformation logic from OpenAI /v1/embeddings format to LM Studio's `/v1/embeddings` format. Why separate file? Make it easy to see how transformation works diff --git a/litellm/llms/novita/chat/transformation.py b/litellm/llms/novita/chat/transformation.py index c05d2d7b2c5..5a64a124ade 100644 --- a/litellm/llms/novita/chat/transformation.py +++ b/litellm/llms/novita/chat/transformation.py @@ -1,5 +1,5 @@ """ -Support for OpenAI's `/v1/chat/completions` endpoint. +Support for OpenAI's `/v1/chat/completions` endpoint. Calls done in OpenAI/openai.py as Novita AI is openai-compatible. diff --git a/litellm/llms/nvidia_nim/chat/transformation.py b/litellm/llms/nvidia_nim/chat/transformation.py index b8f8b04eb53..2ef92a90626 100644 --- a/litellm/llms/nvidia_nim/chat/transformation.py +++ b/litellm/llms/nvidia_nim/chat/transformation.py @@ -1,7 +1,7 @@ """ -Nvidia NIM endpoint: https://docs.api.nvidia.com/nim/reference/databricks-dbrx-instruct-infer +Nvidia NIM endpoint: https://docs.api.nvidia.com/nim/reference/databricks-dbrx-instruct-infer -This is OpenAI compatible +This is OpenAI compatible This file only contains param mapping logic diff --git a/litellm/llms/nvidia_nim/embed.py b/litellm/llms/nvidia_nim/embed.py index 24c6cc34e4d..61c8e8244e4 100644 --- a/litellm/llms/nvidia_nim/embed.py +++ b/litellm/llms/nvidia_nim/embed.py @@ -1,7 +1,7 @@ """ Nvidia NIM embeddings endpoint: https://docs.api.nvidia.com/nim/reference/nvidia-nv-embedqa-e5-v5-infer -This is OpenAI compatible +This is OpenAI compatible This file only contains param mapping logic diff --git a/litellm/llms/openai/chat/o_series_transformation.py b/litellm/llms/openai/chat/o_series_transformation.py index 02ae2cc9750..8db7ecf7b3a 100644 --- a/litellm/llms/openai/chat/o_series_transformation.py +++ b/litellm/llms/openai/chat/o_series_transformation.py @@ -1,14 +1,14 @@ """ -Support for o1/o3 model family +Support for o1/o3 model family https://platform.openai.com/docs/guides/reasoning Translations handled by LiteLLM: -- modalities: image => drop param (if user opts in to dropping param) -- role: system ==> translate to role 'user' -- streaming => faked by LiteLLM -- Tools, response_format => drop param (if user opts in to dropping param) -- Logprobs => drop param (if user opts in to dropping param) +- modalities: image => drop param (if user opts in to dropping param) +- role: system ==> translate to role 'user' +- streaming => faked by LiteLLM +- Tools, response_format => drop param (if user opts in to dropping param) +- Logprobs => drop param (if user opts in to dropping param) """ from typing import Any, Coroutine, List, Literal, Optional, Union, cast, overload diff --git a/litellm/llms/openai/common_utils.py b/litellm/llms/openai/common_utils.py index c13a976c1b9..381f215a13f 100644 --- a/litellm/llms/openai/common_utils.py +++ b/litellm/llms/openai/common_utils.py @@ -201,7 +201,7 @@ class BaseOpenAILLM: @staticmethod def get_openai_client_initialization_param_fields( - client_type: Literal["openai", "azure"] + client_type: Literal["openai", "azure"], ) -> Tuple[str, ...]: """Returns a tuple of fields that are used to initialize the OpenAI client""" if client_type == "openai": diff --git a/litellm/llms/openrouter/image_generation/transformation.py b/litellm/llms/openrouter/image_generation/transformation.py index a55716a5e50..9c2293eb3f1 100644 --- a/litellm/llms/openrouter/image_generation/transformation.py +++ b/litellm/llms/openrouter/image_generation/transformation.py @@ -49,7 +49,6 @@ from litellm.types.utils import ( ) from litellm.llms.openrouter.common_utils import OpenRouterException - if TYPE_CHECKING: from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj else: diff --git a/litellm/llms/sagemaker/completion/transformation.py b/litellm/llms/sagemaker/completion/transformation.py index 3e4e2460cdb..8fd32bc4460 100644 --- a/litellm/llms/sagemaker/completion/transformation.py +++ b/litellm/llms/sagemaker/completion/transformation.py @@ -1,7 +1,7 @@ """ Translate from OpenAI's `/v1/chat/completions` to Sagemaker's `/invoke` -In the Huggingface TGI format. +In the Huggingface TGI format. """ import json diff --git a/litellm/llms/sagemaker/embedding/transformation.py b/litellm/llms/sagemaker/embedding/transformation.py index 04430171187..09bdb9295e7 100644 --- a/litellm/llms/sagemaker/embedding/transformation.py +++ b/litellm/llms/sagemaker/embedding/transformation.py @@ -1,7 +1,7 @@ """ Translate from OpenAI's `/v1/embeddings` to Sagemaker's `/invoke` -In the Huggingface TGI format. +In the Huggingface TGI format. """ from typing import TYPE_CHECKING, Any, List, Optional, Union diff --git a/litellm/llms/sap/credentials.py b/litellm/llms/sap/credentials.py index 0ae351783e8..dd307ddf496 100644 --- a/litellm/llms/sap/credentials.py +++ b/litellm/llms/sap/credentials.py @@ -207,7 +207,7 @@ def resolve_resource_group(sources: List[Source]) -> Optional[str]: def _parse_service_key_once( - service_key: Optional[Union[str, dict]] + service_key: Optional[Union[str, dict]], ) -> Optional[Dict[str, Any]]: """ Pre-parse service_key if it's a string to avoid repeated JSON parsing. diff --git a/litellm/llms/snowflake/chat/transformation.py b/litellm/llms/snowflake/chat/transformation.py index 3e590680a75..23bb6f44757 100644 --- a/litellm/llms/snowflake/chat/transformation.py +++ b/litellm/llms/snowflake/chat/transformation.py @@ -14,7 +14,6 @@ from ...openai_like.chat.transformation import OpenAIGPTConfig from ..utils import SnowflakeBaseConfig - if TYPE_CHECKING: from litellm.litellm_core_utils.litellm_logging import Logging as _LiteLLMLoggingObj diff --git a/litellm/llms/together_ai/chat.py b/litellm/llms/together_ai/chat.py index 7efb12fc1b2..238849cc1ec 100644 --- a/litellm/llms/together_ai/chat.py +++ b/litellm/llms/together_ai/chat.py @@ -1,5 +1,5 @@ """ -Support for OpenAI's `/v1/chat/completions` endpoint. +Support for OpenAI's `/v1/chat/completions` endpoint. Calls done in OpenAI/openai.py as TogetherAI is openai-compatible. diff --git a/litellm/llms/together_ai/embed.py b/litellm/llms/together_ai/embed.py index 577df0256cc..6a39b94acfc 100644 --- a/litellm/llms/together_ai/embed.py +++ b/litellm/llms/together_ai/embed.py @@ -1,5 +1,5 @@ """ -Support for OpenAI's `/v1/embeddings` endpoint. +Support for OpenAI's `/v1/embeddings` endpoint. Calls done in OpenAI/openai.py as TogetherAI is openai-compatible. diff --git a/litellm/llms/together_ai/rerank/transformation.py b/litellm/llms/together_ai/rerank/transformation.py index 63b593dfe42..f4d642bd25a 100644 --- a/litellm/llms/together_ai/rerank/transformation.py +++ b/litellm/llms/together_ai/rerank/transformation.py @@ -1,5 +1,5 @@ """ -Transformation logic from Cohere's /v1/rerank format to Together AI's `/v1/rerank` format. +Transformation logic from Cohere's /v1/rerank format to Together AI's `/v1/rerank` format. Why separate file? Make it easy to see how transformation works """ diff --git a/litellm/llms/vertex_ai/context_caching/transformation.py b/litellm/llms/vertex_ai/context_caching/transformation.py index 3d532113ba0..f73eb220cc6 100644 --- a/litellm/llms/vertex_ai/context_caching/transformation.py +++ b/litellm/llms/vertex_ai/context_caching/transformation.py @@ -1,5 +1,5 @@ """ -Transformation logic for context caching. +Transformation logic for context caching. Why separate file? Make it easy to see how transformation works """ @@ -19,7 +19,7 @@ from ..gemini.transformation import ( def get_first_continuous_block_idx( - filtered_messages: List[Tuple[int, AllMessageValues]] # (idx, message) + filtered_messages: List[Tuple[int, AllMessageValues]], # (idx, message) ) -> int: """ Find the array index that ends the first continuous sequence of message blocks. diff --git a/litellm/llms/vertex_ai/gemini/transformation.py b/litellm/llms/vertex_ai/gemini/transformation.py index 2995edd1e07..4f5846cc5b6 100644 --- a/litellm/llms/vertex_ai/gemini/transformation.py +++ b/litellm/llms/vertex_ai/gemini/transformation.py @@ -1073,16 +1073,14 @@ def _gemini_convert_messages_with_history( # noqa: PLR0915 contents.append(ContentType(role="user", parts=tool_call_responses)) if len(contents) == 0: - verbose_logger.warning( - """ + verbose_logger.warning(""" No contents in messages. Contents are required. See https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.publishers.models/generateContent#request-body. If the original request did not comply to OpenAI API requirements it should have failed by now, but LiteLLM does not check for missing messages. Setting an empty content to prevent an 400 error. Relevant Issue - https://github.com/BerriAI/litellm/issues/9733 - """ - ) + """) contents.append(ContentType(role="user", parts=[PartType(text=" ")])) return contents except Exception as e: diff --git a/litellm/llms/vertex_ai/gemini_embeddings/batch_embed_content_transformation.py b/litellm/llms/vertex_ai/gemini_embeddings/batch_embed_content_transformation.py index e1b365c9f42..ba6e6f0c056 100644 --- a/litellm/llms/vertex_ai/gemini_embeddings/batch_embed_content_transformation.py +++ b/litellm/llms/vertex_ai/gemini_embeddings/batch_embed_content_transformation.py @@ -1,5 +1,5 @@ """ -Transformation logic from OpenAI /v1/embeddings format to Google AI Studio /batchEmbedContents format. +Transformation logic from OpenAI /v1/embeddings format to Google AI Studio /batchEmbedContents format. Why separate file? Make it easy to see how transformation works """ diff --git a/litellm/llms/vertex_ai/text_to_speech/text_to_speech_handler.py b/litellm/llms/vertex_ai/text_to_speech/text_to_speech_handler.py index 9d9015c2b91..b835ad7d8fa 100644 --- a/litellm/llms/vertex_ai/text_to_speech/text_to_speech_handler.py +++ b/litellm/llms/vertex_ai/text_to_speech/text_to_speech_handler.py @@ -139,7 +139,7 @@ class VertexTextToSpeechAPI(VertexLLM): ########## End of logging ############ ####### Send the request ################### if _is_async is True: - return self.async_audio_speech( # type:ignore + return self.async_audio_speech( # type: ignore logging_obj=logging_obj, url=url, headers=headers, request=request ) sync_handler = _get_httpx_client() diff --git a/litellm/llms/vllm/completion/transformation.py b/litellm/llms/vllm/completion/transformation.py index ec4c07e95d8..e03b07f9897 100644 --- a/litellm/llms/vllm/completion/transformation.py +++ b/litellm/llms/vllm/completion/transformation.py @@ -1,5 +1,5 @@ """ -Translates from OpenAI's `/v1/chat/completions` to the VLLM sdk `llm.generate`. +Translates from OpenAI's `/v1/chat/completions` to the VLLM sdk `llm.generate`. NOT RECOMMENDED FOR PRODUCTION USE. Use `hosted_vllm/` instead. """ diff --git a/litellm/llms/voyage/embedding/transformation_contextual.py b/litellm/llms/voyage/embedding/transformation_contextual.py index 40328062e09..1f5ca99f47d 100644 --- a/litellm/llms/voyage/embedding/transformation_contextual.py +++ b/litellm/llms/voyage/embedding/transformation_contextual.py @@ -1,6 +1,6 @@ """ -This module is used to transform the request and response for the Voyage contextualized embeddings API. -This would be used for all the contextualized embeddings models in Voyage. +This module is used to transform the request and response for the Voyage contextualized embeddings API. +This would be used for all the contextualized embeddings models in Voyage. """ from typing import List, Optional, Union diff --git a/litellm/proxy/_experimental/mcp_server/openapi_to_mcp_generator.py b/litellm/proxy/_experimental/mcp_server/openapi_to_mcp_generator.py index 271517bb1e6..de70fe1331e 100644 --- a/litellm/proxy/_experimental/mcp_server/openapi_to_mcp_generator.py +++ b/litellm/proxy/_experimental/mcp_server/openapi_to_mcp_generator.py @@ -305,7 +305,7 @@ def build_input_schema(operation: Dict[str, Any]) -> Dict[str, Any]: def _merge_openapi_tool_request_headers( - static_headers: Dict[str, str] + static_headers: Dict[str, str], ) -> Dict[str, str]: """Merge static closure headers with per-request ContextVar overrides. diff --git a/litellm/proxy/auth/model_checks.py b/litellm/proxy/auth/model_checks.py index dea79d84250..d364b52c676 100644 --- a/litellm/proxy/auth/model_checks.py +++ b/litellm/proxy/auth/model_checks.py @@ -11,7 +11,6 @@ from litellm.router_utils.fallback_event_handlers import get_fallback_model_grou from litellm.types.router import CredentialLiteLLMParams, LiteLLM_Params from litellm.utils import get_valid_models - _CREDENTIAL_LITELLM_PARAM_FIELDS = set(CredentialLiteLLMParams.model_fields) diff --git a/litellm/proxy/common_utils/custom_openapi_spec.py b/litellm/proxy/common_utils/custom_openapi_spec.py index a93749c3952..fa3cb02195b 100644 --- a/litellm/proxy/common_utils/custom_openapi_spec.py +++ b/litellm/proxy/common_utils/custom_openapi_spec.py @@ -324,7 +324,7 @@ class CustomOpenAPISpec: @staticmethod def add_chat_completion_request_schema( - openapi_schema: Dict[str, Any] + openapi_schema: Dict[str, Any], ) -> Dict[str, Any]: """ Add ProxyChatCompletionRequest schema to chat completion endpoints for documentation. @@ -380,7 +380,7 @@ class CustomOpenAPISpec: @staticmethod def add_responses_api_request_schema( - openapi_schema: Dict[str, Any] + openapi_schema: Dict[str, Any], ) -> Dict[str, Any]: """ Add ResponsesAPIRequestParams schema to responses API endpoints for documentation. @@ -410,7 +410,7 @@ class CustomOpenAPISpec: @staticmethod def add_llm_api_request_schema_body( - openapi_schema: Dict[str, Any] + openapi_schema: Dict[str, Any], ) -> Dict[str, Any]: """ Add LLM API request schema bodies to OpenAPI specification for documentation. diff --git a/litellm/proxy/common_utils/http_parsing_utils.py b/litellm/proxy/common_utils/http_parsing_utils.py index fecfc1b4714..2ce3fda6297 100644 --- a/litellm/proxy/common_utils/http_parsing_utils.py +++ b/litellm/proxy/common_utils/http_parsing_utils.py @@ -12,7 +12,6 @@ from litellm.proxy.common_utils.callback_utils import ( ) from litellm.types.router import Deployment - _FORM_CONTENT_TYPES: frozenset[str] = frozenset( {"application/x-www-form-urlencoded", "multipart/form-data"} ) @@ -301,7 +300,7 @@ async def get_form_data(request: Request) -> Dict[str, Any]: async def convert_upload_files_to_file_data( - form_data: Dict[str, Any] + form_data: Dict[str, Any], ) -> Dict[str, Any]: """ Convert FastAPI UploadFile objects to file data tuples for litellm. diff --git a/litellm/proxy/common_utils/openai_endpoint_utils.py b/litellm/proxy/common_utils/openai_endpoint_utils.py index c4bfe11aec1..905967fa465 100644 --- a/litellm/proxy/common_utils/openai_endpoint_utils.py +++ b/litellm/proxy/common_utils/openai_endpoint_utils.py @@ -1,5 +1,5 @@ """ -Contains utils used by OpenAI compatible endpoints +Contains utils used by OpenAI compatible endpoints """ from typing import Optional, Set diff --git a/litellm/proxy/config_management_endpoints/pass_through_endpoints.py b/litellm/proxy/config_management_endpoints/pass_through_endpoints.py index 5ff02b8bce0..4ebd989dc53 100644 --- a/litellm/proxy/config_management_endpoints/pass_through_endpoints.py +++ b/litellm/proxy/config_management_endpoints/pass_through_endpoints.py @@ -1,5 +1,5 @@ """ -What is this? +What is this? CRUD endpoints for managing pass-through endpoints """ diff --git a/litellm/proxy/db/create_views.py b/litellm/proxy/db/create_views.py index d84cebcf05a..97525a528d0 100644 --- a/litellm/proxy/db/create_views.py +++ b/litellm/proxy/db/create_views.py @@ -34,8 +34,7 @@ async def create_missing_views(db: _db): # noqa: PLR0915 if not any(marker in error_msg for marker in _VIEW_NOT_FOUND_MARKERS): raise # If an error occurs, the view does not exist, so create it - await db.execute_raw( - """ + await db.execute_raw(""" CREATE VIEW "LiteLLM_VerificationTokenView" AS SELECT v.*, @@ -47,8 +46,7 @@ async def create_missing_views(db: _db): # noqa: PLR0915 FROM "LiteLLM_VerificationToken" v LEFT JOIN "LiteLLM_TeamTable" t ON v.team_id = t.team_id LEFT JOIN "LiteLLM_ProjectTable" p ON v.project_id = p.project_id; - """ - ) + """) verbose_logger.debug("LiteLLM_VerificationTokenView Created!") diff --git a/litellm/proxy/guardrails/_content_utils.py b/litellm/proxy/guardrails/_content_utils.py index 7cad1352a79..766ef0cf9f6 100644 --- a/litellm/proxy/guardrails/_content_utils.py +++ b/litellm/proxy/guardrails/_content_utils.py @@ -10,7 +10,6 @@ every text fragment. from typing import Any, Callable, Dict, FrozenSet, Iterator, List - # Call types whose body carries free-form chat / prompt text that # text-content guardrails (banned keywords, content moderation, secret # detection, …) should inspect. The proxy ingress passes ``route_type`` diff --git a/litellm/proxy/guardrails/guardrail_hooks/akto/__init__.py b/litellm/proxy/guardrails/guardrail_hooks/akto/__init__.py index c4aaea709ba..1e3dd906b9f 100644 --- a/litellm/proxy/guardrails/guardrail_hooks/akto/__init__.py +++ b/litellm/proxy/guardrails/guardrail_hooks/akto/__init__.py @@ -4,7 +4,6 @@ from litellm.types.guardrails import SupportedGuardrailIntegrations from .akto import AktoGuardrail - if TYPE_CHECKING: from litellm.types.guardrails import Guardrail, LitellmParams diff --git a/litellm/proxy/hooks/litellm_skills/__init__.py b/litellm/proxy/hooks/litellm_skills/__init__.py index 057cf3d8b38..1507b652ab4 100644 --- a/litellm/proxy/hooks/litellm_skills/__init__.py +++ b/litellm/proxy/hooks/litellm_skills/__init__.py @@ -6,7 +6,7 @@ The actual skill logic is in litellm/llms/litellm_proxy/skills/. Usage: from litellm.proxy.hooks.litellm_skills import SkillsInjectionHook - + # Register hook in proxy litellm.callbacks.append(SkillsInjectionHook()) """ diff --git a/litellm/proxy/management_endpoints/budget_management_endpoints.py b/litellm/proxy/management_endpoints/budget_management_endpoints.py index 60dc7827a6f..2eda1b30c5d 100644 --- a/litellm/proxy/management_endpoints/budget_management_endpoints.py +++ b/litellm/proxy/management_endpoints/budget_management_endpoints.py @@ -1,9 +1,9 @@ """ BUDGET MANAGEMENT -All /budget management endpoints +All /budget management endpoints -/budget/new +/budget/new /budget/info /budget/update /budget/delete diff --git a/litellm/proxy/management_endpoints/customer_endpoints.py b/litellm/proxy/management_endpoints/customer_endpoints.py index 4889f0b7f80..1fd8320db20 100644 --- a/litellm/proxy/management_endpoints/customer_endpoints.py +++ b/litellm/proxy/management_endpoints/customer_endpoints.py @@ -1,9 +1,9 @@ """ CUSTOMER MANAGEMENT -All /customer management endpoints +All /customer management endpoints -/customer/new +/customer/new /customer/info /customer/update /customer/delete diff --git a/litellm/proxy/management_endpoints/model_management_endpoints.py b/litellm/proxy/management_endpoints/model_management_endpoints.py index 472306eb818..f2d8ec8fb55 100644 --- a/litellm/proxy/management_endpoints/model_management_endpoints.py +++ b/litellm/proxy/management_endpoints/model_management_endpoints.py @@ -546,7 +546,7 @@ async def _update_existing_team_model_assignment( """ def _get_team_public_model_name( - model_info: Optional[Union[dict, str]] + model_info: Optional[Union[dict, str]], ) -> Optional[str]: if isinstance(model_info, dict): value = model_info.get("team_public_model_name") diff --git a/litellm/proxy/management_endpoints/sso/custom_microsoft_sso.py b/litellm/proxy/management_endpoints/sso/custom_microsoft_sso.py index 191212d6f0b..04e44c623d1 100644 --- a/litellm/proxy/management_endpoints/sso/custom_microsoft_sso.py +++ b/litellm/proxy/management_endpoints/sso/custom_microsoft_sso.py @@ -7,7 +7,7 @@ variables. Environment Variables: - MICROSOFT_AUTHORIZATION_ENDPOINT: Custom authorization endpoint URL -- MICROSOFT_TOKEN_ENDPOINT: Custom token endpoint URL +- MICROSOFT_TOKEN_ENDPOINT: Custom token endpoint URL - MICROSOFT_USERINFO_ENDPOINT: Custom userinfo endpoint URL If these are not set, the default Microsoft endpoints are used. diff --git a/litellm/proxy/management_endpoints/team_endpoints.py b/litellm/proxy/management_endpoints/team_endpoints.py index 86c4d6dcd9a..0b2f93d817a 100644 --- a/litellm/proxy/management_endpoints/team_endpoints.py +++ b/litellm/proxy/management_endpoints/team_endpoints.py @@ -4381,9 +4381,7 @@ async def list_team( except Exception as e: team_exception = """Invalid team object for team_id: {}. team_object={}. Error: {} - """.format( - team.team_id, team.model_dump(), str(e) - ) + """.format(team.team_id, team.model_dump(), str(e)) verbose_proxy_logger.exception(team_exception) continue # Sort the responses by team_alias diff --git a/litellm/proxy/management_endpoints/user_agent_analytics_endpoints.py b/litellm/proxy/management_endpoints/user_agent_analytics_endpoints.py index 872b6fa2250..ebd276fbee5 100644 --- a/litellm/proxy/management_endpoints/user_agent_analytics_endpoints.py +++ b/litellm/proxy/management_endpoints/user_agent_analytics_endpoints.py @@ -3,7 +3,7 @@ User Agent Analytics Endpoints This module provides optimized endpoints for tracking user agent activity metrics including: - Daily Active Users (DAU) by tags for configurable number of days -- Weekly Active Users (WAU) by tags for configurable number of weeks +- Weekly Active Users (WAU) by tags for configurable number of weeks - Monthly Active Users (MAU) by tags for configurable number of months - Summary analytics by tags diff --git a/litellm/proxy/pass_through_endpoints/llm_provider_handlers/cursor_passthrough_logging_handler.py b/litellm/proxy/pass_through_endpoints/llm_provider_handlers/cursor_passthrough_logging_handler.py index a104f962630..e7696e5a18a 100644 --- a/litellm/proxy/pass_through_endpoints/llm_provider_handlers/cursor_passthrough_logging_handler.py +++ b/litellm/proxy/pass_through_endpoints/llm_provider_handlers/cursor_passthrough_logging_handler.py @@ -18,7 +18,6 @@ from litellm.litellm_core_utils.litellm_logging import ( from litellm.proxy._types import PassThroughEndpointLoggingTypedDict from litellm.types.utils import StandardPassThroughResponseObject - CURSOR_AGENT_ENDPOINTS: Dict[str, str] = { "POST /v0/agents": "cursor:agent:create", "GET /v0/agents": "cursor:agent:list", diff --git a/litellm/proxy/proxy_cli.py b/litellm/proxy/proxy_cli.py index 37bab3a45d0..e4c5dabb50b 100644 --- a/litellm/proxy/proxy_cli.py +++ b/litellm/proxy/proxy_cli.py @@ -321,9 +321,7 @@ class ProxyInitializationHelpers: _endpoint_str = ( f"curl --location 'http://0.0.0.0:{port}/chat/completions' \\" ) - curl_command = ( - _endpoint_str - + """ + curl_command = _endpoint_str + """ --header 'Content-Type: application/json' \\ --data ' { "model": "gpt-3.5-turbo", @@ -336,7 +334,6 @@ class ProxyInitializationHelpers: }' \n """ - ) print() # noqa print( # noqa '\033[1;34mLiteLLM: Test your local proxy with: "litellm --test" This runs an openai.ChatCompletion request to your proxy [In a new terminal tab]\033[0m\n' @@ -412,11 +409,9 @@ class ProxyInitializationHelpers: with open(os.devnull, "w") as devnull: subprocess.Popen(command, stdout=devnull, stderr=devnull) except Exception as e: - print( # noqa - f""" + print(f""" LiteLLM Warning: proxy started with `ollama` model\n`ollama serve` failed with Exception{e}. \nEnsure you run `ollama serve` - """ - ) # noqa + """) # noqa # noqa @staticmethod def _is_port_in_use(port): diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 3d558ede9f1..759534a32a1 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -2710,11 +2710,9 @@ def run_ollama_serve(): with open(os.devnull, "w") as devnull: subprocess.Popen(command, stdout=devnull, stderr=devnull) except Exception as e: - verbose_proxy_logger.debug( - f""" + verbose_proxy_logger.debug(f""" LiteLLM Warning: proxy started with `ollama` model\n`ollama serve` failed with Exception{e}. \nEnsure you run `ollama serve` - """ - ) + """) def _get_process_rss_mb() -> Optional[float]: diff --git a/litellm/proxy/spend_tracking/spend_management_endpoints.py b/litellm/proxy/spend_tracking/spend_management_endpoints.py index d030fabe8b5..e3019801aae 100644 --- a/litellm/proxy/spend_tracking/spend_management_endpoints.py +++ b/litellm/proxy/spend_tracking/spend_management_endpoints.py @@ -3184,16 +3184,14 @@ async def provider_budgets() -> ProviderBudgetResponse: async def get_spend_by_tags( prisma_client: PrismaClient, start_date=None, end_date=None ): - response = await prisma_client.db.query_raw( - """ + response = await prisma_client.db.query_raw(""" SELECT jsonb_array_elements_text(request_tags) AS individual_request_tag, COUNT(*) AS log_count, SUM(spend) AS total_spend FROM "LiteLLM_SpendLogs" GROUP BY individual_request_tag; - """ - ) + """) return response diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py index 36fd605cf72..032ab6c63b2 100644 --- a/litellm/proxy/utils.py +++ b/litellm/proxy/utils.py @@ -2979,8 +2979,7 @@ class PrismaClient: required_view = "LiteLLM_VerificationTokenView" expected_views_str = ", ".join(f"'{view}'" for view in expected_views) pg_schema = os.getenv("DATABASE_SCHEMA", "public") - ret = await self.db.query_raw( - f""" + ret = await self.db.query_raw(f""" WITH existing_views AS ( SELECT viewname FROM pg_views @@ -2992,8 +2991,7 @@ class PrismaClient: (SELECT COUNT(*) FROM existing_views) AS view_count, ARRAY_AGG(viewname) AS view_names FROM existing_views - """ - ) + """) expected_total_views = len(expected_views) if ret[0]["view_count"] == expected_total_views: verbose_proxy_logger.info("All necessary views exist!") @@ -3002,8 +3000,7 @@ class PrismaClient: ## check if required view exists ## if ret[0]["view_names"] and required_view not in ret[0]["view_names"]: await self.health_check() # make sure we can connect to db - await self.db.execute_raw( - """ + await self.db.execute_raw(""" CREATE VIEW "LiteLLM_VerificationTokenView" AS SELECT v.*, @@ -3013,8 +3010,7 @@ class PrismaClient: t.rpm_limit AS team_rpm_limit FROM "LiteLLM_VerificationToken" v LEFT JOIN "LiteLLM_TeamTable" t ON v.team_id = t.team_id; - """ - ) + """) verbose_proxy_logger.info( "LiteLLM_VerificationTokenView Created in DB!" diff --git a/litellm/proxy/vertex_ai_endpoints/langfuse_endpoints.py b/litellm/proxy/vertex_ai_endpoints/langfuse_endpoints.py index 8ce1bedcf90..b47f6a747db 100644 --- a/litellm/proxy/vertex_ai_endpoints/langfuse_endpoints.py +++ b/litellm/proxy/vertex_ai_endpoints/langfuse_endpoints.py @@ -1,5 +1,5 @@ """ -What is this? +What is this? Logging Pass-Through Endpoints """ diff --git a/litellm/router.py b/litellm/router.py index 29025ad1437..debccb0e83f 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -848,7 +848,7 @@ class Router: @staticmethod def _normalize_strategy( - strategy: Union[RoutingStrategy, str, None] + strategy: Union[RoutingStrategy, str, None], ) -> Optional[str]: if strategy is None: return None diff --git a/litellm/router_strategy/adaptive_router/hooks.py b/litellm/router_strategy/adaptive_router/hooks.py index 9e346006ac1..99fe5e26f7f 100644 --- a/litellm/router_strategy/adaptive_router/hooks.py +++ b/litellm/router_strategy/adaptive_router/hooks.py @@ -103,7 +103,7 @@ def _last_user_content(messages: Optional[List[Dict[str, Any]]]) -> Optional[str def _recent_tool_results( - messages: Optional[List[Dict[str, Any]]] + messages: Optional[List[Dict[str, Any]]], ) -> List[Dict[str, Any]]: """Extract the current turn's tool result payloads from the request messages. diff --git a/litellm/router_strategy/adaptive_router/signals.py b/litellm/router_strategy/adaptive_router/signals.py index a48bdea1eb6..5e33a64d27f 100644 --- a/litellm/router_strategy/adaptive_router/signals.py +++ b/litellm/router_strategy/adaptive_router/signals.py @@ -24,7 +24,6 @@ from litellm.router_strategy.adaptive_router.config import ( TOOL_CALL_HISTORY_MAX, ) - # ---- Public types --------------------------------------------------------- diff --git a/litellm/router_strategy/budget_limiter.py b/litellm/router_strategy/budget_limiter.py index be27b852478..da41577e99a 100644 --- a/litellm/router_strategy/budget_limiter.py +++ b/litellm/router_strategy/budget_limiter.py @@ -10,11 +10,11 @@ This means you can use this with weighted-pick, lowest-latency, simple-shuffle, Example: ``` openai: - budget_limit: 0.000000000001 - time_period: 1d + budget_limit: 0.000000000001 + time_period: 1d anthropic: - budget_limit: 100 - time_period: 7d + budget_limit: 100 + time_period: 7d ``` """ diff --git a/litellm/router_utils/get_retry_from_policy.py b/litellm/router_utils/get_retry_from_policy.py index ec326ebb50d..162d6428f85 100644 --- a/litellm/router_utils/get_retry_from_policy.py +++ b/litellm/router_utils/get_retry_from_policy.py @@ -1,5 +1,5 @@ """ -Get num retries for an exception. +Get num retries for an exception. - Account for retry policy by exception type. """ diff --git a/litellm/router_utils/pattern_match_deployments.py b/litellm/router_utils/pattern_match_deployments.py index 17b453d6031..48f85a83411 100644 --- a/litellm/router_utils/pattern_match_deployments.py +++ b/litellm/router_utils/pattern_match_deployments.py @@ -34,7 +34,7 @@ class PatternUtils: @staticmethod def sorted_patterns( - patterns: Dict[str, List[Dict]] + patterns: Dict[str, List[Dict]], ) -> List[Tuple[str, List[Dict]]]: """ Cached property for patterns sorted by specificity. diff --git a/litellm/router_utils/router_callbacks/track_deployment_metrics.py b/litellm/router_utils/router_callbacks/track_deployment_metrics.py index 1f226879d03..9039b0df8e6 100644 --- a/litellm/router_utils/router_callbacks/track_deployment_metrics.py +++ b/litellm/router_utils/router_callbacks/track_deployment_metrics.py @@ -1,5 +1,5 @@ """ -Helper functions to get/set num success and num failures per deployment +Helper functions to get/set num success and num failures per deployment set_deployment_failures_for_current_minute diff --git a/litellm/secret_managers/aws_secret_manager.py b/litellm/secret_managers/aws_secret_manager.py index fbe951e6492..60d0a713eff 100644 --- a/litellm/secret_managers/aws_secret_manager.py +++ b/litellm/secret_managers/aws_secret_manager.py @@ -4,7 +4,7 @@ This is a file for the AWS Secret Manager Integration Relevant issue: https://github.com/BerriAI/litellm/issues/1883 Requires: -* `os.environ["AWS_REGION_NAME"], +* `os.environ["AWS_REGION_NAME"], * `pip install boto3>=1.28.57` """ diff --git a/litellm/secret_managers/aws_secret_manager_v2.py b/litellm/secret_managers/aws_secret_manager_v2.py index c1b4d019dcf..4461e34396e 100644 --- a/litellm/secret_managers/aws_secret_manager_v2.py +++ b/litellm/secret_managers/aws_secret_manager_v2.py @@ -10,7 +10,7 @@ Handles Async Operations for: Relevant issue: https://github.com/BerriAI/litellm/issues/1883 Requires: -* `os.environ["AWS_REGION_NAME"], +* `os.environ["AWS_REGION_NAME"], * `pip install boto3>=1.28.57` """ diff --git a/litellm/vector_store_files/utils.py b/litellm/vector_store_files/utils.py index ffe73516bda..1ee5b47e306 100644 --- a/litellm/vector_store_files/utils.py +++ b/litellm/vector_store_files/utils.py @@ -21,7 +21,7 @@ class VectorStoreFileRequestUtils: @staticmethod def get_create_request_params( - params: Dict[str, Any] + params: Dict[str, Any], ) -> VectorStoreFileCreateRequest: filtered = VectorStoreFileRequestUtils._filter_params( params=params, model=VectorStoreFileCreateRequest @@ -37,7 +37,7 @@ class VectorStoreFileRequestUtils: @staticmethod def get_update_request_params( - params: Dict[str, Any] + params: Dict[str, Any], ) -> VectorStoreFileUpdateRequest: filtered = VectorStoreFileRequestUtils._filter_params( params=params, model=VectorStoreFileUpdateRequest diff --git a/pyproject.toml b/pyproject.toml index ea62511fbde..f2686047f3c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -132,7 +132,7 @@ litellm-proxy = "litellm.proxy.client.cli:cli" dev = [ "diff-cover==9.7.2", "flake8==7.3.0", - "black==24.10.0", + "black==26.3.1", "mypy==1.19.0", "pytest==9.0.3", "pytest-mock==3.15.1", diff --git a/tests/code_coverage_tests/liccheck.ini b/tests/code_coverage_tests/liccheck.ini index 3d53ecede7b..0d1a6f0b045 100644 --- a/tests/code_coverage_tests/liccheck.ini +++ b/tests/code_coverage_tests/liccheck.ini @@ -156,6 +156,7 @@ pytest: >=9.0.3 # MIT license pytest-postgresql: >=7.0.2 # LGPLv3+ license pytest-xdist: >=3.8.0 # MIT License ruff: >=0.15.3 # MIT License +black: >=26.3.1 # MIT License manually verified (uses PEP 639 License-Expression: MIT, not the legacy License field, so liccheck reports it as unknown) types-requests: >=2.32.4.20260107 # Apache 2.0 license (typeshed) types-pyyaml: >=6.0.12.20250915 # Apache 2.0 license (typeshed) fakeredis: >=2.34.1 # BSD license diff --git a/uv.lock b/uv.lock index cafb6664958..e99d8d49da6 100644 --- a/uv.lock +++ b/uv.lock @@ -9,7 +9,7 @@ resolution-markers = [ ] [options] -exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. +exclude-newer = "2026-05-19T00:08:46.706629Z" exclude-newer-span = "P3D" [manifest] @@ -539,7 +539,7 @@ wheels = [ [[package]] name = "black" -version = "24.10.0" +version = "26.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -547,28 +547,33 @@ dependencies = [ { name = "packaging" }, { name = "pathspec" }, { name = "platformdirs" }, + { name = "pytokens" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d8/0d/cc2fb42b8c50d80143221515dd7e4766995bd07c56c9a3ed30baf080b6dc/black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875", size = 645813, upload-time = "2024-10-07T19:20:50.361Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/c5/61175d618685d42b005847464b8fb4743a67b1b8fdb75e50e5a96c31a27a/black-26.3.1.tar.gz", hash = "sha256:2c50f5063a9641c7eed7795014ba37b0f5fa227f3d408b968936e24bc0566b07", size = 666155, upload-time = "2026-03-12T03:36:03.593Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/f3/465c0eb5cddf7dbbfe1fecd9b875d1dcf51b88923cd2c1d7e9ab95c6336b/black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812", size = 1623211, upload-time = "2024-10-07T19:26:12.43Z" }, - { url = "https://files.pythonhosted.org/packages/df/57/b6d2da7d200773fdfcc224ffb87052cf283cec4d7102fab450b4a05996d8/black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea", size = 1457139, upload-time = "2024-10-07T19:25:06.453Z" }, - { url = "https://files.pythonhosted.org/packages/6e/c5/9023b7673904a5188f9be81f5e129fff69f51f5515655fbd1d5a4e80a47b/black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:649fff99a20bd06c6f727d2a27f401331dc0cc861fb69cde910fe95b01b5928f", size = 1753774, upload-time = "2024-10-07T19:23:58.47Z" }, - { url = "https://files.pythonhosted.org/packages/e1/32/df7f18bd0e724e0d9748829765455d6643ec847b3f87e77456fc99d0edab/black-24.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe4d6476887de70546212c99ac9bd803d90b42fc4767f058a0baa895013fbb3e", size = 1414209, upload-time = "2024-10-07T19:24:42.54Z" }, - { url = "https://files.pythonhosted.org/packages/c2/cc/7496bb63a9b06a954d3d0ac9fe7a73f3bf1cd92d7a58877c27f4ad1e9d41/black-24.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5a2221696a8224e335c28816a9d331a6c2ae15a2ee34ec857dcf3e45dbfa99ad", size = 1607468, upload-time = "2024-10-07T19:26:14.966Z" }, - { url = "https://files.pythonhosted.org/packages/2b/e3/69a738fb5ba18b5422f50b4f143544c664d7da40f09c13969b2fd52900e0/black-24.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9da3333530dbcecc1be13e69c250ed8dfa67f43c4005fb537bb426e19200d50", size = 1437270, upload-time = "2024-10-07T19:25:24.291Z" }, - { url = "https://files.pythonhosted.org/packages/c9/9b/2db8045b45844665c720dcfe292fdaf2e49825810c0103e1191515fc101a/black-24.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4007b1393d902b48b36958a216c20c4482f601569d19ed1df294a496eb366392", size = 1737061, upload-time = "2024-10-07T19:23:52.18Z" }, - { url = "https://files.pythonhosted.org/packages/a3/95/17d4a09a5be5f8c65aa4a361444d95edc45def0de887810f508d3f65db7a/black-24.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:394d4ddc64782e51153eadcaaca95144ac4c35e27ef9b0a42e121ae7e57a9175", size = 1423293, upload-time = "2024-10-07T19:24:41.7Z" }, - { url = "https://files.pythonhosted.org/packages/90/04/bf74c71f592bcd761610bbf67e23e6a3cff824780761f536512437f1e655/black-24.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e39e0fae001df40f95bd8cc36b9165c5e2ea88900167bddf258bacef9bbdc3", size = 1644256, upload-time = "2024-10-07T19:27:53.355Z" }, - { url = "https://files.pythonhosted.org/packages/4c/ea/a77bab4cf1887f4b2e0bce5516ea0b3ff7d04ba96af21d65024629afedb6/black-24.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d37d422772111794b26757c5b55a3eade028aa3fde43121ab7b673d050949d65", size = 1448534, upload-time = "2024-10-07T19:26:44.953Z" }, - { url = "https://files.pythonhosted.org/packages/4e/3e/443ef8bc1fbda78e61f79157f303893f3fddf19ca3c8989b163eb3469a12/black-24.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b3502784f09ce2443830e3133dacf2c0110d45191ed470ecb04d0f5f6fcb0f", size = 1761892, upload-time = "2024-10-07T19:24:10.264Z" }, - { url = "https://files.pythonhosted.org/packages/52/93/eac95ff229049a6901bc84fec6908a5124b8a0b7c26ea766b3b8a5debd22/black-24.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:30d2c30dc5139211dda799758559d1b049f7f14c580c409d6ad925b74a4208a8", size = 1434796, upload-time = "2024-10-07T19:25:06.239Z" }, - { url = "https://files.pythonhosted.org/packages/d0/a0/a993f58d4ecfba035e61fca4e9f64a2ecae838fc9f33ab798c62173ed75c/black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981", size = 1643986, upload-time = "2024-10-07T19:28:50.684Z" }, - { url = "https://files.pythonhosted.org/packages/37/d5/602d0ef5dfcace3fb4f79c436762f130abd9ee8d950fa2abdbf8bbc555e0/black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b", size = 1448085, upload-time = "2024-10-07T19:28:12.093Z" }, - { url = "https://files.pythonhosted.org/packages/47/6d/a3a239e938960df1a662b93d6230d4f3e9b4a22982d060fc38c42f45a56b/black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2", size = 1760928, upload-time = "2024-10-07T19:24:15.233Z" }, - { url = "https://files.pythonhosted.org/packages/dd/cf/af018e13b0eddfb434df4d9cd1b2b7892bab119f7a20123e93f6910982e8/black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b", size = 1436875, upload-time = "2024-10-07T19:24:42.762Z" }, - { url = "https://files.pythonhosted.org/packages/8d/a7/4b27c50537ebca8bec139b872861f9d2bf501c5ec51fcf897cb924d9e264/black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d", size = 206898, upload-time = "2024-10-07T19:20:48.317Z" }, + { url = "https://files.pythonhosted.org/packages/32/a8/11170031095655d36ebc6664fe0897866f6023892396900eec0e8fdc4299/black-26.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:86a8b5035fce64f5dcd1b794cf8ec4d31fe458cf6ce3986a30deb434df82a1d2", size = 1866562, upload-time = "2026-03-12T03:39:58.639Z" }, + { url = "https://files.pythonhosted.org/packages/69/ce/9e7548d719c3248c6c2abfd555d11169457cbd584d98d179111338423790/black-26.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5602bdb96d52d2d0672f24f6ffe5218795736dd34807fd0fd55ccd6bf206168b", size = 1703623, upload-time = "2026-03-12T03:40:00.347Z" }, + { url = "https://files.pythonhosted.org/packages/7f/0a/8d17d1a9c06f88d3d030d0b1d4373c1551146e252afe4547ed601c0e697f/black-26.3.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c54a4a82e291a1fee5137371ab488866b7c86a3305af4026bdd4dc78642e1ac", size = 1768388, upload-time = "2026-03-12T03:40:01.765Z" }, + { url = "https://files.pythonhosted.org/packages/52/79/c1ee726e221c863cde5164f925bacf183dfdf0397d4e3f94889439b947b4/black-26.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:6e131579c243c98f35bce64a7e08e87fb2d610544754675d4a0e73a070a5aa3a", size = 1412969, upload-time = "2026-03-12T03:40:03.252Z" }, + { url = "https://files.pythonhosted.org/packages/73/a5/15c01d613f5756f68ed8f6d4ec0a1e24b82b18889fa71affd3d1f7fad058/black-26.3.1-cp310-cp310-win_arm64.whl", hash = "sha256:5ed0ca58586c8d9a487352a96b15272b7fa55d139fc8496b519e78023a8dab0a", size = 1220345, upload-time = "2026-03-12T03:40:04.892Z" }, + { url = "https://files.pythonhosted.org/packages/17/57/5f11c92861f9c92eb9dddf515530bc2d06db843e44bdcf1c83c1427824bc/black-26.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:28ef38aee69e4b12fda8dba75e21f9b4f979b490c8ac0baa7cb505369ac9e1ff", size = 1851987, upload-time = "2026-03-12T03:40:06.248Z" }, + { url = "https://files.pythonhosted.org/packages/54/aa/340a1463660bf6831f9e39646bf774086dbd8ca7fc3cded9d59bbdf4ad0a/black-26.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf9bf162ed91a26f1adba8efda0b573bc6924ec1408a52cc6f82cb73ec2b142c", size = 1689499, upload-time = "2026-03-12T03:40:07.642Z" }, + { url = "https://files.pythonhosted.org/packages/f3/01/b726c93d717d72733da031d2de10b92c9fa4c8d0c67e8a8a372076579279/black-26.3.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:474c27574d6d7037c1bc875a81d9be0a9a4f9ee95e62800dab3cfaadbf75acd5", size = 1754369, upload-time = "2026-03-12T03:40:09.279Z" }, + { url = "https://files.pythonhosted.org/packages/e3/09/61e91881ca291f150cfc9eb7ba19473c2e59df28859a11a88248b5cbbc4d/black-26.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:5e9d0d86df21f2e1677cc4bd090cd0e446278bcbbe49bf3659c308c3e402843e", size = 1413613, upload-time = "2026-03-12T03:40:10.943Z" }, + { url = "https://files.pythonhosted.org/packages/16/73/544f23891b22e7efe4d8f812371ab85b57f6a01b2fc45e3ba2e52ba985b8/black-26.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:9a5e9f45e5d5e1c5b5c29b3bd4265dcc90e8b92cf4534520896ed77f791f4da5", size = 1219719, upload-time = "2026-03-12T03:40:12.597Z" }, + { url = "https://files.pythonhosted.org/packages/dc/f8/da5eae4fc75e78e6dceb60624e1b9662ab00d6b452996046dfa9b8a6025b/black-26.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e6f89631eb88a7302d416594a32faeee9fb8fb848290da9d0a5f2903519fc1", size = 1895920, upload-time = "2026-03-12T03:40:13.921Z" }, + { url = "https://files.pythonhosted.org/packages/2c/9f/04e6f26534da2e1629b2b48255c264cabf5eedc5141d04516d9d68a24111/black-26.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cd2012d35b47d589cb8a16faf8a32ef7a336f56356babd9fcf70939ad1897f", size = 1718499, upload-time = "2026-03-12T03:40:15.239Z" }, + { url = "https://files.pythonhosted.org/packages/04/91/a5935b2a63e31b331060c4a9fdb5a6c725840858c599032a6f3aac94055f/black-26.3.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f76ff19ec5297dd8e66eb64deda23631e642c9393ab592826fd4bdc97a4bce7", size = 1794994, upload-time = "2026-03-12T03:40:17.124Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0a/86e462cdd311a3c2a8ece708d22aba17d0b2a0d5348ca34b40cdcbea512e/black-26.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:ddb113db38838eb9f043623ba274cfaf7d51d5b0c22ecb30afe58b1bb8322983", size = 1420867, upload-time = "2026-03-12T03:40:18.83Z" }, + { url = "https://files.pythonhosted.org/packages/5b/e5/22515a19cb7eaee3440325a6b0d95d2c0e88dd180cb011b12ae488e031d1/black-26.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:dfdd51fc3e64ea4f35873d1b3fb25326773d55d2329ff8449139ebaad7357efb", size = 1230124, upload-time = "2026-03-12T03:40:20.425Z" }, + { url = "https://files.pythonhosted.org/packages/f5/77/5728052a3c0450c53d9bb3945c4c46b91baa62b2cafab6801411b6271e45/black-26.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:855822d90f884905362f602880ed8b5df1b7e3ee7d0db2502d4388a954cc8c54", size = 1895034, upload-time = "2026-03-12T03:40:21.813Z" }, + { url = "https://files.pythonhosted.org/packages/52/73/7cae55fdfdfbe9d19e9a8d25d145018965fe2079fa908101c3733b0c55a0/black-26.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8a33d657f3276328ce00e4d37fe70361e1ec7614da5d7b6e78de5426cb56332f", size = 1718503, upload-time = "2026-03-12T03:40:23.666Z" }, + { url = "https://files.pythonhosted.org/packages/e1/87/af89ad449e8254fdbc74654e6467e3c9381b61472cc532ee350d28cfdafb/black-26.3.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f1cd08e99d2f9317292a311dfe578fd2a24b15dbce97792f9c4d752275c1fa56", size = 1793557, upload-time = "2026-03-12T03:40:25.497Z" }, + { url = "https://files.pythonhosted.org/packages/43/10/d6c06a791d8124b843bf325ab4ac7d2f5b98731dff84d6064eafd687ded1/black-26.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:c7e72339f841b5a237ff14f7d3880ddd0fc7f98a1199e8c4327f9a4f478c1839", size = 1422766, upload-time = "2026-03-12T03:40:27.14Z" }, + { url = "https://files.pythonhosted.org/packages/59/4f/40a582c015f2d841ac24fed6390bd68f0fc896069ff3a886317959c9daf8/black-26.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:afc622538b430aa4c8c853f7f63bc582b3b8030fd8c80b70fb5fa5b834e575c2", size = 1232140, upload-time = "2026-03-12T03:40:28.882Z" }, + { url = "https://files.pythonhosted.org/packages/8e/0d/52d98722666d6fc6c3dd4c76df339501d6efd40e0ff95e6186a7b7f0befd/black-26.3.1-py3-none-any.whl", hash = "sha256:2bd5aa94fc267d38bb21a70d7410a89f1a1d318841855f698746f8e7f51acd1b", size = 207542, upload-time = "2026-03-12T03:36:01.668Z" }, ] [[package]] @@ -3484,7 +3489,7 @@ ci = [ { name = "traceloop-sdk", specifier = "==0.33.12" }, ] dev = [ - { name = "black", specifier = "==24.10.0" }, + { name = "black", specifier = "==26.3.1" }, { name = "diff-cover", specifier = "==9.7.2" }, { name = "fakeredis", specifier = "==2.34.1" }, { name = "fastapi-offline", specifier = "==1.7.6" }, @@ -6162,6 +6167,35 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6c/a0/4ed6632b70a52de845df056654162acdebaf97c20e3212c559ac43e7216e/python_ulid-3.1.0-py3-none-any.whl", hash = "sha256:e2cdc979c8c877029b4b7a38a6fba3bc4578e4f109a308419ff4d3ccf0a46619", size = 11577, upload-time = "2025-08-18T16:09:25.047Z" }, ] +[[package]] +name = "pytokens" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/34/b4e015b99031667a7b960f888889c5bd34ef585c85e1cb56a594b92836ac/pytokens-0.4.1.tar.gz", hash = "sha256:292052fe80923aae2260c073f822ceba21f3872ced9a68bb7953b348e561179a", size = 23015, upload-time = "2026-01-30T01:03:45.924Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/24/f206113e05cb8ef51b3850e7ef88f20da6f4bf932190ceb48bd3da103e10/pytokens-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a44ed93ea23415c54f3face3b65ef2b844d96aeb3455b8a69b3df6beab6acc5", size = 161522, upload-time = "2026-01-30T01:02:50.393Z" }, + { url = "https://files.pythonhosted.org/packages/d4/e9/06a6bf1b90c2ed81a9c7d2544232fe5d2891d1cd480e8a1809ca354a8eb2/pytokens-0.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:add8bf86b71a5d9fb5b89f023a80b791e04fba57960aa790cc6125f7f1d39dfe", size = 246945, upload-time = "2026-01-30T01:02:52.399Z" }, + { url = "https://files.pythonhosted.org/packages/69/66/f6fb1007a4c3d8b682d5d65b7c1fb33257587a5f782647091e3408abe0b8/pytokens-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:670d286910b531c7b7e3c0b453fd8156f250adb140146d234a82219459b9640c", size = 259525, upload-time = "2026-01-30T01:02:53.737Z" }, + { url = "https://files.pythonhosted.org/packages/04/92/086f89b4d622a18418bac74ab5db7f68cf0c21cf7cc92de6c7b919d76c88/pytokens-0.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4e691d7f5186bd2842c14813f79f8884bb03f5995f0575272009982c5ac6c0f7", size = 262693, upload-time = "2026-01-30T01:02:54.871Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7b/8b31c347cf94a3f900bdde750b2e9131575a61fdb620d3d3c75832262137/pytokens-0.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:27b83ad28825978742beef057bfe406ad6ed524b2d28c252c5de7b4a6dd48fa2", size = 103567, upload-time = "2026-01-30T01:02:56.414Z" }, + { url = "https://files.pythonhosted.org/packages/3d/92/790ebe03f07b57e53b10884c329b9a1a308648fc083a6d4a39a10a28c8fc/pytokens-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d70e77c55ae8380c91c0c18dea05951482e263982911fc7410b1ffd1dadd3440", size = 160864, upload-time = "2026-01-30T01:02:57.882Z" }, + { url = "https://files.pythonhosted.org/packages/13/25/a4f555281d975bfdd1eba731450e2fe3a95870274da73fb12c40aeae7625/pytokens-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a58d057208cb9075c144950d789511220b07636dd2e4708d5645d24de666bdc", size = 248565, upload-time = "2026-01-30T01:02:59.912Z" }, + { url = "https://files.pythonhosted.org/packages/17/50/bc0394b4ad5b1601be22fa43652173d47e4c9efbf0044c62e9a59b747c56/pytokens-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b49750419d300e2b5a3813cf229d4e5a4c728dae470bcc89867a9ad6f25a722d", size = 260824, upload-time = "2026-01-30T01:03:01.471Z" }, + { url = "https://files.pythonhosted.org/packages/4e/54/3e04f9d92a4be4fc6c80016bc396b923d2a6933ae94b5f557c939c460ee0/pytokens-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9907d61f15bf7261d7e775bd5d7ee4d2930e04424bab1972591918497623a16", size = 264075, upload-time = "2026-01-30T01:03:04.143Z" }, + { url = "https://files.pythonhosted.org/packages/d1/1b/44b0326cb5470a4375f37988aea5d61b5cc52407143303015ebee94abfd6/pytokens-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:ee44d0f85b803321710f9239f335aafe16553b39106384cef8e6de40cb4ef2f6", size = 103323, upload-time = "2026-01-30T01:03:05.412Z" }, + { url = "https://files.pythonhosted.org/packages/41/5d/e44573011401fb82e9d51e97f1290ceb377800fb4eed650b96f4753b499c/pytokens-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:140709331e846b728475786df8aeb27d24f48cbcf7bcd449f8de75cae7a45083", size = 160663, upload-time = "2026-01-30T01:03:06.473Z" }, + { url = "https://files.pythonhosted.org/packages/f0/e6/5bbc3019f8e6f21d09c41f8b8654536117e5e211a85d89212d59cbdab381/pytokens-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d6c4268598f762bc8e91f5dbf2ab2f61f7b95bdc07953b602db879b3c8c18e1", size = 255626, upload-time = "2026-01-30T01:03:08.177Z" }, + { url = "https://files.pythonhosted.org/packages/bf/3c/2d5297d82286f6f3d92770289fd439956b201c0a4fc7e72efb9b2293758e/pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24afde1f53d95348b5a0eb19488661147285ca4dd7ed752bbc3e1c6242a304d1", size = 269779, upload-time = "2026-01-30T01:03:09.756Z" }, + { url = "https://files.pythonhosted.org/packages/20/01/7436e9ad693cebda0551203e0bf28f7669976c60ad07d6402098208476de/pytokens-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5ad948d085ed6c16413eb5fec6b3e02fa00dc29a2534f088d3302c47eb59adf9", size = 268076, upload-time = "2026-01-30T01:03:10.957Z" }, + { url = "https://files.pythonhosted.org/packages/2e/df/533c82a3c752ba13ae7ef238b7f8cdd272cf1475f03c63ac6cf3fcfb00b6/pytokens-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:3f901fe783e06e48e8cbdc82d631fca8f118333798193e026a50ce1b3757ea68", size = 103552, upload-time = "2026-01-30T01:03:12.066Z" }, + { url = "https://files.pythonhosted.org/packages/cb/dc/08b1a080372afda3cceb4f3c0a7ba2bde9d6a5241f1edb02a22a019ee147/pytokens-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8bdb9d0ce90cbf99c525e75a2fa415144fd570a1ba987380190e8b786bc6ef9b", size = 160720, upload-time = "2026-01-30T01:03:13.843Z" }, + { url = "https://files.pythonhosted.org/packages/64/0c/41ea22205da480837a700e395507e6a24425151dfb7ead73343d6e2d7ffe/pytokens-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5502408cab1cb18e128570f8d598981c68a50d0cbd7c61312a90507cd3a1276f", size = 254204, upload-time = "2026-01-30T01:03:14.886Z" }, + { url = "https://files.pythonhosted.org/packages/e0/d2/afe5c7f8607018beb99971489dbb846508f1b8f351fcefc225fcf4b2adc0/pytokens-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29d1d8fb1030af4d231789959f21821ab6325e463f0503a61d204343c9b355d1", size = 268423, upload-time = "2026-01-30T01:03:15.936Z" }, + { url = "https://files.pythonhosted.org/packages/68/d4/00ffdbd370410c04e9591da9220a68dc1693ef7499173eb3e30d06e05ed1/pytokens-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b08dd6b86058b6dc07efe9e98414f5102974716232d10f32ff39701e841c4", size = 266859, upload-time = "2026-01-30T01:03:17.458Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c9/c3161313b4ca0c601eeefabd3d3b576edaa9afdefd32da97210700e47652/pytokens-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:9bd7d7f544d362576be74f9d5901a22f317efc20046efe2034dced238cbbfe78", size = 103520, upload-time = "2026-01-30T01:03:18.652Z" }, + { url = "https://files.pythonhosted.org/packages/c6/78/397db326746f0a342855b81216ae1f0a32965deccfd7c830a2dbc66d2483/pytokens-0.4.1-py3-none-any.whl", hash = "sha256:26cef14744a8385f35d0e095dc8b3a7583f6c953c2e3d269c7f82484bf5ad2de", size = 13729, upload-time = "2026-01-30T01:03:45.029Z" }, +] + [[package]] name = "pytz" version = "2026.2"