mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-12 23:01:41 +00:00
Merge remote-tracking branch 'origin/litellm_internal_staging' into claude/per-file-any-grandfathering-6qvth8
This commit is contained in:
commit
715ec2d7a2
112 changed files with 1899 additions and 255 deletions
33
.github/workflows/test-linting.yml
vendored
33
.github/workflows/test-linting.yml
vendored
|
|
@ -77,6 +77,12 @@ jobs:
|
|||
run: |
|
||||
uv run --no-sync python scripts/ruff_strict_gate.py --base "$BASE_SHA"
|
||||
|
||||
- name: Check type-discipline budget (mutable collections / casts / type guards / kwargs / unexplained suppressions, delta vs base)
|
||||
env:
|
||||
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
||||
run: |
|
||||
uv run --no-sync python scripts/type_discipline_gate.py --base "$BASE_SHA"
|
||||
|
||||
- name: Print OpenAI version
|
||||
run: |
|
||||
uv run --no-sync python -c "import openai; print(f'OpenAI version: {openai.__version__}')"
|
||||
|
|
@ -100,6 +106,33 @@ jobs:
|
|||
run: |
|
||||
uv run --no-sync python -c "from litellm import *" || (echo '🚨 import failed, this means you introduced unprotected imports! 🚨'; exit 1)
|
||||
|
||||
# Intentionally NON-GATING. This job turns red when a *-budget.json ceiling is
|
||||
# raised (or a rule/budget is dropped) so a loosening is obvious in review, but it
|
||||
# must be kept OUT of the branch-protection required-checks list so a justified
|
||||
# bump can still be merged by a human who has seen and accepted the red.
|
||||
budget-ratchet:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Ratchet check (budgets may only decrease; non-gating)
|
||||
env:
|
||||
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
||||
run: |
|
||||
python scripts/budget_ratchet_check.py --base "$BASE_SHA"
|
||||
|
||||
any-discipline:
|
||||
# Separate job: the first run cold-builds litellm's type cache (~2 min, ~3 GB),
|
||||
# so keep it off the main lint job's time budget. Subsequent runs reuse the
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ If you're trying to create a new function that relies on untyped stuff, instead
|
|||
|
||||
The Any-discipline gate (`make lint-any`, also a CI job) grandfathers each file under `litellm/` at its current count of values typed `Any` (including the `X | Any`) in `any-discipline-budget.json` and gives it ~50% headroom; a changed file fails once it exceeds that ceiling, so a brand new file must be `Any`-free while a legacy file can absorb a little drift before it has to be cleaned. Ideally `# any-ok: <reason>` is never used; treat it as a last resort for a genuine typed/untyped boundary that Pydantic truly can't model
|
||||
|
||||
If you get an LIT001 or LIT002 fail, refactor the code to follow functional programming best practices rather than introducing mutable data structures. For example, build values in one shot with comprehensions or generators wrapped in `tuple()` / `frozenset()` instead of seeding an empty `list`/`dict`/`set` and mutating it over time. Ideally `# mutable-ok` is never used; reach for it only as a genuine last resort when an immutable rewrite is truly impossible, and always pair it with a real reason
|
||||
|
||||
Ask to commit and push your work when you're done (or if you're confident that your code is good and works, just do it)
|
||||
|
||||
When you must use real LLM models to, for example, write e2e tests, write a QA runbook, etc., make sure to use the latest models (doesn't have to be smartest, can also be a modern small, fast one. No strong preference for smart vs fast here, just use something modern) as of the year and month of the current date. Do a web search as necessary to figure that out
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ db = Prisma(
|
|||
)
|
||||
|
||||
|
||||
async def check_view_exists(): # noqa: PLR0915
|
||||
async def check_view_exists():
|
||||
"""
|
||||
Checks if the LiteLLM_VerificationTokenView and MonthlyGlobalSpend exists in the user's db.
|
||||
|
||||
|
|
@ -34,8 +34,7 @@ async def check_view_exists(): # noqa: PLR0915
|
|||
print("LiteLLM_VerificationTokenView Exists!") # noqa
|
||||
except Exception:
|
||||
# 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.*,
|
||||
|
|
@ -45,8 +44,7 @@ async def check_view_exists(): # noqa: PLR0915
|
|||
t.rpm_limit AS team_rpm_limit
|
||||
FROM "LiteLLM_VerificationToken" v
|
||||
LEFT JOIN "LiteLLM_TeamTable" t ON v.team_id = t.team_id;
|
||||
"""
|
||||
)
|
||||
""")
|
||||
|
||||
print("LiteLLM_VerificationTokenView Created!") # noqa
|
||||
|
||||
|
|
|
|||
|
|
@ -412,7 +412,7 @@ class _PROXY_LiteLLMManagedFiles(CustomLogger, BaseFileEndpoints):
|
|||
detail=f"User {user_api_key_dict.user_id} does not have access to the file {file_id}",
|
||||
)
|
||||
|
||||
async def async_pre_call_hook( # noqa: PLR0915
|
||||
async def async_pre_call_hook(
|
||||
self,
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
cache: DualCache,
|
||||
|
|
|
|||
|
|
@ -483,7 +483,7 @@ async def new_project(
|
|||
response_model=LiteLLM_ProjectTable,
|
||||
)
|
||||
@management_endpoint_wrapper
|
||||
async def update_project( # noqa: PLR0915
|
||||
async def update_project(
|
||||
data: UpdateProjectRequest,
|
||||
http_request: Request,
|
||||
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ def get_redis_url_from_environment():
|
|||
return f"{redis_protocol}://{auth_part}{os.environ['REDIS_HOST']}:{os.environ['REDIS_PORT']}"
|
||||
|
||||
|
||||
def _get_redis_client_logic(**env_overrides): # noqa: PLR0915
|
||||
def _get_redis_client_logic(**env_overrides):
|
||||
"""
|
||||
Common functionality across sync + async redis client implementations
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -436,7 +436,7 @@ def _build_streaming_logging_obj(
|
|||
return logging_obj
|
||||
|
||||
|
||||
async def asend_message_streaming( # noqa: PLR0915
|
||||
async def asend_message_streaming(
|
||||
a2a_client: Optional["A2AClientType"] = None,
|
||||
request: Optional["SendStreamingMessageRequest"] = None,
|
||||
api_base: Optional[str] = None,
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ async def acreate_batch(
|
|||
|
||||
|
||||
@client
|
||||
def create_batch( # noqa: PLR0915
|
||||
def create_batch(
|
||||
completion_window: Literal["24h"],
|
||||
endpoint: Literal["/v1/chat/completions", "/v1/embeddings", "/v1/completions"],
|
||||
input_file_id: str,
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ class LLMCachingHandler:
|
|||
return cr["model"]
|
||||
return None
|
||||
|
||||
def _process_async_embedding_cached_response( # noqa: PLR0915
|
||||
def _process_async_embedding_cached_response(
|
||||
self,
|
||||
final_embedding_cached_response: Optional[EmbeddingResponse],
|
||||
cached_result: List[Optional[CachedEmbedding]],
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ from .base_cache import BaseCache
|
|||
class QdrantSemanticCache(BaseCache):
|
||||
CACHE_KEY_FIELD_NAME = "litellm_cache_key"
|
||||
|
||||
def __init__( # noqa: PLR0915
|
||||
def __init__(
|
||||
self,
|
||||
qdrant_api_base=None,
|
||||
qdrant_api_key=None,
|
||||
|
|
|
|||
|
|
@ -1211,7 +1211,7 @@ class OpenAiResponsesToChatCompletionStreamIterator(BaseModelResponseIterator):
|
|||
return self.chunk_parser(json.loads(str_line))
|
||||
|
||||
@staticmethod
|
||||
def translate_responses_chunk_to_openai_stream( # noqa: PLR0915
|
||||
def translate_responses_chunk_to_openai_stream(
|
||||
parsed_chunk: Union[dict, BaseModel],
|
||||
) -> "ModelResponseStream":
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ def _transcription_usage_has_token_details(
|
|||
return (prompt_tokens_val > 0) or (completion_tokens_val > 0)
|
||||
|
||||
|
||||
def cost_per_token( # noqa: PLR0915
|
||||
def cost_per_token(
|
||||
model: str = "",
|
||||
prompt_tokens: int = 0,
|
||||
completion_tokens: int = 0,
|
||||
|
|
@ -1136,7 +1136,7 @@ def _store_cost_breakdown_in_logging_obj(
|
|||
pass
|
||||
|
||||
|
||||
def completion_cost( # noqa: PLR0915
|
||||
def completion_cost(
|
||||
completion_response=None,
|
||||
model: Optional[str] = None,
|
||||
prompt="",
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ def image_generation(
|
|||
|
||||
|
||||
@client
|
||||
def image_generation( # noqa: PLR0915
|
||||
def image_generation(
|
||||
prompt: str,
|
||||
model: Optional[str] = None,
|
||||
n: Optional[int] = None,
|
||||
|
|
@ -738,7 +738,7 @@ def image_variation(
|
|||
|
||||
|
||||
@client
|
||||
def image_edit( # noqa: PLR0915
|
||||
def image_edit(
|
||||
image: Optional[Union[FileTypes, List[FileTypes]]] = None,
|
||||
prompt: Optional[str] = None,
|
||||
model: Optional[str] = None,
|
||||
|
|
|
|||
|
|
@ -351,7 +351,7 @@ class SlackAlerting(CustomBatchLogger):
|
|||
except Exception:
|
||||
return 0
|
||||
|
||||
async def send_daily_reports(self, router) -> bool: # noqa: PLR0915
|
||||
async def send_daily_reports(self, router) -> bool:
|
||||
"""
|
||||
Send a daily report on:
|
||||
- Top 5 deployments with most failed requests
|
||||
|
|
@ -1373,7 +1373,7 @@ Model Info:
|
|||
|
||||
return False
|
||||
|
||||
async def send_alert( # noqa: PLR0915
|
||||
async def send_alert(
|
||||
self,
|
||||
message: str,
|
||||
level: Literal["Low", "Medium", "High"],
|
||||
|
|
|
|||
|
|
@ -133,9 +133,7 @@ class BraintrustLogger(CustomLogger):
|
|||
|
||||
self.default_project_id = project_dict["id"]
|
||||
|
||||
def log_success_event( # noqa: PLR0915
|
||||
self, kwargs, response_obj, start_time, end_time
|
||||
):
|
||||
def log_success_event(self, kwargs, response_obj, start_time, end_time):
|
||||
verbose_logger.debug("REACHES BRAINTRUST SUCCESS")
|
||||
try:
|
||||
litellm_call_id = kwargs.get("litellm_call_id")
|
||||
|
|
@ -271,9 +269,7 @@ class BraintrustLogger(CustomLogger):
|
|||
except Exception as e:
|
||||
raise e # don't use verbose_logger.exception, if exception is raised
|
||||
|
||||
async def async_log_success_event( # noqa: PLR0915
|
||||
self, kwargs, response_obj, start_time, end_time
|
||||
):
|
||||
async def async_log_success_event(self, kwargs, response_obj, start_time, end_time):
|
||||
verbose_logger.debug("REACHES BRAINTRUST SUCCESS")
|
||||
try:
|
||||
litellm_call_id = kwargs.get("litellm_call_id")
|
||||
|
|
|
|||
|
|
@ -549,7 +549,7 @@ class LangFuseLogger:
|
|||
)
|
||||
)
|
||||
|
||||
def _log_langfuse_v2( # noqa: PLR0915
|
||||
def _log_langfuse_v2(
|
||||
self,
|
||||
user_id: Optional[str],
|
||||
metadata: dict,
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ def _is_url_match(url, matchers: List[str]) -> bool:
|
|||
return False
|
||||
|
||||
|
||||
def create_mock_client_factory(config: MockClientConfig): # noqa: PLR0915
|
||||
def create_mock_client_factory(config: MockClientConfig):
|
||||
"""
|
||||
Factory function that creates mock client functions based on configuration.
|
||||
|
||||
|
|
|
|||
|
|
@ -2198,9 +2198,7 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger):
|
|||
|
||||
return kv_pairs
|
||||
|
||||
def set_attributes( # noqa: PLR0915
|
||||
self, span: Span, kwargs, response_obj: Optional[Any]
|
||||
):
|
||||
def set_attributes(self, span: Span, kwargs, response_obj: Optional[Any]):
|
||||
try:
|
||||
if self.callback_name == "langtrace":
|
||||
from litellm.integrations.langtrace import LangtraceAttributes
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class PrometheusLogger(CustomLogger):
|
|||
return cb
|
||||
return None
|
||||
|
||||
def __init__( # noqa: PLR0915
|
||||
def __init__(
|
||||
self,
|
||||
**kwargs,
|
||||
):
|
||||
|
|
@ -2255,7 +2255,7 @@ class PrometheusLogger(CustomLogger):
|
|||
or _litellm_params_metadata.get("user_agent"),
|
||||
}
|
||||
|
||||
def set_llm_deployment_failure_metrics(self, request_kwargs: dict): # noqa: PLR0915
|
||||
def set_llm_deployment_failure_metrics(self, request_kwargs: dict):
|
||||
"""
|
||||
Sets Failure metrics when an LLM API call fails
|
||||
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ def extract_and_raise_litellm_exception(
|
|||
)
|
||||
|
||||
|
||||
def exception_type( # type: ignore # noqa: PLR0915
|
||||
def exception_type( # type: ignore
|
||||
model,
|
||||
original_exception,
|
||||
custom_llm_provider,
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ def handle_anthropic_text_model_custom_llm_provider(
|
|||
return model, custom_llm_provider
|
||||
|
||||
|
||||
def get_llm_provider( # noqa: PLR0915
|
||||
def get_llm_provider(
|
||||
model: str,
|
||||
custom_llm_provider: Optional[str] = None,
|
||||
api_base: Optional[str] = None,
|
||||
|
|
@ -568,7 +568,7 @@ def get_llm_provider( # noqa: PLR0915
|
|||
)
|
||||
|
||||
|
||||
def _get_openai_compatible_provider_info( # noqa: PLR0915
|
||||
def _get_openai_compatible_provider_info(
|
||||
model: str,
|
||||
api_base: Optional[str],
|
||||
api_key: Optional[str],
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from litellm.exceptions import BadRequestError
|
|||
from litellm.types.utils import LlmProviders, LlmProvidersSet
|
||||
|
||||
|
||||
def get_supported_openai_params( # noqa: PLR0915
|
||||
def get_supported_openai_params(
|
||||
model: str,
|
||||
custom_llm_provider: Optional[str] = None,
|
||||
request_type: Literal[
|
||||
|
|
|
|||
|
|
@ -986,7 +986,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
self._get_masked_api_base(additional_args.get("api_base", ""))
|
||||
)
|
||||
|
||||
def pre_call(self, input, api_key, model=None, additional_args={}): # noqa: PLR0915
|
||||
def pre_call(self, input, api_key, model=None, additional_args={}):
|
||||
# Log the exact input to the LLM API
|
||||
litellm.error_logs["PRE_CALL"] = locals()
|
||||
try:
|
||||
|
|
@ -2119,7 +2119,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
await self.async_success_handler(result=complete_streaming_response)
|
||||
return
|
||||
|
||||
def success_handler( # noqa: PLR0915
|
||||
def success_handler(
|
||||
self, result=None, start_time=None, end_time=None, cache_hit=None, **kwargs
|
||||
):
|
||||
verbose_logger.debug(
|
||||
|
|
@ -2584,7 +2584,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
),
|
||||
)
|
||||
|
||||
async def async_success_handler( # noqa: PLR0915
|
||||
async def async_success_handler(
|
||||
self, result=None, start_time=None, end_time=None, cache_hit=None, **kwargs
|
||||
):
|
||||
"""
|
||||
|
|
@ -3036,7 +3036,7 @@ class Logging(LiteLLMLoggingBaseClass):
|
|||
kwargs=self.model_call_details,
|
||||
) # type: ignore
|
||||
|
||||
def failure_handler( # noqa: PLR0915
|
||||
def failure_handler(
|
||||
self, exception, traceback_exception, start_time=None, end_time=None
|
||||
):
|
||||
verbose_logger.debug(
|
||||
|
|
@ -3753,7 +3753,7 @@ def _get_masked_values(
|
|||
}
|
||||
|
||||
|
||||
def set_callbacks(callback_list, function_id=None): # noqa: PLR0915
|
||||
def set_callbacks(callback_list, function_id=None):
|
||||
"""
|
||||
Globally sets the callback client
|
||||
"""
|
||||
|
|
@ -3854,7 +3854,7 @@ def set_callbacks(callback_list, function_id=None): # noqa: PLR0915
|
|||
return None
|
||||
|
||||
|
||||
def _init_custom_logger_compatible_class( # noqa: PLR0915
|
||||
def _init_custom_logger_compatible_class(
|
||||
logging_integration: _custom_logger_compatible_callbacks_literal,
|
||||
internal_usage_cache: Optional[DualCache],
|
||||
llm_router: Optional[
|
||||
|
|
@ -4611,7 +4611,7 @@ def _maybe_auto_initialize_arize_phoenix(_in_memory_loggers: list) -> None:
|
|||
)
|
||||
|
||||
|
||||
def get_custom_logger_compatible_class( # noqa: PLR0915
|
||||
def get_custom_logger_compatible_class(
|
||||
logging_integration: _custom_logger_compatible_callbacks_literal,
|
||||
) -> Optional[CustomLogger]:
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -683,7 +683,7 @@ def _get_regional_uplift_multiplier(
|
|||
return 1.0
|
||||
|
||||
|
||||
def generic_cost_per_token( # noqa: PLR0915
|
||||
def generic_cost_per_token(
|
||||
model: str,
|
||||
usage: Usage,
|
||||
custom_llm_provider: str,
|
||||
|
|
|
|||
|
|
@ -471,7 +471,7 @@ def _should_convert_tool_call_to_json_mode(
|
|||
return False
|
||||
|
||||
|
||||
def convert_to_model_response_object( # noqa: PLR0915
|
||||
def convert_to_model_response_object(
|
||||
response_object: Optional[dict] = None,
|
||||
model_response_object: Optional[
|
||||
Union[
|
||||
|
|
|
|||
|
|
@ -1475,7 +1475,7 @@ def convert_to_gemini_tool_call_invoke(
|
|||
)
|
||||
|
||||
|
||||
def convert_to_gemini_tool_call_result( # noqa: PLR0915
|
||||
def convert_to_gemini_tool_call_result(
|
||||
message: Union[ChatCompletionToolMessage, ChatCompletionFunctionMessage],
|
||||
last_message_with_tool_calls: Optional[dict],
|
||||
model: Optional[str] = None,
|
||||
|
|
@ -2227,7 +2227,7 @@ def _sanitize_empty_text_content(
|
|||
return message
|
||||
|
||||
|
||||
def _add_missing_tool_results( # noqa: PLR0915
|
||||
def _add_missing_tool_results(
|
||||
current_message: AllMessageValues,
|
||||
messages: List[AllMessageValues],
|
||||
current_index: int,
|
||||
|
|
@ -2484,7 +2484,7 @@ def sanitize_messages_for_tool_calling(
|
|||
return sanitized_messages
|
||||
|
||||
|
||||
def anthropic_messages_pt( # noqa: PLR0915
|
||||
def anthropic_messages_pt(
|
||||
messages: List[AllMessageValues],
|
||||
model: str,
|
||||
llm_provider: str,
|
||||
|
|
@ -3278,7 +3278,7 @@ def convert_to_cohere_tool_invoke(tool_calls: list) -> List[ToolCallObject]:
|
|||
return cohere_tool_invoke
|
||||
|
||||
|
||||
def cohere_messages_pt_v2( # noqa: PLR0915
|
||||
def cohere_messages_pt_v2(
|
||||
messages: List,
|
||||
model: str,
|
||||
llm_provider: str,
|
||||
|
|
@ -4703,7 +4703,7 @@ class BedrockConverseMessagesProcessor:
|
|||
return messages
|
||||
|
||||
@staticmethod
|
||||
async def _bedrock_converse_messages_pt_async( # noqa: PLR0915
|
||||
async def _bedrock_converse_messages_pt_async(
|
||||
messages: List,
|
||||
model: str,
|
||||
llm_provider: str,
|
||||
|
|
@ -5133,7 +5133,7 @@ class BedrockConverseMessagesProcessor:
|
|||
return assistant_parts
|
||||
|
||||
|
||||
def _bedrock_converse_messages_pt( # noqa: PLR0915
|
||||
def _bedrock_converse_messages_pt(
|
||||
messages: List,
|
||||
model: str,
|
||||
llm_provider: str,
|
||||
|
|
|
|||
|
|
@ -1198,7 +1198,7 @@ class RealTimeStreaming:
|
|||
item["content"] = new_content
|
||||
return item
|
||||
|
||||
async def client_ack_messages(self): # noqa: PLR0915
|
||||
async def client_ack_messages(self):
|
||||
try:
|
||||
while True:
|
||||
message = await self.websocket.receive_text()
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ class ChunkProcessor:
|
|||
)
|
||||
return response
|
||||
|
||||
def get_combined_tool_content( # noqa: PLR0915
|
||||
def get_combined_tool_content(
|
||||
self, tool_call_chunks: List[Dict[str, Any]]
|
||||
) -> List[ChatCompletionMessageToolCall]:
|
||||
tool_calls_list: List[ChatCompletionMessageToolCall] = []
|
||||
|
|
|
|||
|
|
@ -967,7 +967,7 @@ class CustomStreamWrapper:
|
|||
delta, model_response.choices[0].delta, attribute
|
||||
)
|
||||
|
||||
def return_processed_chunk_logic( # noqa: PLR0915, C901
|
||||
def return_processed_chunk_logic( # noqa: C901
|
||||
self,
|
||||
completion_obj: Dict[str, Any],
|
||||
model_response: ModelResponseStream,
|
||||
|
|
@ -1145,7 +1145,7 @@ class CustomStreamWrapper:
|
|||
del model_response.choices[0].delta.reasoning_content
|
||||
return
|
||||
|
||||
def chunk_creator(self, chunk: Any): # type: ignore # noqa: PLR0915
|
||||
def chunk_creator(self, chunk: Any): # type: ignore
|
||||
if hasattr(chunk, "id"):
|
||||
self.response_id = chunk.id
|
||||
model_response = self.model_response_creator()
|
||||
|
|
@ -1887,7 +1887,7 @@ class CustomStreamWrapper:
|
|||
model_response.choices[0].finish_reason = "tool_calls"
|
||||
return model_response
|
||||
|
||||
def __next__(self) -> "ModelResponseStream": # noqa: PLR0915
|
||||
def __next__(self) -> "ModelResponseStream":
|
||||
cache_hit = False
|
||||
if (
|
||||
self.custom_llm_provider is not None
|
||||
|
|
@ -2077,7 +2077,7 @@ class CustomStreamWrapper:
|
|||
|
||||
return self.completion_stream
|
||||
|
||||
async def __anext__(self) -> "ModelResponseStream": # noqa: PLR0915
|
||||
async def __anext__(self) -> "ModelResponseStream":
|
||||
cache_hit = False
|
||||
if (
|
||||
self.custom_llm_provider is not None
|
||||
|
|
|
|||
|
|
@ -772,7 +772,7 @@ class ModelResponseIterator:
|
|||
)
|
||||
return results
|
||||
|
||||
def chunk_parser(self, chunk: dict) -> ModelResponseStream: # noqa: PLR0915
|
||||
def chunk_parser(self, chunk: dict) -> ModelResponseStream:
|
||||
try:
|
||||
type_chunk = chunk.get("type", "") or ""
|
||||
|
||||
|
|
|
|||
|
|
@ -605,7 +605,7 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
|||
)
|
||||
return _tool_choice
|
||||
|
||||
def _map_tool_helper( # noqa: PLR0915
|
||||
def _map_tool_helper(
|
||||
self,
|
||||
tool: ChatCompletionToolParam,
|
||||
) -> Tuple[Optional[AllAnthropicToolsValues], Optional[AnthropicMcpServerTool]]:
|
||||
|
|
@ -1399,7 +1399,7 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
|||
|
||||
return None
|
||||
|
||||
def map_openai_params( # noqa: PLR0915
|
||||
def map_openai_params(
|
||||
self,
|
||||
non_default_params: dict,
|
||||
optional_params: dict,
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper):
|
|||
cache_read_input_tokens=0,
|
||||
)
|
||||
|
||||
def __next__(self): # noqa: PLR0915
|
||||
def __next__(self):
|
||||
from .transformation import LiteLLMAnthropicMessagesAdapter
|
||||
|
||||
try:
|
||||
|
|
@ -618,7 +618,7 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper):
|
|||
)
|
||||
raise StopIteration
|
||||
|
||||
async def __anext__(self): # noqa: PLR0915
|
||||
async def __anext__(self):
|
||||
from .transformation import LiteLLMAnthropicMessagesAdapter
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -383,7 +383,7 @@ class LiteLLMAnthropicMessagesAdapter:
|
|||
isinstance(tool_type, str) and tool_type.startswith("web_search")
|
||||
) or tool_name == "web_search"
|
||||
|
||||
def translate_anthropic_messages_to_openai( # noqa: PLR0915
|
||||
def translate_anthropic_messages_to_openai(
|
||||
self,
|
||||
messages: List[
|
||||
Union[
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ def _read_summary_max_tokens_setting() -> int:
|
|||
return COMPACT_SUMMARY_MAX_TOKENS
|
||||
|
||||
|
||||
async def _check_summary_model_access( # noqa: PLR0915
|
||||
async def _check_summary_model_access(
|
||||
user_api_key_auth: Any,
|
||||
summary_model: str,
|
||||
llm_router: Any,
|
||||
|
|
@ -970,7 +970,7 @@ def apply_client_compaction_block_history(
|
|||
)
|
||||
|
||||
|
||||
async def apply_compact_20260112( # noqa: PLR0915
|
||||
async def apply_compact_20260112(
|
||||
*,
|
||||
model: str,
|
||||
messages: List[Dict[str, Any]],
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class AnthropicResponsesStreamWrapper:
|
|||
self._current_block_index += 1
|
||||
return self._current_block_index
|
||||
|
||||
def _process_event(self, event: Any) -> None: # noqa: PLR0915
|
||||
def _process_event(self, event: Any) -> None:
|
||||
"""Convert one Responses API event into zero or more Anthropic chunks queued for emission."""
|
||||
event_type = getattr(event, "type", None)
|
||||
if event_type is None and isinstance(event, dict):
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class LiteLLMAnthropicToResponsesAPIAdapter:
|
|||
return source.get("url")
|
||||
return None
|
||||
|
||||
def translate_messages_to_responses_input( # noqa: PLR0915
|
||||
def translate_messages_to_responses_input(
|
||||
self,
|
||||
messages: List[
|
||||
Union[
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ class BedrockConverseLLM(BaseAWSLLM):
|
|||
encoding=encoding,
|
||||
)
|
||||
|
||||
def completion( # noqa: PLR0915
|
||||
def completion(
|
||||
self,
|
||||
model: str,
|
||||
messages: list,
|
||||
|
|
|
|||
|
|
@ -2189,7 +2189,7 @@ class AmazonConverseConfig(BaseConfig):
|
|||
real_tools = [t for i, t in enumerate(tools) if i not in json_tool_indices]
|
||||
return real_tools if real_tools else None
|
||||
|
||||
def _transform_response( # noqa: PLR0915
|
||||
def _transform_response(
|
||||
self,
|
||||
model: str,
|
||||
response: httpx.Response,
|
||||
|
|
|
|||
|
|
@ -473,7 +473,7 @@ class BedrockLLM(BaseAWSLLM):
|
|||
prompt += f"{message['content']}"
|
||||
return prompt, chat_history # type: ignore
|
||||
|
||||
def process_response( # noqa: PLR0915
|
||||
def process_response(
|
||||
self,
|
||||
model: str,
|
||||
response: httpx.Response,
|
||||
|
|
@ -765,7 +765,7 @@ class BedrockLLM(BaseAWSLLM):
|
|||
|
||||
return model_response
|
||||
|
||||
def completion( # noqa: PLR0915
|
||||
def completion(
|
||||
self,
|
||||
model: str,
|
||||
messages: list,
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ class BedrockEmbedding(BaseAWSLLM):
|
|||
batch_data=batch_data,
|
||||
)
|
||||
|
||||
def embeddings( # noqa: PLR0915
|
||||
def embeddings(
|
||||
self,
|
||||
model: str,
|
||||
input: List[str],
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ class BedrockStabilityImageEditConfig(BaseImageEditConfig):
|
|||
|
||||
return mapped_params
|
||||
|
||||
def transform_image_edit_request( # noqa: PLR0915
|
||||
def transform_image_edit_request(
|
||||
self,
|
||||
model: str,
|
||||
prompt: Optional[str],
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ class BedrockPassthroughGuardrailHandler(BaseTranslation):
|
|||
return _is_converse_endpoint(endpoint)
|
||||
|
||||
@staticmethod
|
||||
async def de_anonymize_event_stream( # noqa: PLR0915
|
||||
async def de_anonymize_event_stream(
|
||||
body_bytes: bytes,
|
||||
proxy_logging_obj: "ProxyLogging",
|
||||
user_api_key_dict: "UserAPIKeyAuth",
|
||||
|
|
|
|||
|
|
@ -5676,7 +5676,7 @@ class BaseLLMHTTPHandler:
|
|||
)
|
||||
raise
|
||||
|
||||
async def async_responses_websocket( # noqa: PLR0915
|
||||
async def async_responses_websocket(
|
||||
self,
|
||||
model: str,
|
||||
websocket: Any,
|
||||
|
|
|
|||
|
|
@ -1378,7 +1378,7 @@ class GeminiRealtimeConfig(BaseRealtimeConfig):
|
|||
raise ValueError(f"Unknown openai event: {key}, value: {value}")
|
||||
return openai_event
|
||||
|
||||
def transform_realtime_response( # noqa: PLR0915
|
||||
def transform_realtime_response(
|
||||
self,
|
||||
message: Union[str, bytes],
|
||||
model: str,
|
||||
|
|
|
|||
|
|
@ -404,7 +404,7 @@ class HuggingFaceEmbeddingConfig(BaseConfig):
|
|||
)
|
||||
return completion_response
|
||||
|
||||
def convert_to_model_response_object( # noqa: PLR0915
|
||||
def convert_to_model_response_object(
|
||||
self,
|
||||
completion_response: Union[List[Dict[str, Any]], Dict[str, Any]],
|
||||
model_response: ModelResponse,
|
||||
|
|
|
|||
|
|
@ -608,7 +608,7 @@ class OpenAIChatCompletion(BaseLLM, BaseOpenAILLM):
|
|||
|
||||
return streaming_response
|
||||
|
||||
def completion( # type: ignore # noqa: PLR0915
|
||||
def completion( # type: ignore
|
||||
self,
|
||||
model_response: ModelResponse,
|
||||
timeout: Union[float, httpx.Timeout],
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ class PredibaseConfig(BaseConfig):
|
|||
optional_params["response_format"] = value
|
||||
return optional_params
|
||||
|
||||
def transform_response( # noqa: PLR0915
|
||||
def transform_response(
|
||||
self,
|
||||
model: str,
|
||||
raw_response: Response,
|
||||
|
|
|
|||
|
|
@ -678,7 +678,7 @@ def check_if_part_exists_in_parts(
|
|||
return False
|
||||
|
||||
|
||||
def _gemini_convert_messages_with_history( # noqa: PLR0915
|
||||
def _gemini_convert_messages_with_history(
|
||||
messages: List[AllMessageValues],
|
||||
model: Optional[str] = None,
|
||||
litellm_params: Optional[dict] = None,
|
||||
|
|
@ -1176,7 +1176,7 @@ def _rewrite_google_maps_response_format(data: RequestBody) -> None:
|
|||
_rewrite_mime_type_to_response_format(generation_config)
|
||||
|
||||
|
||||
def _transform_request_body( # noqa: PLR0915
|
||||
def _transform_request_body(
|
||||
messages: List[AllMessageValues],
|
||||
model: str,
|
||||
optional_params: dict,
|
||||
|
|
|
|||
|
|
@ -614,9 +614,7 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
|
|||
|
||||
return googleSearch, googleSearchRetrieval, enterpriseWebSearch, urlContext
|
||||
|
||||
def _map_function( # noqa: PLR0915
|
||||
self, value: List[dict], optional_params: dict
|
||||
) -> List[Tools]:
|
||||
def _map_function(self, value: List[dict], optional_params: dict) -> List[Tools]:
|
||||
"""
|
||||
Map OpenAI-style tools/functions to Vertex AI format.
|
||||
|
||||
|
|
@ -1173,7 +1171,7 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
|
|||
optional_params["include_server_side_tool_invocations"] = True
|
||||
return
|
||||
|
||||
def map_openai_params( # noqa: PLR0915
|
||||
def map_openai_params(
|
||||
self,
|
||||
non_default_params: Dict,
|
||||
optional_params: Dict,
|
||||
|
|
@ -1904,7 +1902,7 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
|
|||
return False
|
||||
|
||||
@staticmethod
|
||||
def _calculate_usage( # noqa: PLR0915
|
||||
def _calculate_usage(
|
||||
completion_response: Union[
|
||||
GenerateContentResponseBody, BidiGenerateContentServerMessage
|
||||
],
|
||||
|
|
@ -2380,7 +2378,7 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
|
|||
return annotations
|
||||
|
||||
@staticmethod
|
||||
def _process_candidates( # noqa: PLR0915
|
||||
def _process_candidates(
|
||||
_candidates: List[Candidates],
|
||||
model_response: Union[ModelResponse, "ModelResponseStream"],
|
||||
standard_optional_params: dict,
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ class GoogleBatchEmbeddings(VertexLLM):
|
|||
|
||||
return resolved_files
|
||||
|
||||
def batch_embeddings( # noqa: PLR0915
|
||||
def batch_embeddings(
|
||||
self,
|
||||
model: str,
|
||||
input: GeminiEmbeddingInput,
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ def _set_client_in_cache(client_cache_key: str, vertex_llm_model: Any):
|
|||
)
|
||||
|
||||
|
||||
def completion( # noqa: PLR0915
|
||||
def completion(
|
||||
model: str,
|
||||
messages: list,
|
||||
model_response: ModelResponse,
|
||||
|
|
@ -485,7 +485,7 @@ def completion( # noqa: PLR0915
|
|||
)
|
||||
|
||||
|
||||
async def async_completion( # noqa: PLR0915
|
||||
async def async_completion(
|
||||
llm_model,
|
||||
mode: str,
|
||||
prompt: str,
|
||||
|
|
|
|||
|
|
@ -1086,7 +1086,7 @@ def _build_custom_pricing_entry(
|
|||
|
||||
@tracer.wrap()
|
||||
@client
|
||||
def completion( # type: ignore # noqa: PLR0915
|
||||
def completion( # type: ignore
|
||||
model: str,
|
||||
# Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create
|
||||
messages: List = [],
|
||||
|
|
@ -4878,7 +4878,7 @@ def embedding(
|
|||
|
||||
|
||||
@client
|
||||
def embedding( # noqa: PLR0915
|
||||
def embedding(
|
||||
model,
|
||||
input=[],
|
||||
# Optional params
|
||||
|
|
@ -6125,7 +6125,7 @@ async def atext_completion(
|
|||
|
||||
|
||||
@client
|
||||
def text_completion( # noqa: PLR0915
|
||||
def text_completion(
|
||||
prompt: Union[
|
||||
str, List[Union[str, List[Union[str, List[int]]]]]
|
||||
], # Required: The prompt(s) to generate completions for.
|
||||
|
|
@ -6664,7 +6664,7 @@ async def atranscription(*args, **kwargs) -> TranscriptionResponse:
|
|||
|
||||
|
||||
@client
|
||||
def transcription( # noqa: PLR0915
|
||||
def transcription(
|
||||
model: str,
|
||||
file: FileTypes,
|
||||
## OPTIONAL OPENAI PARAMS ##
|
||||
|
|
@ -6971,7 +6971,7 @@ async def aspeech(*args, **kwargs) -> HttpxBinaryResponseContent:
|
|||
|
||||
|
||||
@client
|
||||
def speech( # noqa: PLR0915
|
||||
def speech(
|
||||
model: str,
|
||||
input: str,
|
||||
voice: Optional[Union[str, dict]] = None,
|
||||
|
|
@ -7662,7 +7662,7 @@ def stream_chunk_builder_text_completion(
|
|||
return TextCompletionResponse(**response)
|
||||
|
||||
|
||||
def stream_chunk_builder( # noqa: PLR0915
|
||||
def stream_chunk_builder(
|
||||
chunks: list,
|
||||
messages: Optional[list] = None,
|
||||
start_time=None,
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ class MCPRequestHandler:
|
|||
LITELLM_MCP_ACCESS_GROUPS_HEADER_NAME = SpecialHeaders.mcp_access_groups.value
|
||||
|
||||
@staticmethod
|
||||
async def process_mcp_request( # noqa: PLR0915
|
||||
async def process_mcp_request(
|
||||
scope: Scope,
|
||||
) -> Tuple[
|
||||
UserAPIKeyAuth,
|
||||
|
|
|
|||
|
|
@ -3355,7 +3355,7 @@ class MCPServerManager:
|
|||
)
|
||||
)
|
||||
|
||||
async def _call_regular_mcp_tool( # noqa: PLR0915
|
||||
async def _call_regular_mcp_tool(
|
||||
self,
|
||||
mcp_server: MCPServer,
|
||||
original_tool_name: str,
|
||||
|
|
|
|||
|
|
@ -661,7 +661,7 @@ def _convert_openai_response_to_mcp_result(
|
|||
)
|
||||
|
||||
|
||||
async def _check_model_access( # noqa: PLR0915
|
||||
async def _check_model_access(
|
||||
model: str, user_api_key_auth: Any
|
||||
) -> Optional["ErrorData"]:
|
||||
"""Enforce model-permission checks for MCP sampling requests.
|
||||
|
|
|
|||
|
|
@ -617,7 +617,7 @@ if MCP_AVAILABLE:
|
|||
active_mcp_session_var.reset(_session_reset_token)
|
||||
|
||||
@server.call_tool()
|
||||
async def mcp_server_tool_call( # noqa: PLR0915
|
||||
async def mcp_server_tool_call(
|
||||
name: str, arguments: Dict[str, Any] | None
|
||||
) -> CallToolResult:
|
||||
"""
|
||||
|
|
@ -1591,7 +1591,7 @@ if MCP_AVAILABLE:
|
|||
_mcp_gateway_initialize_instructions.reset(instructions_token)
|
||||
_mcp_gateway_server_name.reset(server_name_token)
|
||||
|
||||
async def _get_tools_from_mcp_servers( # noqa: PLR0915
|
||||
async def _get_tools_from_mcp_servers(
|
||||
user_api_key_auth: Optional[UserAPIKeyAuth],
|
||||
mcp_auth_header: Optional[str],
|
||||
mcp_servers: Optional[List[str]],
|
||||
|
|
@ -2435,7 +2435,7 @@ if MCP_AVAILABLE:
|
|||
},
|
||||
)
|
||||
|
||||
async def execute_mcp_tool( # noqa: PLR0915
|
||||
async def execute_mcp_tool(
|
||||
name: str,
|
||||
arguments: Dict[str, Any],
|
||||
allowed_mcp_servers: List[MCPServer],
|
||||
|
|
@ -3642,7 +3642,7 @@ if MCP_AVAILABLE:
|
|||
detail="Forbidden",
|
||||
)
|
||||
|
||||
async def handle_streamable_http_mcp( # noqa: PLR0915
|
||||
async def handle_streamable_http_mcp(
|
||||
scope: Scope, receive: Receive, send: Send
|
||||
) -> None:
|
||||
"""Handle MCP requests through StreamableHTTP."""
|
||||
|
|
|
|||
|
|
@ -2152,6 +2152,10 @@ class ConfigGeneralSettings(LiteLLMPydanticObjectBase):
|
|||
master_key: Optional[str] = Field(
|
||||
None, description="require a key for all calls to proxy"
|
||||
)
|
||||
allow_cli_sso_verification_uri_complete: bool | None = Field(
|
||||
None,
|
||||
description="opt-in to RFC 8628 verification_uri_complete for the CLI SSO device flow, pre-filling the user_code in the browser. Off by default; intended for same-host clients where the device that starts the flow and the browser run on the same machine",
|
||||
)
|
||||
database_url: Optional[str] = Field(
|
||||
None,
|
||||
description="connect to a postgres db - needed for generating temporary keys + tracking spend / key",
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ async def get_agent_card(
|
|||
tags=["[beta] A2A Agents"],
|
||||
dependencies=[Depends(user_api_key_auth)],
|
||||
)
|
||||
async def invoke_agent_a2a( # noqa: PLR0915
|
||||
async def invoke_agent_a2a(
|
||||
agent_id: str,
|
||||
request: Request,
|
||||
fastapi_response: Response,
|
||||
|
|
|
|||
|
|
@ -519,7 +519,7 @@ MODEL_DISCOVERY_ROUTES = frozenset(
|
|||
)
|
||||
|
||||
|
||||
async def common_checks( # noqa: PLR0915
|
||||
async def common_checks(
|
||||
request_body: dict,
|
||||
team_object: Optional[LiteLLM_TeamTable],
|
||||
user_object: Optional[LiteLLM_UserTable],
|
||||
|
|
|
|||
|
|
@ -1954,7 +1954,7 @@ class JWTAuthManager:
|
|||
return None, None, None
|
||||
|
||||
@staticmethod
|
||||
async def auth_builder( # noqa: PLR0915
|
||||
async def auth_builder(
|
||||
api_key: str,
|
||||
jwt_handler: JWTHandler,
|
||||
request_data: dict,
|
||||
|
|
|
|||
|
|
@ -979,7 +979,7 @@ def _ensure_parent_otel_span_on_request_state(request: Request) -> None:
|
|||
request.state.parent_otel_span = parent_otel_span
|
||||
|
||||
|
||||
async def _user_api_key_auth_builder( # noqa: PLR0915
|
||||
async def _user_api_key_auth_builder(
|
||||
request: Request,
|
||||
api_key: str,
|
||||
azure_api_key_header: str,
|
||||
|
|
@ -2126,7 +2126,7 @@ def _team_obj_from_token(valid_token: UserAPIKeyAuth) -> LiteLLM_TeamTableCached
|
|||
|
||||
|
||||
@tracer.wrap()
|
||||
async def _run_centralized_common_checks( # noqa: PLR0915
|
||||
async def _run_centralized_common_checks(
|
||||
user_api_key_auth_obj: UserAPIKeyAuth,
|
||||
request: Request,
|
||||
request_data: dict,
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ router = APIRouter()
|
|||
dependencies=[Depends(user_api_key_auth)],
|
||||
tags=["batch"],
|
||||
)
|
||||
async def create_batch( # noqa: PLR0915
|
||||
async def create_batch(
|
||||
request: Request,
|
||||
fastapi_response: Response,
|
||||
provider: Optional[str] = None,
|
||||
|
|
@ -343,7 +343,7 @@ async def create_batch( # noqa: PLR0915
|
|||
dependencies=[Depends(user_api_key_auth)],
|
||||
tags=["batch"],
|
||||
)
|
||||
async def retrieve_batch( # noqa: PLR0915
|
||||
async def retrieve_batch(
|
||||
request: Request,
|
||||
fastapi_response: Response,
|
||||
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ class _UpstreamClosingStreamingResponse(StreamingResponse):
|
|||
)
|
||||
|
||||
|
||||
async def create_response( # noqa: PLR0915
|
||||
async def create_response(
|
||||
generator: AsyncGenerator[str, None],
|
||||
media_type: str,
|
||||
headers: dict,
|
||||
|
|
@ -1148,7 +1148,7 @@ class ProxyBaseLLMRequestProcessing:
|
|||
_payload_str,
|
||||
)
|
||||
|
||||
async def base_process_llm_request( # noqa: PLR0915
|
||||
async def base_process_llm_request(
|
||||
self,
|
||||
request: Request,
|
||||
fastapi_response: Response,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ if TYPE_CHECKING:
|
|||
from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLogging
|
||||
|
||||
|
||||
def initialize_callbacks_on_proxy( # noqa: PLR0915
|
||||
def initialize_callbacks_on_proxy(
|
||||
value: Any,
|
||||
premium_user: bool,
|
||||
config_file_path: str,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ _db = Any
|
|||
_VIEW_NOT_FOUND_MARKERS = ("does not exist", "no such table", "undefined table")
|
||||
|
||||
|
||||
async def create_missing_views(db: _db): # noqa: PLR0915
|
||||
async def create_missing_views(db: _db):
|
||||
"""
|
||||
--------------------------------------------------
|
||||
NOTE: Copy of `litellm/db_scripts/create_views.py`.
|
||||
|
|
|
|||
|
|
@ -1128,7 +1128,7 @@ class DBSpendUpdateWriter:
|
|||
"_flush_tool_discovery_queue error (non-blocking): %s", e
|
||||
)
|
||||
|
||||
async def _commit_spend_updates_to_db( # noqa: PLR0915
|
||||
async def _commit_spend_updates_to_db(
|
||||
self,
|
||||
prisma_client: PrismaClient,
|
||||
n_retry_times: int,
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ class lakeraAI_Moderation(CustomGuardrail):
|
|||
|
||||
return None
|
||||
|
||||
async def _check( # noqa: PLR0915
|
||||
async def _check(
|
||||
self,
|
||||
data: dict,
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ class PanwPrismaAirsHandler(CustomGuardrail):
|
|||
)
|
||||
return ""
|
||||
|
||||
async def _call_panw_api( # noqa: PLR0915
|
||||
async def _call_panw_api(
|
||||
self,
|
||||
content: str = "",
|
||||
is_response: bool = False,
|
||||
|
|
@ -1762,7 +1762,7 @@ class PanwPrismaAirsHandler(CustomGuardrail):
|
|||
return rd.get("name") if ("arguments" in rd or "mcp_arguments" in rd) else None
|
||||
|
||||
@log_guardrail_information
|
||||
async def apply_guardrail( # noqa: PLR0915
|
||||
async def apply_guardrail(
|
||||
self,
|
||||
inputs: GenericGuardrailAPIInputs,
|
||||
request_data: dict,
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ class UnifiedLLMGuardrails(CustomLogger):
|
|||
|
||||
return response
|
||||
|
||||
async def async_post_call_streaming_iterator_hook( # noqa: PLR0915
|
||||
async def async_post_call_streaming_iterator_hook(
|
||||
self,
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
response: Any,
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ async def test_endpoint(request: Request):
|
|||
tags=["health"],
|
||||
dependencies=[Depends(user_api_key_auth)],
|
||||
)
|
||||
async def health_services_endpoint( # noqa: PLR0915
|
||||
async def health_services_endpoint(
|
||||
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
|
||||
service: services = fastapi.Query(description="Specify the service being hit."),
|
||||
):
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ class _PROXY_MaxParallelRequestsHandler(CustomLogger):
|
|||
request_count_end_user_id=results[5],
|
||||
)
|
||||
|
||||
async def async_pre_call_hook( # noqa: PLR0915
|
||||
async def async_pre_call_hook(
|
||||
self,
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
cache: DualCache,
|
||||
|
|
@ -506,9 +506,7 @@ class _PROXY_MaxParallelRequestsHandler(CustomLogger):
|
|||
|
||||
return
|
||||
|
||||
async def async_log_success_event( # noqa: PLR0915
|
||||
self, kwargs, response_obj, start_time, end_time
|
||||
):
|
||||
async def async_log_success_event(self, kwargs, response_obj, start_time, end_time):
|
||||
from litellm.proxy.common_utils.callback_utils import (
|
||||
get_model_group_from_litellm_kwargs,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1317,7 +1317,7 @@ class LiteLLMProxyRequestSetup:
|
|||
)
|
||||
|
||||
|
||||
async def add_litellm_data_to_request( # noqa: PLR0915
|
||||
async def add_litellm_data_to_request(
|
||||
data: dict,
|
||||
request: Request,
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
|
|
|
|||
|
|
@ -726,7 +726,7 @@ def _key_metadata(
|
|||
return KeyMetadata(key_alias=meta.get("key_alias"), team_id=meta.get("team_id"))
|
||||
|
||||
|
||||
def _aggregate_grouping_sets_records_sync( # noqa: PLR0915
|
||||
def _aggregate_grouping_sets_records_sync(
|
||||
*,
|
||||
records: List[Any],
|
||||
api_key_metadata: Dict[str, Dict[str, Any]],
|
||||
|
|
|
|||
|
|
@ -675,7 +675,7 @@ def _enforce_upperbound_key_params(
|
|||
)
|
||||
|
||||
|
||||
async def _common_key_generation_helper( # noqa: PLR0915
|
||||
async def _common_key_generation_helper(
|
||||
data: GenerateKeyRequest,
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
litellm_changed_by: Optional[str],
|
||||
|
|
@ -3419,7 +3419,7 @@ def _check_model_access_group(
|
|||
return True
|
||||
|
||||
|
||||
async def generate_key_helper_fn( # noqa: PLR0915
|
||||
async def generate_key_helper_fn(
|
||||
request_type: Literal[
|
||||
"user", "key"
|
||||
], # identifies if this request is from /user/new or /key/generate
|
||||
|
|
@ -4070,7 +4070,7 @@ async def delete_key_aliases(
|
|||
)
|
||||
|
||||
|
||||
async def _rotate_master_key( # noqa: PLR0915
|
||||
async def _rotate_master_key(
|
||||
prisma_client: PrismaClient,
|
||||
user_api_key_dict: UserAPIKeyAuth,
|
||||
current_master_key: str,
|
||||
|
|
|
|||
|
|
@ -933,7 +933,7 @@ def _check_team_budget_update_authority(
|
|||
response_model=LiteLLM_TeamTable,
|
||||
)
|
||||
@management_endpoint_wrapper
|
||||
async def new_team( # noqa: PLR0915
|
||||
async def new_team(
|
||||
data: NewTeamRequest,
|
||||
http_request: Request,
|
||||
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
|
||||
|
|
@ -1637,7 +1637,7 @@ def validate_team_org_change(
|
|||
"/team/update", tags=["team management"], dependencies=[Depends(user_api_key_auth)]
|
||||
)
|
||||
@management_endpoint_wrapper
|
||||
async def update_team( # noqa: PLR0915
|
||||
async def update_team(
|
||||
data: UpdateTeamRequest,
|
||||
http_request: Request,
|
||||
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
|
||||
|
|
|
|||
|
|
@ -145,6 +145,9 @@ _CLI_SSO_START_RATE_LIMIT_WINDOW_SECONDS = 60
|
|||
_CLI_SSO_START_RATE_LIMIT_MAX_ATTEMPTS = 30
|
||||
_CLI_SSO_USER_CODE_ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"
|
||||
_CLI_SSO_LOGIN_ID_RE = re.compile(r"^cli-[A-Za-z0-9_-]{12,124}$")
|
||||
_CLI_SSO_USER_CODE_RE = re.compile(
|
||||
rf"^[{_CLI_SSO_USER_CODE_ALPHABET}]{{4}}-[{_CLI_SSO_USER_CODE_ALPHABET}]{{4}}$"
|
||||
)
|
||||
_CLI_SSO_SCALAR_TYPES = (str, int, float, bool)
|
||||
_CLI_SSO_DEST_KEY_RE = re.compile(r"^[A-Za-z0-9_.-]+$")
|
||||
_CLI_SSO_SECRET_KEY_FRAGMENTS = frozenset(
|
||||
|
|
@ -182,6 +185,45 @@ def _is_valid_cli_sso_login_id(login_id: Optional[str]) -> bool:
|
|||
return isinstance(login_id, str) and bool(_CLI_SSO_LOGIN_ID_RE.fullmatch(login_id))
|
||||
|
||||
|
||||
def _is_valid_cli_sso_user_code(user_code: str | None) -> bool:
|
||||
return isinstance(user_code, str) and bool(
|
||||
_CLI_SSO_USER_CODE_RE.fullmatch(user_code)
|
||||
)
|
||||
|
||||
|
||||
def _cli_sso_verification_uri_complete_enabled() -> bool:
|
||||
from litellm.proxy.proxy_server import general_settings
|
||||
|
||||
return bool(
|
||||
general_settings.get( # any-ok: operator opt-in read from the untyped general_settings dict
|
||||
"allow_cli_sso_verification_uri_complete", False
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _cli_sso_start_response_body(
|
||||
*,
|
||||
login_id: str,
|
||||
poll_secret: str,
|
||||
user_code: str,
|
||||
verification_uri_complete: str | None,
|
||||
) -> dict[str, str | int]:
|
||||
if verification_uri_complete is None:
|
||||
return {
|
||||
"login_id": login_id,
|
||||
"poll_secret": poll_secret,
|
||||
"user_code": user_code,
|
||||
"expires_in": CLI_SSO_SESSION_TTL_SECONDS,
|
||||
}
|
||||
return {
|
||||
"login_id": login_id,
|
||||
"poll_secret": poll_secret,
|
||||
"user_code": user_code,
|
||||
"verification_uri_complete": verification_uri_complete,
|
||||
"expires_in": CLI_SSO_SESSION_TTL_SECONDS,
|
||||
}
|
||||
|
||||
|
||||
def _get_cli_sso_start_rate_limit_cache_key(
|
||||
request: Request, use_x_forwarded_for: Optional[bool] = False
|
||||
) -> str:
|
||||
|
|
@ -478,10 +520,20 @@ def _cli_poll_attribution_metadata_from_session(
|
|||
|
||||
|
||||
def _render_cli_sso_verification_page(
|
||||
verify_url: str, browser_complete_token: str
|
||||
verify_url: str,
|
||||
browser_complete_token: str,
|
||||
prefill_user_code: str | None = None,
|
||||
) -> str:
|
||||
escaped_verify_url = escape(verify_url, quote=True)
|
||||
escaped_browser_complete_token = escape(browser_complete_token, quote=True)
|
||||
user_code_value_attr = (
|
||||
f' value="{escape(prefill_user_code, quote=True)}"' if prefill_user_code else ""
|
||||
)
|
||||
instructions = (
|
||||
"Confirm the verification code below to finish this login."
|
||||
if prefill_user_code
|
||||
else "Enter the verification code shown in your terminal to finish this login."
|
||||
)
|
||||
return f"""
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
|
@ -535,11 +587,11 @@ def _render_cli_sso_verification_page(
|
|||
<body>
|
||||
<main>
|
||||
<h1>Complete CLI Login</h1>
|
||||
<p>Enter the verification code shown in your terminal to finish this login.</p>
|
||||
<p>{instructions}</p>
|
||||
<form method="post" action="{escaped_verify_url}">
|
||||
<input type="hidden" name="browser_complete_token" value="{escaped_browser_complete_token}" />
|
||||
<label for="user_code">Verification code</label>
|
||||
<input id="user_code" name="user_code" autocomplete="one-time-code" required autofocus />
|
||||
<input id="user_code" name="user_code" autocomplete="one-time-code"{user_code_value_attr} required autofocus />
|
||||
<button type="submit">Continue</button>
|
||||
</form>
|
||||
</main>
|
||||
|
|
@ -573,12 +625,29 @@ async def cli_sso_start(request: Request):
|
|||
}
|
||||
_set_cli_sso_flow(login_id=login_id, cache=user_api_key_cache, flow=flow)
|
||||
|
||||
return {
|
||||
"login_id": login_id,
|
||||
"poll_secret": poll_secret,
|
||||
"user_code": user_code,
|
||||
"expires_in": CLI_SSO_SESSION_TTL_SECONDS,
|
||||
}
|
||||
verification_uri_complete: str | None = (
|
||||
(
|
||||
get_custom_url(
|
||||
request_base_url=str(request.base_url), route="sso/key/generate"
|
||||
)
|
||||
+ "?"
|
||||
+ urlencode(
|
||||
{
|
||||
"source": LITELLM_CLI_SOURCE_IDENTIFIER,
|
||||
"key": login_id,
|
||||
"user_code": user_code,
|
||||
}
|
||||
)
|
||||
)
|
||||
if _cli_sso_verification_uri_complete_enabled()
|
||||
else None
|
||||
)
|
||||
return _cli_sso_start_response_body(
|
||||
login_id=login_id,
|
||||
poll_secret=poll_secret,
|
||||
user_code=user_code,
|
||||
verification_uri_complete=verification_uri_complete,
|
||||
)
|
||||
|
||||
|
||||
@router.post(
|
||||
|
|
@ -829,6 +898,7 @@ async def google_login(
|
|||
key: Optional[str] = None,
|
||||
existing_key: Optional[str] = None,
|
||||
return_to: Optional[str] = None,
|
||||
user_code: str | None = None,
|
||||
):
|
||||
"""
|
||||
Create Proxy API Keys using Google Workspace SSO. Requires setting PROXY_BASE_URL in .env
|
||||
|
|
@ -897,6 +967,7 @@ async def google_login(
|
|||
cli_state: Optional[str] = SSOAuthenticationHandler._get_cli_state(
|
||||
source=source,
|
||||
key=key,
|
||||
user_code=(user_code if _cli_sso_verification_uri_complete_enabled() else None),
|
||||
)
|
||||
|
||||
# check if user defined a custom auth sso sign in handler, if yes, use it
|
||||
|
|
@ -1921,14 +1992,16 @@ async def auth_callback(request: Request, state: Optional[str] = None):
|
|||
)
|
||||
|
||||
if state and state.startswith(f"{LITELLM_CLI_SESSION_TOKEN_PREFIX}:"):
|
||||
# State format: {PREFIX}:{login_id}
|
||||
state_parts = state.split(":", 1)
|
||||
# State format: {PREFIX}:{login_id}[:{user_code}]
|
||||
state_parts = state.split(":", 2)
|
||||
key_id = state_parts[1] if len(state_parts) > 1 else None
|
||||
prefill_user_code = state_parts[2] if len(state_parts) > 2 else None
|
||||
|
||||
verbose_proxy_logger.info("CLI SSO callback detected")
|
||||
return await cli_sso_callback(
|
||||
request=request,
|
||||
key=key_id,
|
||||
prefill_user_code=prefill_user_code,
|
||||
result=result,
|
||||
received_response=received_response,
|
||||
)
|
||||
|
|
@ -2008,6 +2081,7 @@ async def _complete_cli_sso_callback_session(
|
|||
prisma_client: PrismaClient,
|
||||
user_api_key_cache: UserApiKeyCache,
|
||||
proxy_logging_obj: ProxyLogging,
|
||||
prefill_user_code: str | None = None,
|
||||
):
|
||||
from fastapi.responses import HTMLResponse
|
||||
|
||||
|
|
@ -2071,6 +2145,7 @@ async def _complete_cli_sso_callback_session(
|
|||
content=_render_cli_sso_verification_page(
|
||||
verify_url=verify_url,
|
||||
browser_complete_token=browser_complete_token,
|
||||
prefill_user_code=prefill_user_code,
|
||||
),
|
||||
status_code=200,
|
||||
)
|
||||
|
|
@ -2081,6 +2156,7 @@ async def cli_sso_callback(
|
|||
key: Optional[str] = None,
|
||||
result: Optional[Union[OpenID, dict]] = None,
|
||||
received_response: Optional[dict] = None,
|
||||
prefill_user_code: str | None = None,
|
||||
):
|
||||
"""CLI SSO callback - stores session info for JWT generation on polling"""
|
||||
verbose_proxy_logger.info("CLI SSO callback")
|
||||
|
|
@ -2137,6 +2213,7 @@ async def cli_sso_callback(
|
|||
prisma_client=prisma_client,
|
||||
user_api_key_cache=user_api_key_cache,
|
||||
proxy_logging_obj=proxy_logging_obj,
|
||||
prefill_user_code=prefill_user_code,
|
||||
)
|
||||
except ProxyException:
|
||||
raise
|
||||
|
|
@ -3053,21 +3130,27 @@ class SSOAuthenticationHandler:
|
|||
|
||||
@staticmethod
|
||||
def _get_cli_state(
|
||||
source: Optional[str], key: Optional[str], existing_key: Optional[str] = None
|
||||
source: str | None,
|
||||
key: str | None,
|
||||
existing_key: str | None = None,
|
||||
user_code: str | None = None,
|
||||
) -> Optional[str]:
|
||||
"""
|
||||
Checks the request 'source' if a cli state token was passed in
|
||||
|
||||
This is used to authenticate through the CLI login flow.
|
||||
|
||||
The state parameter format is: {PREFIX}:{login_id}
|
||||
The state parameter format is: {PREFIX}:{login_id}[:{user_code}]
|
||||
- The state parameter is used to pass data through the OAuth flow without changing the callback URL
|
||||
- user_code is appended only for the opt-in verification_uri_complete flow so the verify page can pre-fill it
|
||||
"""
|
||||
from litellm.constants import (
|
||||
LITELLM_CLI_SESSION_TOKEN_PREFIX,
|
||||
)
|
||||
|
||||
if source == LITELLM_CLI_SOURCE_IDENTIFIER and key:
|
||||
if _is_valid_cli_sso_user_code(user_code):
|
||||
return f"{LITELLM_CLI_SESSION_TOKEN_PREFIX}:{key}:{user_code}"
|
||||
return f"{LITELLM_CLI_SESSION_TOKEN_PREFIX}:{key}"
|
||||
else:
|
||||
return None
|
||||
|
|
@ -3145,7 +3228,7 @@ class SSOAuthenticationHandler:
|
|||
)
|
||||
|
||||
@staticmethod
|
||||
async def get_redirect_response_from_openid( # noqa: PLR0915
|
||||
async def get_redirect_response_from_openid(
|
||||
result: Union[OpenID, dict, CustomOpenID],
|
||||
request: Request,
|
||||
received_response: Optional[dict] = None,
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ async def route_create_file(
|
|||
dependencies=[Depends(user_api_key_auth)],
|
||||
tags=["files"],
|
||||
)
|
||||
async def create_file( # noqa: PLR0915
|
||||
async def create_file(
|
||||
request: Request,
|
||||
fastapi_response: Response,
|
||||
purpose: str = Form(...),
|
||||
|
|
@ -589,7 +589,7 @@ async def create_file( # noqa: PLR0915
|
|||
dependencies=[Depends(user_api_key_auth)],
|
||||
tags=["files"],
|
||||
)
|
||||
async def get_file_content( # noqa: PLR0915
|
||||
async def get_file_content(
|
||||
request: Request,
|
||||
fastapi_response: Response,
|
||||
file_id: str,
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@ class AnthropicPassthroughLoggingHandler:
|
|||
)
|
||||
|
||||
@staticmethod
|
||||
def _collapse_pure_text_chunks( # noqa: PLR0915
|
||||
def _collapse_pure_text_chunks(
|
||||
all_chunks: Sequence[Union[str, bytes]],
|
||||
) -> Optional[List[str]]:
|
||||
"""
|
||||
|
|
@ -551,7 +551,7 @@ class AnthropicPassthroughLoggingHandler:
|
|||
return complete_streaming_response
|
||||
|
||||
@staticmethod
|
||||
def batch_creation_handler( # noqa: PLR0915
|
||||
def batch_creation_handler(
|
||||
httpx_response: httpx.Response,
|
||||
logging_obj: LiteLLMLoggingObj,
|
||||
url_route: str,
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ class OpenAIPassthroughLoggingHandler(BasePassthroughLoggingHandler):
|
|||
return litellm_model_response, response_cost
|
||||
|
||||
@staticmethod
|
||||
def openai_passthrough_handler( # noqa: PLR0915
|
||||
def openai_passthrough_handler(
|
||||
httpx_response: httpx.Response,
|
||||
response_body: dict,
|
||||
logging_obj: LiteLLMLoggingObj,
|
||||
|
|
|
|||
|
|
@ -645,7 +645,7 @@ class VertexPassthroughLoggingHandler:
|
|||
return kwargs
|
||||
|
||||
@staticmethod
|
||||
def batch_prediction_jobs_handler( # noqa: PLR0915
|
||||
def batch_prediction_jobs_handler(
|
||||
httpx_response: httpx.Response,
|
||||
logging_obj: LiteLLMLoggingObj,
|
||||
url_route: str,
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ async def set_env_variables_in_header(custom_headers: Optional[dict]) -> Optiona
|
|||
return headers
|
||||
|
||||
|
||||
async def chat_completion_pass_through_endpoint( # noqa: PLR0915
|
||||
async def chat_completion_pass_through_endpoint(
|
||||
fastapi_response: Response,
|
||||
request: Request,
|
||||
adapter_id: str,
|
||||
|
|
@ -701,7 +701,7 @@ from litellm.passthrough.timeout_utils import (
|
|||
)
|
||||
|
||||
|
||||
async def pass_through_request( # noqa: PLR0915
|
||||
async def pass_through_request(
|
||||
request: Request,
|
||||
target: str,
|
||||
custom_headers: dict,
|
||||
|
|
@ -1540,7 +1540,7 @@ async def _parse_request_data_by_content_type(
|
|||
return query_params_data, custom_body_data, file_data, stream
|
||||
|
||||
|
||||
def create_pass_through_route( # noqa: PLR0915
|
||||
def create_pass_through_route(
|
||||
endpoint,
|
||||
target: str,
|
||||
custom_headers: Optional[Mapping[str, Any]] = None,
|
||||
|
|
@ -1776,7 +1776,7 @@ def create_websocket_passthrough_route(
|
|||
return websocket_endpoint_func
|
||||
|
||||
|
||||
async def websocket_passthrough_request( # noqa: PLR0915
|
||||
async def websocket_passthrough_request(
|
||||
websocket: WebSocket,
|
||||
target: str,
|
||||
custom_headers: dict,
|
||||
|
|
|
|||
|
|
@ -814,7 +814,7 @@ class ProxyInitializationHelpers:
|
|||
default=False,
|
||||
help="Enable uvicorn hot reload (dev only). Also reloads when the --config YAML file changes. Incompatible with --num_workers>1, --run_gunicorn, and --run_hypercorn.",
|
||||
)
|
||||
def run_server( # noqa: PLR0915
|
||||
def run_server(
|
||||
cli_args,
|
||||
host,
|
||||
port,
|
||||
|
|
|
|||
|
|
@ -745,7 +745,7 @@ async def _initialize_shared_aiohttp_session():
|
|||
|
||||
|
||||
@asynccontextmanager
|
||||
async def proxy_startup_event(app: FastAPI): # noqa: PLR0915
|
||||
async def proxy_startup_event(app: FastAPI):
|
||||
global prisma_client, master_key, use_background_health_checks, llm_router, llm_model_list, general_settings, proxy_budget_rescheduler_min_time, proxy_budget_rescheduler_max_time, litellm_proxy_admin_name, db_writer_client, store_model_in_db, premium_user, _license_check, proxy_batch_polling_interval, shared_aiohttp_session
|
||||
import json
|
||||
|
||||
|
|
@ -2496,7 +2496,7 @@ async def _invalidate_spend_counter(counter_key: str):
|
|||
)
|
||||
|
||||
|
||||
async def update_cache( # noqa: PLR0915
|
||||
async def update_cache(
|
||||
token: Optional[str],
|
||||
user_id: Optional[str],
|
||||
end_user_id: Optional[str],
|
||||
|
|
@ -3900,7 +3900,7 @@ class ProxyConfig:
|
|||
premium_user = _license_check.is_premium()
|
||||
return
|
||||
|
||||
async def load_config( # noqa: PLR0915
|
||||
async def load_config(
|
||||
self, router: Optional[litellm.Router], config_file_path: str
|
||||
):
|
||||
"""
|
||||
|
|
@ -6631,7 +6631,7 @@ def save_worker_config(**data):
|
|||
os.environ["WORKER_CONFIG"] = json.dumps(data)
|
||||
|
||||
|
||||
async def initialize( # noqa: PLR0915
|
||||
async def initialize(
|
||||
model=None,
|
||||
alias=None,
|
||||
api_base=None,
|
||||
|
|
@ -7022,7 +7022,7 @@ def _format_streaming_sse_chunk(chunk: Union[str, bytes]) -> Union[str, bytes]:
|
|||
return f"data: {chunk}\n\n"
|
||||
|
||||
|
||||
async def async_data_generator( # noqa: PLR0915
|
||||
async def async_data_generator(
|
||||
response, user_api_key_dict: UserAPIKeyAuth, request_data: dict
|
||||
):
|
||||
verbose_proxy_logger.debug("inside generator")
|
||||
|
|
@ -7470,7 +7470,7 @@ class ProxyStartupEvent:
|
|||
)
|
||||
|
||||
@classmethod
|
||||
async def initialize_scheduled_background_jobs( # noqa: PLR0915
|
||||
async def initialize_scheduled_background_jobs(
|
||||
cls,
|
||||
general_settings: dict,
|
||||
prisma_client: PrismaClient,
|
||||
|
|
@ -8681,7 +8681,7 @@ async def chat_completion(
|
|||
dependencies=[Depends(user_api_key_auth)],
|
||||
tags=["completions"],
|
||||
)
|
||||
async def completion( # noqa: PLR0915
|
||||
async def completion(
|
||||
request: Request,
|
||||
fastapi_response: Response,
|
||||
model: Optional[str] = None,
|
||||
|
|
@ -14411,7 +14411,7 @@ async def invitation_delete(
|
|||
dependencies=[Depends(user_api_key_auth)],
|
||||
include_in_schema=False,
|
||||
)
|
||||
async def update_config( # noqa: PLR0915
|
||||
async def update_config(
|
||||
config_info: ConfigYAML,
|
||||
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
|
||||
):
|
||||
|
|
@ -15028,7 +15028,7 @@ async def delete_callback(
|
|||
include_in_schema=False,
|
||||
dependencies=[Depends(user_api_key_auth)],
|
||||
)
|
||||
async def get_config(): # noqa: PLR0915
|
||||
async def get_config():
|
||||
"""
|
||||
For Admin UI - allows admin to view config via UI
|
||||
# return the callbacks and the env variables for the callback
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ from litellm.proxy.response_polling.polling_handler import ResponsePollingHandle
|
|||
from litellm.types.llms.openai import ResponsesAPIStatus
|
||||
|
||||
|
||||
async def background_streaming_task( # noqa: PLR0915
|
||||
async def background_streaming_task(
|
||||
polling_id: str,
|
||||
data: dict,
|
||||
polling_handler: ResponsePollingHandler,
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ async def add_shared_session_to_data(data: dict) -> None:
|
|||
pass
|
||||
|
||||
|
||||
async def route_request( # noqa: PLR0915 - Complex routing function, refactoring tracked separately
|
||||
async def route_request(
|
||||
data: dict,
|
||||
llm_router: Optional[LitellmRouter],
|
||||
user_model: Optional[str],
|
||||
|
|
|
|||
|
|
@ -1734,7 +1734,7 @@ async def calculate_spend(request: SpendCalculateRequest):
|
|||
200: {"model": List[LiteLLM_SpendLogs]},
|
||||
},
|
||||
)
|
||||
async def ui_view_spend_logs( # noqa: PLR0915
|
||||
async def ui_view_spend_logs(
|
||||
request: Request,
|
||||
api_key: Optional[str] = fastapi.Query(
|
||||
default=None,
|
||||
|
|
@ -2273,7 +2273,7 @@ async def ui_view_request_response_for_request_id(
|
|||
200: {"model": List[LiteLLM_SpendLogs]},
|
||||
},
|
||||
)
|
||||
async def view_spend_logs( # noqa: PLR0915
|
||||
async def view_spend_logs(
|
||||
api_key: Optional[str] = fastapi.Query(
|
||||
default=None,
|
||||
description="Get spend logs based on api key",
|
||||
|
|
|
|||
|
|
@ -228,9 +228,7 @@ def _extract_usage_for_ocr_call(response_obj: Any, response_obj_dict: dict) -> d
|
|||
return {}
|
||||
|
||||
|
||||
def get_logging_payload( # noqa: PLR0915
|
||||
kwargs, response_obj, start_time, end_time
|
||||
) -> SpendLogsPayload:
|
||||
def get_logging_payload(kwargs, response_obj, start_time, end_time) -> SpendLogsPayload:
|
||||
if kwargs is None:
|
||||
kwargs = {}
|
||||
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ async def arealtime_calls(
|
|||
|
||||
|
||||
@wrapper_client
|
||||
async def _arealtime( # noqa: PLR0915
|
||||
async def _arealtime(
|
||||
model: str,
|
||||
websocket: Any, # fastapi websocket
|
||||
api_base: Optional[str] = None,
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ async def arerank(
|
|||
|
||||
|
||||
@client
|
||||
def rerank( # noqa: PLR0915
|
||||
def rerank(
|
||||
model: str,
|
||||
query: str,
|
||||
documents: List[Union[str, Dict[str, Any]]],
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ def _add_mcp_metadata_to_response(
|
|||
setattr(message, "provider_specific_fields", provider_fields)
|
||||
|
||||
|
||||
async def acompletion_with_mcp( # noqa: PLR0915
|
||||
async def acompletion_with_mcp(
|
||||
model: str,
|
||||
messages: List,
|
||||
tools: Optional[List] = None,
|
||||
|
|
|
|||
|
|
@ -644,7 +644,7 @@ class LiteLLM_Proxy_MCP_Handler:
|
|||
return result_text or "Tool executed successfully"
|
||||
|
||||
@staticmethod
|
||||
async def _execute_tool_calls( # noqa: PLR0915
|
||||
async def _execute_tool_calls(
|
||||
tool_server_map: dict[str, str],
|
||||
tool_calls: List[Any],
|
||||
user_api_key_auth: Any,
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ class Router:
|
|||
lowesttpm_logger: Optional[LowestTPMLoggingHandler] = None
|
||||
optional_callbacks: Optional[List[Union[CustomLogger, Callable, str]]] = None
|
||||
|
||||
def __init__( # noqa: PLR0915
|
||||
def __init__(
|
||||
self,
|
||||
model_list: Optional[
|
||||
Union[List[DeploymentTypedDict], List[Dict[str, Any]]]
|
||||
|
|
@ -2887,7 +2887,7 @@ class Router:
|
|||
f"Silent experiment failed for model {silent_model}: {str(e)}"
|
||||
)
|
||||
|
||||
async def _acompletion( # noqa: PLR0915
|
||||
async def _acompletion(
|
||||
self, model: str, messages: List[Dict[str, str]], **kwargs
|
||||
) -> Union[
|
||||
ModelResponse,
|
||||
|
|
@ -5158,7 +5158,7 @@ class Router:
|
|||
)
|
||||
raise e
|
||||
|
||||
async def _acreate_file( # noqa: PLR0915
|
||||
async def _acreate_file(
|
||||
self,
|
||||
model: str,
|
||||
**kwargs,
|
||||
|
|
@ -6467,7 +6467,7 @@ class Router:
|
|||
# propagate so they remain visible.
|
||||
return None
|
||||
|
||||
async def async_function_with_fallbacks_common_utils( # noqa: PLR0915
|
||||
async def async_function_with_fallbacks_common_utils(
|
||||
self,
|
||||
e: Exception,
|
||||
disable_fallbacks: Optional[bool],
|
||||
|
|
@ -6843,7 +6843,7 @@ class Router:
|
|||
)
|
||||
|
||||
@tracer.wrap()
|
||||
async def async_function_with_retries(self, *args, **kwargs): # noqa: PLR0915
|
||||
async def async_function_with_retries(self, *args, **kwargs):
|
||||
verbose_router_logger.debug("Inside async function with retries.")
|
||||
original_function = kwargs.pop("original_function")
|
||||
fallbacks = kwargs.pop("fallbacks", self.fallbacks)
|
||||
|
|
@ -9324,7 +9324,7 @@ class Router:
|
|||
|
||||
return model_info
|
||||
|
||||
def _set_model_group_info( # noqa: PLR0915
|
||||
def _set_model_group_info(
|
||||
self, model_group: str, user_facing_model_group_name: str
|
||||
) -> Optional[ModelGroupInfo]:
|
||||
"""
|
||||
|
|
@ -10566,7 +10566,7 @@ class Router:
|
|||
)
|
||||
return client
|
||||
|
||||
def _pre_call_checks( # noqa: PLR0915
|
||||
def _pre_call_checks(
|
||||
self,
|
||||
model: str,
|
||||
healthy_deployments: List,
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ class LowestCostLoggingHandler(CustomLogger):
|
|||
)
|
||||
pass
|
||||
|
||||
async def async_get_available_deployments( # noqa: PLR0915
|
||||
async def async_get_available_deployments(
|
||||
self,
|
||||
model_group: str,
|
||||
healthy_deployments: list,
|
||||
|
|
|
|||
|
|
@ -35,9 +35,7 @@ class LowestLatencyLoggingHandler(CustomLogger):
|
|||
self.router_cache = router_cache
|
||||
self.routing_args = RoutingArgs(**routing_args)
|
||||
|
||||
def log_success_event( # noqa: PLR0915
|
||||
self, kwargs, response_obj, start_time, end_time
|
||||
):
|
||||
def log_success_event(self, kwargs, response_obj, start_time, end_time):
|
||||
try:
|
||||
"""
|
||||
Update latency usage on success
|
||||
|
|
@ -259,9 +257,7 @@ class LowestLatencyLoggingHandler(CustomLogger):
|
|||
)
|
||||
pass
|
||||
|
||||
async def async_log_success_event( # noqa: PLR0915
|
||||
self, kwargs, response_obj, start_time, end_time
|
||||
):
|
||||
async def async_log_success_event(self, kwargs, response_obj, start_time, end_time):
|
||||
try:
|
||||
"""
|
||||
Update latency usage on success
|
||||
|
|
@ -413,7 +409,7 @@ class LowestLatencyLoggingHandler(CustomLogger):
|
|||
)
|
||||
pass
|
||||
|
||||
def _get_available_deployments( # noqa: PLR0915
|
||||
def _get_available_deployments(
|
||||
self,
|
||||
model_group: str,
|
||||
healthy_deployments: list,
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ class LowestTPMLoggingHandler(CustomLogger):
|
|||
verbose_router_logger.debug(traceback.format_exc())
|
||||
pass
|
||||
|
||||
def get_available_deployments( # noqa: PLR0915
|
||||
def get_available_deployments(
|
||||
self,
|
||||
model_group: str,
|
||||
healthy_deployments: list,
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ def get_secret_bool(
|
|||
return str_to_bool(_secret_value)
|
||||
|
||||
|
||||
def get_secret( # noqa: PLR0915
|
||||
def get_secret(
|
||||
secret_name: str,
|
||||
default_value: Optional[Union[str, bool]] = None,
|
||||
):
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ def _is_base64(s):
|
|||
return False
|
||||
|
||||
|
||||
def get_secret_from_manager( # noqa: PLR0915
|
||||
def get_secret_from_manager(
|
||||
client: Any,
|
||||
key_manager: str,
|
||||
secret_name: str,
|
||||
|
|
|
|||
|
|
@ -1572,7 +1572,7 @@ class Usage(SafeAttributeModel, CompletionUsage):
|
|||
prompt_tokens_details: Optional[PromptTokensDetailsWrapper] = None
|
||||
"""Breakdown of tokens used in the prompt."""
|
||||
|
||||
def __init__( # noqa: PLR0915
|
||||
def __init__(
|
||||
self,
|
||||
prompt_tokens: Optional[int] = None,
|
||||
completion_tokens: Optional[int] = None,
|
||||
|
|
@ -1908,7 +1908,7 @@ class ModelResponse(ModelResponseBase):
|
|||
choices: List[Choices]
|
||||
"""The list of completion choices the model generated for the input prompt."""
|
||||
|
||||
def __init__( # noqa: PLR0915
|
||||
def __init__(
|
||||
self,
|
||||
id=None,
|
||||
choices=None,
|
||||
|
|
|
|||
|
|
@ -760,7 +760,7 @@ def _remove_thought_signatures_from_messages(
|
|||
return processed_messages
|
||||
|
||||
|
||||
def function_setup( # noqa: PLR0915
|
||||
def function_setup(
|
||||
original_function: str, rules_obj, start_time, *args, **kwargs
|
||||
): # just run once to check if user wants to send their data anywhere - PostHog/Sentry/Slack/etc.
|
||||
### NOTICES ###
|
||||
|
|
@ -1422,12 +1422,12 @@ def post_call_processing(
|
|||
raise e
|
||||
|
||||
|
||||
def client(original_function): # noqa: PLR0915
|
||||
def client(original_function):
|
||||
Rules = getattr(sys.modules[__name__], "Rules")
|
||||
rules_obj = Rules()
|
||||
|
||||
@wraps(original_function)
|
||||
def wrapper(*args, **kwargs): # noqa: PLR0915
|
||||
def wrapper(*args, **kwargs):
|
||||
# DO NOT MOVE THIS. It always needs to run first
|
||||
# Check if this is an async function. If so only execute the async function
|
||||
call_type = original_function.__name__
|
||||
|
|
@ -1775,7 +1775,7 @@ def client(original_function): # noqa: PLR0915
|
|||
raise e
|
||||
|
||||
@wraps(original_function)
|
||||
async def wrapper_async(*args, **kwargs): # noqa: PLR0915
|
||||
async def wrapper_async(*args, **kwargs):
|
||||
print_args_passed_to_litellm(original_function, args, kwargs)
|
||||
start_time = datetime.datetime.now()
|
||||
result = None
|
||||
|
|
@ -2942,7 +2942,7 @@ def _resolve_builtin_model_cost_entry(
|
|||
return None
|
||||
|
||||
|
||||
def register_model(model_cost: Union[str, dict]): # noqa: PLR0915
|
||||
def register_model(model_cost: Union[str, dict]):
|
||||
"""
|
||||
Register new / Override existing models (and their pricing) to specific providers.
|
||||
Provide EITHER a model cost dictionary or a url to a hosted json blob
|
||||
|
|
@ -3365,7 +3365,7 @@ def get_optional_params_image_gen(
|
|||
return optional_params
|
||||
|
||||
|
||||
def get_optional_params_embeddings( # noqa: PLR0915
|
||||
def get_optional_params_embeddings(
|
||||
# 2 optional params
|
||||
model: str,
|
||||
user: Optional[str] = None,
|
||||
|
|
@ -4112,7 +4112,7 @@ def pre_process_optional_params(
|
|||
return optional_params
|
||||
|
||||
|
||||
def get_optional_params( # noqa: PLR0915
|
||||
def get_optional_params(
|
||||
# use the openai defaults
|
||||
# https://platform.openai.com/docs/api-reference/chat/create
|
||||
model: str,
|
||||
|
|
@ -5842,7 +5842,7 @@ def _is_potential_model_name_in_model_cost(
|
|||
)
|
||||
|
||||
|
||||
def _get_model_info_helper( # noqa: PLR0915
|
||||
def _get_model_info_helper(
|
||||
model: str,
|
||||
custom_llm_provider: Optional[str] = None,
|
||||
api_base: Optional[str] = None,
|
||||
|
|
@ -6566,7 +6566,7 @@ def create_proxy_transport_and_mounts():
|
|||
return sync_proxy_mounts, async_proxy_mounts
|
||||
|
||||
|
||||
def validate_environment( # noqa: PLR0915
|
||||
def validate_environment(
|
||||
model: Optional[str] = None,
|
||||
api_key: Optional[str] = None,
|
||||
api_base: Optional[str] = None,
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
{
|
||||
"ANN001": {
|
||||
"baseline": 2865,
|
||||
"slack": 10
|
||||
"slack": 50
|
||||
},
|
||||
"ANN002": {
|
||||
"baseline": 64,
|
||||
"slack": 3
|
||||
"slack": 5
|
||||
},
|
||||
"ANN003": {
|
||||
"baseline": 759,
|
||||
"slack": 10
|
||||
"slack": 30
|
||||
},
|
||||
"ANN201": {
|
||||
"baseline": 1944,
|
||||
"slack": 10
|
||||
"slack": 50
|
||||
},
|
||||
"ANN202": {
|
||||
"baseline": 858,
|
||||
"slack": 10
|
||||
"slack": 30
|
||||
},
|
||||
"ANN204": {
|
||||
"baseline": 658,
|
||||
"slack": 10
|
||||
"slack": 20
|
||||
},
|
||||
"ANN205": {
|
||||
"baseline": 117,
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
},
|
||||
"ANN401": {
|
||||
"baseline": 1886,
|
||||
"slack": 10
|
||||
"slack": 50
|
||||
},
|
||||
"ASYNC230": {
|
||||
"baseline": 11,
|
||||
|
|
@ -45,15 +45,15 @@
|
|||
},
|
||||
"B006": {
|
||||
"baseline": 180,
|
||||
"slack": 3
|
||||
"slack": 10
|
||||
},
|
||||
"B008": {
|
||||
"baseline": 490,
|
||||
"slack": 10
|
||||
"slack": 15
|
||||
},
|
||||
"B009": {
|
||||
"baseline": 79,
|
||||
"slack": 10
|
||||
"slack": 5
|
||||
},
|
||||
"B010": {
|
||||
"baseline": 187,
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
},
|
||||
"BLE001": {
|
||||
"baseline": 2854,
|
||||
"slack": 10
|
||||
"slack": 50
|
||||
},
|
||||
"C401": {
|
||||
"baseline": 8,
|
||||
|
|
@ -109,7 +109,7 @@
|
|||
},
|
||||
"C901": {
|
||||
"baseline": 301,
|
||||
"slack": 3
|
||||
"slack": 15
|
||||
},
|
||||
"D419": {
|
||||
"baseline": 6,
|
||||
|
|
@ -125,7 +125,7 @@
|
|||
},
|
||||
"DTZ005": {
|
||||
"baseline": 229,
|
||||
"slack": 10
|
||||
"slack": 15
|
||||
},
|
||||
"DTZ006": {
|
||||
"baseline": 10,
|
||||
|
|
@ -165,7 +165,7 @@
|
|||
},
|
||||
"I001": {
|
||||
"baseline": 258,
|
||||
"slack": 10
|
||||
"slack": 15
|
||||
},
|
||||
"LOG015": {
|
||||
"baseline": 5,
|
||||
|
|
@ -189,11 +189,11 @@
|
|||
},
|
||||
"PERF403": {
|
||||
"baseline": 69,
|
||||
"slack": 10
|
||||
"slack": 5
|
||||
},
|
||||
"PIE790": {
|
||||
"baseline": 263,
|
||||
"slack": 10
|
||||
"slack": 15
|
||||
},
|
||||
"PIE800": {
|
||||
"baseline": 1,
|
||||
|
|
@ -233,7 +233,7 @@
|
|||
},
|
||||
"PLR0913": {
|
||||
"baseline": 1813,
|
||||
"slack": 3
|
||||
"slack": 50
|
||||
},
|
||||
"PLR1704": {
|
||||
"baseline": 3,
|
||||
|
|
@ -245,7 +245,7 @@
|
|||
},
|
||||
"PLR1714": {
|
||||
"baseline": 252,
|
||||
"slack": 10
|
||||
"slack": 15
|
||||
},
|
||||
"PLR1730": {
|
||||
"baseline": 7,
|
||||
|
|
@ -265,11 +265,11 @@
|
|||
},
|
||||
"PLW0602": {
|
||||
"baseline": 215,
|
||||
"slack": 10
|
||||
"slack": 15
|
||||
},
|
||||
"PLW0603": {
|
||||
"baseline": 183,
|
||||
"slack": 3
|
||||
"slack": 10
|
||||
},
|
||||
"PLW1508": {
|
||||
"baseline": 188,
|
||||
|
|
@ -301,15 +301,15 @@
|
|||
},
|
||||
"RET504": {
|
||||
"baseline": 709,
|
||||
"slack": 10
|
||||
"slack": 20
|
||||
},
|
||||
"RUF010": {
|
||||
"baseline": 844,
|
||||
"slack": 10
|
||||
"slack": 30
|
||||
},
|
||||
"RUF012": {
|
||||
"baseline": 158,
|
||||
"slack": 3
|
||||
"slack": 10
|
||||
},
|
||||
"RUF015": {
|
||||
"baseline": 8,
|
||||
|
|
@ -321,7 +321,7 @@
|
|||
},
|
||||
"RUF022": {
|
||||
"baseline": 80,
|
||||
"slack": 10
|
||||
"slack": 5
|
||||
},
|
||||
"RUF023": {
|
||||
"baseline": 2,
|
||||
|
|
@ -337,15 +337,15 @@
|
|||
},
|
||||
"RUF059": {
|
||||
"baseline": 69,
|
||||
"slack": 10
|
||||
"slack": 5
|
||||
},
|
||||
"RUF100": {
|
||||
"baseline": 465,
|
||||
"slack": 10
|
||||
"slack": 15
|
||||
},
|
||||
"S110": {
|
||||
"baseline": 222,
|
||||
"slack": 10
|
||||
"slack": 15
|
||||
},
|
||||
"S112": {
|
||||
"baseline": 21,
|
||||
|
|
@ -353,11 +353,11 @@
|
|||
},
|
||||
"SIM101": {
|
||||
"baseline": 58,
|
||||
"slack": 10
|
||||
"slack": 5
|
||||
},
|
||||
"SIM102": {
|
||||
"baseline": 311,
|
||||
"slack": 10
|
||||
"slack": 15
|
||||
},
|
||||
"SIM103": {
|
||||
"baseline": 119,
|
||||
|
|
@ -412,20 +412,20 @@
|
|||
"slack": 3
|
||||
},
|
||||
"TID251": {
|
||||
"baseline": 2405,
|
||||
"slack": 10
|
||||
"baseline": 2664,
|
||||
"slack": 50
|
||||
},
|
||||
"TRY002": {
|
||||
"baseline": 528,
|
||||
"slack": 10
|
||||
"slack": 20
|
||||
},
|
||||
"TRY004": {
|
||||
"baseline": 93,
|
||||
"slack": 10
|
||||
"slack": 5
|
||||
},
|
||||
"TRY201": {
|
||||
"baseline": 409,
|
||||
"slack": 10
|
||||
"slack": 15
|
||||
},
|
||||
"TRY203": {
|
||||
"baseline": 113,
|
||||
|
|
@ -433,15 +433,15 @@
|
|||
},
|
||||
"TRY300": {
|
||||
"baseline": 853,
|
||||
"slack": 10
|
||||
"slack": 30
|
||||
},
|
||||
"UP006": {
|
||||
"baseline": 12941,
|
||||
"slack": 10
|
||||
"slack": 100
|
||||
},
|
||||
"UP007": {
|
||||
"baseline": 2520,
|
||||
"slack": 10
|
||||
"slack": 50
|
||||
},
|
||||
"UP008": {
|
||||
"baseline": 2,
|
||||
|
|
@ -469,7 +469,7 @@
|
|||
},
|
||||
"UP032": {
|
||||
"baseline": 609,
|
||||
"slack": 10
|
||||
"slack": 20
|
||||
},
|
||||
"UP034": {
|
||||
"baseline": 1,
|
||||
|
|
@ -477,7 +477,7 @@
|
|||
},
|
||||
"UP035": {
|
||||
"baseline": 2250,
|
||||
"slack": 10
|
||||
"slack": 50
|
||||
},
|
||||
"UP036": {
|
||||
"baseline": 1,
|
||||
|
|
@ -485,10 +485,10 @@
|
|||
},
|
||||
"UP037": {
|
||||
"baseline": 100,
|
||||
"slack": 10
|
||||
"slack": 5
|
||||
},
|
||||
"UP045": {
|
||||
"baseline": 18417,
|
||||
"slack": 10
|
||||
"slack": 100
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue