perf: optimize python comprehensions and dictionary iterations

This PR resolves multiple Python performance recommendations from `ruff` (PERF401, PERF403, SIM118, C416, C420, UP015) across the codebase.

- Replaced `.keys()` on dict iterations with direct iteration for improved speed (SIM118)
- Streamlined unnecessary generator and dictionary comprehensions (C416, C420)
- Optimized file open modes and OS error aliases (UP015, UP024)

These are entirely safe AST-level syntactic updates that bring the codebase closer to modern Python best practices and marginally improve overhead on large looping operations.

*(Refactored using the open-source [0-editor](https://github.com/0-protocol/0-editor))*
This commit is contained in:
sjhddh 2026-03-29 08:15:03 +00:00
parent 5be0797d24
commit aebb0d04eb
87 changed files with 182 additions and 190 deletions

View file

@ -661,7 +661,7 @@ async def update_project( # noqa: PLR0915
}, },
) )
# Remove budget fields from project update # Remove budget fields from project update
for field in budget_updates.keys(): for field in budget_updates:
update_data.pop(field, None) update_data.pop(field, None)
# Handle object permissions # Handle object permissions

View file

@ -78,8 +78,8 @@ def get_optional_params_add_message(
optional_params = litellm.AzureOpenAIAssistantsAPIConfig().map_openai_params_create_message_params( optional_params = litellm.AzureOpenAIAssistantsAPIConfig().map_openai_params_create_message_params(
non_default_params=non_default_params, optional_params=optional_params non_default_params=non_default_params, optional_params=optional_params
) )
for k in passed_params.keys(): for k in passed_params:
if k not in default_params.keys(): if k not in default_params:
optional_params[k] = passed_params[k] optional_params[k] = passed_params[k]
return optional_params return optional_params
@ -155,7 +155,7 @@ def get_optional_params_image_gen(
if n is not None: if n is not None:
optional_params["sampleCount"] = int(n) optional_params["sampleCount"] = int(n)
for k in passed_params.keys(): for k in passed_params:
if k not in default_params.keys(): if k not in default_params:
optional_params[k] = passed_params[k] optional_params[k] = passed_params[k]
return optional_params return optional_params

View file

@ -170,7 +170,7 @@ def batch_completion_models(*args, **kwargs):
futures = {} futures = {}
with ThreadPoolExecutor(max_workers=len(deployments)) as executor: with ThreadPoolExecutor(max_workers=len(deployments)) as executor:
for deployment in deployments: for deployment in deployments:
for key in kwargs.keys(): for key in kwargs:
if ( if (
key not in deployment key not in deployment
): # don't override deployment values e.g. model name, api base, etc. ): # don't override deployment values e.g. model name, api base, etc.

View file

@ -52,7 +52,7 @@ class BudgetManager:
# Check if user dict file exists # Check if user dict file exists
if os.path.isfile("user_cost.json"): if os.path.isfile("user_cost.json"):
# Load the user dict # Load the user dict
with open("user_cost.json", "r") as json_file: with open("user_cost.json") as json_file:
self.user_dict = json.load(json_file) self.user_dict = json.load(json_file)
else: else:
self.print_verbose("User Dictionary not found!") self.print_verbose("User Dictionary not found!")

View file

@ -332,7 +332,7 @@ class LiteLLMResponsesTransformationHandler(CompletionTransformationBridge):
responses_api_request["tool_choice"] = ( # type: ignore[assignment] responses_api_request["tool_choice"] = ( # type: ignore[assignment]
self._normalize_tool_choice_for_responses_api(value) self._normalize_tool_choice_for_responses_api(value)
) )
elif key in ResponsesAPIOptionalRequestParams.__annotations__.keys(): elif key in ResponsesAPIOptionalRequestParams.__annotations__:
responses_api_request[key] = value # type: ignore responses_api_request[key] = value # type: ignore
elif key == "previous_response_id": elif key == "previous_response_id":
responses_api_request["previous_response_id"] = value responses_api_request["previous_response_id"] = value

View file

@ -693,7 +693,7 @@ OPENAI_TRANSCRIPTION_PARAMS = [
OPENAI_EMBEDDING_PARAMS = ["dimensions", "encoding_format", "user"] OPENAI_EMBEDDING_PARAMS = ["dimensions", "encoding_format", "user"]
DEFAULT_EMBEDDING_PARAM_VALUES = { DEFAULT_EMBEDDING_PARAM_VALUES = {
**{k: None for k in OPENAI_EMBEDDING_PARAMS}, **dict.fromkeys(OPENAI_EMBEDDING_PARAMS),
"model": None, "model": None,
"custom_llm_provider": "", "custom_llm_provider": "",
"input": None, "input": None,

View file

@ -546,7 +546,7 @@ class DataDogLLMObsLogger(CustomBatchLogger):
if isinstance(messages, str): if isinstance(messages, str):
return [messages] return [messages]
elif isinstance(messages, list): elif isinstance(messages, list):
return [message for message in messages] return list(messages)
elif isinstance(messages, dict): elif isinstance(messages, dict):
return [str(messages.get("content", ""))] return [str(messages.get("content", ""))]
return [] return []

View file

@ -31,7 +31,7 @@ class PromptTemplate:
self.output_format = self.metadata.get("output", {}).get("format") self.output_format = self.metadata.get("output", {}).get("format")
self.output_schema = self.metadata.get("output", {}).get("schema", {}) self.output_schema = self.metadata.get("output", {}).get("schema", {})
self.optional_params = {} self.optional_params = {}
for key in self.metadata.keys(): for key in self.metadata:
if key not in restricted_keys: if key not in restricted_keys:
self.optional_params[key] = self.metadata[key] self.optional_params[key] = self.metadata[key]

View file

@ -40,7 +40,7 @@ def load_compatible_callbacks() -> Dict:
json_path = os.path.join( json_path = os.path.join(
os.path.dirname(__file__), "generic_api_compatible_callbacks.json" os.path.dirname(__file__), "generic_api_compatible_callbacks.json"
) )
with open(json_path, "r") as f: with open(json_path) as f:
return json.load(f) return json.load(f)
except Exception as e: except Exception as e:
verbose_logger.warning( verbose_logger.warning(

View file

@ -78,9 +78,7 @@ class InteractionsAPIRequestUtils:
special_params=special_params, special_params=special_params,
custom_llm_provider=custom_llm_provider, custom_llm_provider=custom_llm_provider,
additional_drop_params=additional_drop_params, additional_drop_params=additional_drop_params,
default_param_values={ default_param_values=dict.fromkeys(INTERACTIONS_API_OPTIONAL_PARAMS),
k: None for k in INTERACTIONS_API_OPTIONAL_PARAMS
},
additional_endpoint_specific_params=["input", "model", "agent"], additional_endpoint_specific_params=["input", "model", "agent"],
) )
) )

View file

@ -179,7 +179,7 @@ def get_audio_file_content_hash(file_obj: FileTypes) -> str:
file_content = f.read() file_content = f.read()
if fallback_filename is None: if fallback_filename is None:
fallback_filename = str(file_content_obj) fallback_filename = str(file_content_obj)
except (OSError, IOError): except OSError:
fallback_filename = str(file_content_obj) fallback_filename = str(file_content_obj)
file_content = None file_content = None
elif hasattr(file_content_obj, "read"): elif hasattr(file_content_obj, "read"):
@ -194,7 +194,7 @@ def get_audio_file_content_hash(file_obj: FileTypes) -> str:
file_content = file_content_obj.read() # type: ignore file_content = file_content_obj.read() # type: ignore
if current_position is not None and hasattr(file_content_obj, "seek"): if current_position is not None and hasattr(file_content_obj, "seek"):
file_content_obj.seek(current_position) # type: ignore file_content_obj.seek(current_position) # type: ignore
except (OSError, IOError, AttributeError): except (OSError, AttributeError):
file_content = None file_content = None
else: else:
file_content = None file_content = None

View file

@ -25,9 +25,9 @@ def load_cli_token() -> Optional[dict]:
return None return None
try: try:
with open(token_file, "r") as f: with open(token_file) as f:
return json.load(f) return json.load(f)
except (json.JSONDecodeError, IOError): except (OSError, json.JSONDecodeError):
return None return None

View file

@ -5154,7 +5154,7 @@ class StandardLoggingPayloadSetup:
# Populate well-known typed fields with int/str coercion where needed # Populate well-known typed fields with int/str coercion where needed
typed_keys: dict = {} typed_keys: dict = {}
for key in StandardLoggingAdditionalHeaders.__annotations__.keys(): for key in StandardLoggingAdditionalHeaders.__annotations__:
_key = key.lower().replace("_", "-") _key = key.lower().replace("_", "-")
typed_keys[_key] = key typed_keys[_key] = key
if _key in additiona_headers: if _key in additiona_headers:
@ -5186,7 +5186,7 @@ class StandardLoggingPayloadSetup:
usage_object=None, usage_object=None,
) )
if hidden_params is not None: if hidden_params is not None:
for key in StandardLoggingHiddenParams.__annotations__.keys(): for key in StandardLoggingHiddenParams.__annotations__:
if key in hidden_params: if key in hidden_params:
if key == "additional_headers": if key == "additional_headers":
clean_hidden_params["additional_headers"] = ( clean_hidden_params["additional_headers"] = (
@ -5811,7 +5811,7 @@ def get_standard_logging_metadata(
) )
if isinstance(metadata, dict): if isinstance(metadata, dict):
# Update the clean_metadata with values from input metadata that match StandardLoggingMetadata fields # Update the clean_metadata with values from input metadata that match StandardLoggingMetadata fields
for key in StandardLoggingMetadata.__annotations__.keys(): for key in StandardLoggingMetadata.__annotations__:
if key in metadata: if key in metadata:
clean_metadata[key] = metadata[key] # type: ignore clean_metadata[key] = metadata[key] # type: ignore
@ -5886,16 +5886,16 @@ def create_dummy_standard_logging_payload() -> StandardLoggingPayload:
) )
metadata = StandardLoggingMetadata( # type: ignore metadata = StandardLoggingMetadata( # type: ignore
user_api_key_hash=str("test_hash"), user_api_key_hash="test_hash",
user_api_key_alias=str("test_alias"), user_api_key_alias="test_alias",
user_api_key_team_id=str("test_team"), user_api_key_team_id="test_team",
user_api_key_user_id=str("test_user"), user_api_key_user_id="test_user",
user_api_key_team_alias=str("test_team_alias"), user_api_key_team_alias="test_team_alias",
user_api_key_org_id=None, user_api_key_org_id=None,
spend_logs_metadata=None, spend_logs_metadata=None,
requester_ip_address=str("127.0.0.1"), requester_ip_address="127.0.0.1",
requester_metadata=None, requester_metadata=None,
user_api_key_end_user_id=str("test_end_user"), user_api_key_end_user_id="test_end_user",
) )
hidden_params = StandardLoggingHiddenParams( hidden_params = StandardLoggingHiddenParams(
@ -5925,12 +5925,12 @@ def create_dummy_standard_logging_payload() -> StandardLoggingPayload:
# Main payload initialization # Main payload initialization
return StandardLoggingPayload( # type: ignore return StandardLoggingPayload( # type: ignore
id=str("test_id"), id="test_id",
call_type=str("completion"), call_type="completion",
stream=bool(False), stream=False,
response_cost=response_cost, response_cost=response_cost,
response_cost_failure_debug_info=None, response_cost_failure_debug_info=None,
status=str("success"), status="success",
total_tokens=int( total_tokens=int(
DEFAULT_MOCK_RESPONSE_PROMPT_TOKEN_COUNT DEFAULT_MOCK_RESPONSE_PROMPT_TOKEN_COUNT
+ DEFAULT_MOCK_RESPONSE_COMPLETION_TOKEN_COUNT + DEFAULT_MOCK_RESPONSE_COMPLETION_TOKEN_COUNT
@ -5941,18 +5941,18 @@ def create_dummy_standard_logging_payload() -> StandardLoggingPayload:
endTime=end_time, endTime=end_time,
completionStartTime=completion_start_time, completionStartTime=completion_start_time,
model_map_information=model_info, model_map_information=model_info,
model=str("gpt-3.5-turbo"), model="gpt-3.5-turbo",
model_id=str("model-123"), model_id="model-123",
model_group=str("openai-gpt"), model_group="openai-gpt",
custom_llm_provider=str("openai"), custom_llm_provider="openai",
api_base=str("https://api.openai.com"), api_base="https://api.openai.com",
metadata=metadata, metadata=metadata,
cache_hit=bool(False), cache_hit=False,
cache_key=None, cache_key=None,
saved_cache_cost=saved_cache_cost, saved_cache_cost=saved_cache_cost,
request_tags=[], request_tags=[],
end_user=None, end_user=None,
requester_ip_address=str("127.0.0.1"), requester_ip_address="127.0.0.1",
messages=messages, messages=messages,
response=response, response=response,
error_str=None, error_str=None,

View file

@ -89,7 +89,7 @@ def _truncate_base64_in_value(value: Any) -> Any:
return value return value
# Shallow-copy the root so we don't mutate the caller's data. # Shallow-copy the root so we don't mutate the caller's data.
root = {k: v for k, v in value.items()} if isinstance(value, dict) else list(value) root = dict(value.items()) if isinstance(value, dict) else list(value)
stack: list = [(root, 0)] stack: list = [(root, 0)]
while stack: while stack:
@ -101,7 +101,7 @@ def _truncate_base64_in_value(value: Any) -> Any:
if isinstance(v, str): if isinstance(v, str):
container[k] = _truncate_base64_in_string(v) container[k] = _truncate_base64_in_string(v)
elif isinstance(v, dict): elif isinstance(v, dict):
copy: Union[dict, list] = {ck: cv for ck, cv in v.items()} copy: Union[dict, list] = dict(v.items())
container[k] = copy container[k] = copy
stack.append((copy, depth + 1)) stack.append((copy, depth + 1))
elif isinstance(v, list): elif isinstance(v, list):
@ -113,7 +113,7 @@ def _truncate_base64_in_value(value: Any) -> Any:
if isinstance(v, str): if isinstance(v, str):
container[i] = _truncate_base64_in_string(v) container[i] = _truncate_base64_in_string(v)
elif isinstance(v, dict): elif isinstance(v, dict):
copy = {ck: cv for ck, cv in v.items()} copy = dict(v.items())
container[i] = copy container[i] = copy
stack.append((copy, depth + 1)) stack.append((copy, depth + 1))
elif isinstance(v, list): elif isinstance(v, list):

View file

@ -47,7 +47,7 @@ def is_model_response_stream_empty(model_response: ModelResponseStream) -> bool:
# Check for any non-base fields that are set # Check for any non-base fields that are set
# Access model_fields on the class, not the instance, to avoid Pydantic 2.11+ deprecation warnings # Access model_fields on the class, not the instance, to avoid Pydantic 2.11+ deprecation warnings
for model_response_field in type(model_response).model_fields.keys(): for model_response_field in type(model_response).model_fields:
# Skip base fields that are always set # Skip base fields that are always set
if model_response_field in BASE_FIELDS: if model_response_field in BASE_FIELDS:
continue continue

View file

@ -849,7 +849,7 @@ def construct_tool_use_system_prompt(
"</function_calls>\n" "</function_calls>\n"
"\n" "\n"
"Here are the tools available:\n" "Here are the tools available:\n"
"<tools>\n" + "\n".join([tool_str for tool_str in tool_str_list]) + "\n</tools>" "<tools>\n" + "\n".join(list(tool_str_list)) + "\n</tools>"
) )
return tool_use_system_prompt return tool_use_system_prompt

View file

@ -1280,7 +1280,7 @@ class CustomStreamWrapper:
proto.marshal.collections.repeated.RepeatedComposite, # type: ignore proto.marshal.collections.repeated.RepeatedComposite, # type: ignore
): ):
# If so, convert to list # If so, convert to list
args_dict[key] = [v for v in val] args_dict[key] = list(val)
else: else:
args_dict[key] = val args_dict[key] = val

View file

@ -42,8 +42,8 @@ class AimlImageGenerationConfig(BaseImageGenerationConfig):
) -> dict: ) -> dict:
supported_params = self.get_supported_openai_params(model) supported_params = self.get_supported_openai_params(model)
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
# Map OpenAI params to AI/ML params # Map OpenAI params to AI/ML params
if k == "n": if k == "n":

View file

@ -911,7 +911,7 @@ class BaseAWSLLM:
verbose_logger.debug("Cross-account role assumption detected") verbose_logger.debug("Cross-account role assumption detected")
# Read the web identity token # Read the web identity token
with open(web_identity_token_file, "r") as f: with open(web_identity_token_file) as f:
web_identity_token = f.read().strip() web_identity_token = f.read().strip()
irsa_sts_kwargs = self._build_sts_client_kwargs( irsa_sts_kwargs = self._build_sts_client_kwargs(

View file

@ -40,7 +40,7 @@ class BedrockCohereEmbeddingConfig:
new_transformed_request = CohereEmbeddingRequest( new_transformed_request = CohereEmbeddingRequest(
input_type=transformed_request["input_type"], input_type=transformed_request["input_type"],
) )
for k in CohereEmbeddingRequest.__annotations__.keys(): for k in CohereEmbeddingRequest.__annotations__:
if k in transformed_request: if k in transformed_request:
new_transformed_request[k] = transformed_request[k] # type: ignore new_transformed_request[k] = transformed_request[k] # type: ignore

View file

@ -164,10 +164,10 @@ class BedrockVectorStoreConfig(BaseVectorStoreConfig, BaseAWSLLM):
aws_filters: Optional[Dict] = None aws_filters: Optional[Dict] = None
if isinstance(value, dict): if isinstance(value, dict):
if "operator" in value.keys(): if "operator" in value:
# Single operator - map directly (no wrapping needed) # Single operator - map directly (no wrapping needed)
aws_filters = self._map_operator_filter(value) aws_filters = self._map_operator_filter(value)
elif "and" in value.keys() or "or" in value.keys(): elif "and" in value or "or" in value:
aws_filters = self._map_and_or_filters(value) aws_filters = self._map_and_or_filters(value)
else: else:
# Assume it's already in AWS KB format # Assume it's already in AWS KB format

View file

@ -92,9 +92,9 @@ class Authenticator:
def _read_auth_file(self) -> Optional[Dict[str, Any]]: def _read_auth_file(self) -> Optional[Dict[str, Any]]:
try: try:
with open(self.auth_file, "r") as f: with open(self.auth_file) as f:
return json.load(f) return json.load(f)
except IOError: except OSError:
return None return None
except json.JSONDecodeError as exc: except json.JSONDecodeError as exc:
verbose_logger.warning("Invalid ChatGPT auth file: %s", exc) verbose_logger.warning("Invalid ChatGPT auth file: %s", exc)
@ -104,7 +104,7 @@ class Authenticator:
try: try:
with open(self.auth_file, "w") as f: with open(self.auth_file, "w") as f:
json.dump(data, f) json.dump(data, f)
except IOError as exc: except OSError as exc:
verbose_logger.error("Failed to write ChatGPT auth file: %s", exc) verbose_logger.error("Failed to write ChatGPT auth file: %s", exc)
def _is_token_expired(self, auth_data: Dict[str, Any], access_token: str) -> bool: def _is_token_expired(self, auth_data: Dict[str, Any], access_token: str) -> bool:

View file

@ -23,7 +23,7 @@ from .v1_transformation import CohereEmbeddingConfig
def validate_environment(api_key, headers: dict): def validate_environment(api_key, headers: dict):
# Create a lowercase key lookup to avoid duplicate headers with different cases # Create a lowercase key lookup to avoid duplicate headers with different cases
# This is important when headers come from AWS signed requests (which use Title-Case) # This is important when headers come from AWS signed requests (which use Title-Case)
existing_keys_lower = {k.lower(): k for k in headers.keys()} existing_keys_lower = {k.lower(): k for k in headers}
# Only add headers if they don't already exist (case-insensitive check) # Only add headers if they don't already exist (case-insensitive check)
if "request-source" not in existing_keys_lower: if "request-source" not in existing_keys_lower:

View file

@ -47,8 +47,8 @@ class CometAPIImageGenerationConfig(BaseImageGenerationConfig):
) -> dict: ) -> dict:
supported_params = self.get_supported_openai_params(model) supported_params = self.get_supported_openai_params(model)
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
# CometAPI uses OpenAI-compatible parameters, so we can pass them directly # CometAPI uses OpenAI-compatible parameters, so we can pass them directly
optional_params[k] = non_default_params[k] optional_params[k] = non_default_params[k]

View file

@ -62,8 +62,8 @@ class FalAIBriaConfig(FalAIBaseConfig):
"size": "aspect_ratio", "size": "aspect_ratio",
} }
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
# Use mapped parameter name if exists # Use mapped parameter name if exists
mapped_key = param_mapping.get(k, k) mapped_key = param_mapping.get(k, k)

View file

@ -36,8 +36,8 @@ class FalAIBytedanceBaseConfig(FalAIFluxProV11UltraConfig):
"size": "image_size", "size": "image_size",
} }
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
mapped_key = param_mapping.get(k, k) mapped_key = param_mapping.get(k, k)
mapped_value = non_default_params[k] mapped_value = non_default_params[k]

View file

@ -44,8 +44,8 @@ class FalAIFluxProV11Config(FalAIFluxProV11UltraConfig):
"size": "image_size", "size": "image_size",
} }
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
mapped_key = param_mapping.get(k, k) mapped_key = param_mapping.get(k, k)
mapped_value = non_default_params[k] mapped_value = non_default_params[k]

View file

@ -64,8 +64,8 @@ class FalAIFluxProV11UltraConfig(FalAIBaseConfig):
"size": "aspect_ratio", "size": "aspect_ratio",
} }
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
# Use mapped parameter name if exists # Use mapped parameter name if exists
mapped_key = param_mapping.get(k, k) mapped_key = param_mapping.get(k, k)

View file

@ -41,8 +41,8 @@ class FalAIFluxSchnellConfig(FalAIFluxProV11UltraConfig):
"size": "image_size", "size": "image_size",
} }
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
mapped_key = param_mapping.get(k, k) mapped_key = param_mapping.get(k, k)
mapped_value = non_default_params[k] mapped_value = non_default_params[k]

View file

@ -64,7 +64,7 @@ class FalAIIdeogramV3Config(FalAIBaseConfig):
supported_params = self.get_supported_openai_params(model) supported_params = self.get_supported_openai_params(model)
for k in non_default_params.keys(): for k in non_default_params:
if k in optional_params: if k in optional_params:
continue continue

View file

@ -66,8 +66,8 @@ class FalAIImagen4Config(FalAIBaseConfig):
"size": "aspect_ratio", "size": "aspect_ratio",
} }
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
# Use mapped parameter name if exists # Use mapped parameter name if exists
mapped_key = param_mapping.get(k, k) mapped_key = param_mapping.get(k, k)

View file

@ -62,8 +62,8 @@ class FalAIRecraftV3Config(FalAIBaseConfig):
"size": "image_size", "size": "image_size",
} }
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
# Use mapped parameter name if exists # Use mapped parameter name if exists
mapped_key = param_mapping.get(k, k) mapped_key = param_mapping.get(k, k)

View file

@ -101,8 +101,8 @@ class FalAIStableDiffusionConfig(FalAIBaseConfig):
"size": "image_size", "size": "image_size",
} }
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
# Use mapped parameter name if exists # Use mapped parameter name if exists
mapped_key = param_mapping.get(k, k) mapped_key = param_mapping.get(k, k)

View file

@ -144,8 +144,8 @@ class FalAIImageGenerationConfig(FalAIBaseConfig):
drop_params: bool, drop_params: bool,
) -> dict: ) -> dict:
supported_params = self.get_supported_openai_params(model) supported_params = self.get_supported_openai_params(model)
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
optional_params[k] = non_default_params[k] optional_params[k] = non_default_params[k]
elif drop_params: elif drop_params:

View file

@ -49,7 +49,7 @@ class GoogleImageGenConfig(BaseImageGenerationConfig):
mapped_params = {} mapped_params = {}
for k, v in non_default_params.items(): for k, v in non_default_params.items():
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
# Map OpenAI parameters to Google format # Map OpenAI parameters to Google format
if k == "n": if k == "n":

View file

@ -52,11 +52,11 @@ class Authenticator:
GetAccessTokenError: If unable to obtain an access token after retries. GetAccessTokenError: If unable to obtain an access token after retries.
""" """
try: try:
with open(self.access_token_file, "r") as f: with open(self.access_token_file) as f:
access_token = f.read().strip() access_token = f.read().strip()
if access_token: if access_token:
return access_token return access_token
except IOError: except OSError:
verbose_logger.warning( verbose_logger.warning(
"No existing access token found or error reading file" "No existing access token found or error reading file"
) )
@ -68,7 +68,7 @@ class Authenticator:
try: try:
with open(self.access_token_file, "w") as f: with open(self.access_token_file, "w") as f:
f.write(access_token) f.write(access_token)
except IOError: except OSError:
verbose_logger.error("Error saving access token to file") verbose_logger.error("Error saving access token to file")
return access_token return access_token
except (GetDeviceCodeError, GetAccessTokenError, RefreshAPIKeyError) as e: except (GetDeviceCodeError, GetAccessTokenError, RefreshAPIKeyError) as e:
@ -91,7 +91,7 @@ class Authenticator:
GetAPIKeyError: If unable to obtain an API key. GetAPIKeyError: If unable to obtain an API key.
""" """
try: try:
with open(self.api_key_file, "r") as f: with open(self.api_key_file) as f:
api_key_info = json.load(f) api_key_info = json.load(f)
if api_key_info.get("expires_at", 0) > datetime.now().timestamp(): if api_key_info.get("expires_at", 0) > datetime.now().timestamp():
return api_key_info.get("token") return api_key_info.get("token")
@ -101,7 +101,7 @@ class Authenticator:
message="API key expired", message="API key expired",
status_code=401, status_code=401,
) )
except IOError: except OSError:
verbose_logger.warning("No API key file found or error opening file") verbose_logger.warning("No API key file found or error opening file")
except (json.JSONDecodeError, KeyError) as e: except (json.JSONDecodeError, KeyError) as e:
verbose_logger.warning(f"Error reading API key from file: {str(e)}") verbose_logger.warning(f"Error reading API key from file: {str(e)}")
@ -120,7 +120,7 @@ class Authenticator:
message="API key response missing token", message="API key response missing token",
status_code=401, status_code=401,
) )
except IOError as e: except OSError as e:
verbose_logger.error(f"Error saving API key to file: {str(e)}") verbose_logger.error(f"Error saving API key to file: {str(e)}")
raise GetAPIKeyError( raise GetAPIKeyError(
message=f"Failed to save API key: {str(e)}", message=f"Failed to save API key: {str(e)}",
@ -140,12 +140,12 @@ class Authenticator:
Optional[str]: The GitHub Copilot API endpoint, or None if not found. Optional[str]: The GitHub Copilot API endpoint, or None if not found.
""" """
try: try:
with open(self.api_key_file, "r") as f: with open(self.api_key_file) as f:
api_key_info = json.load(f) api_key_info = json.load(f)
endpoints = api_key_info.get("endpoints", {}) endpoints = api_key_info.get("endpoints", {})
api_endpoint = endpoints.get("api") api_endpoint = endpoints.get("api")
return api_endpoint return api_endpoint
except (IOError, json.JSONDecodeError, KeyError) as e: except (OSError, json.JSONDecodeError, KeyError) as e:
verbose_logger.warning(f"Error reading API endpoint from file: {str(e)}") verbose_logger.warning(f"Error reading API endpoint from file: {str(e)}")
return None return None

View file

@ -161,7 +161,7 @@ class HuggingFaceEmbeddingConfig(BaseConfig):
"hf_text_generation_models.txt", "hf_text_generation_models.txt",
) )
with open(file_path, "r") as file: with open(file_path) as file:
for line in file: for line in file:
tgi_models.add(line.strip()) tgi_models.add(line.strip())
@ -175,7 +175,7 @@ class HuggingFaceEmbeddingConfig(BaseConfig):
"hf_conversational_models.txt", "hf_conversational_models.txt",
) )
conv_models = set() conv_models = set()
with open(file_path, "r") as file: with open(file_path) as file:
for line in file: for line in file:
conv_models.add(line.strip()) conv_models.add(line.strip())
# Cache the set for future use # Cache the set for future use

View file

@ -31,8 +31,8 @@ class DallE2ImageGenerationConfig(BaseImageGenerationConfig):
drop_params: bool, drop_params: bool,
) -> dict: ) -> dict:
supported_params = self.get_supported_openai_params(model) supported_params = self.get_supported_openai_params(model)
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
optional_params[k] = non_default_params[k] optional_params[k] = non_default_params[k]
elif drop_params: elif drop_params:

View file

@ -31,8 +31,8 @@ class DallE3ImageGenerationConfig(BaseImageGenerationConfig):
drop_params: bool, drop_params: bool,
) -> dict: ) -> dict:
supported_params = self.get_supported_openai_params(model) supported_params = self.get_supported_openai_params(model)
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
optional_params[k] = non_default_params[k] optional_params[k] = non_default_params[k]
elif drop_params: elif drop_params:

View file

@ -40,8 +40,8 @@ class GPTImageGenerationConfig(BaseImageGenerationConfig):
drop_params: bool, drop_params: bool,
) -> dict: ) -> dict:
supported_params = self.get_supported_openai_params(model) supported_params = self.get_supported_openai_params(model)
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
optional_params[k] = non_default_params[k] optional_params[k] = non_default_params[k]
elif drop_params: elif drop_params:

View file

@ -140,7 +140,7 @@ class OpenAIWhisperAudioTranscriptionConfig(BaseAudioTranscriptionConfig):
if any( if any(
key in raw_response_json key in raw_response_json
for key in TranscriptionResponse.model_fields.keys() for key in TranscriptionResponse.model_fields
): ):
return TranscriptionResponse(**raw_response_json) return TranscriptionResponse(**raw_response_json)
else: else:

View file

@ -41,8 +41,8 @@ class RecraftImageGenerationConfig(BaseImageGenerationConfig):
drop_params: bool, drop_params: bool,
) -> dict: ) -> dict:
supported_params = self.get_supported_openai_params(model) supported_params = self.get_supported_openai_params(model)
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
optional_params[k] = non_default_params[k] optional_params[k] = non_default_params[k]
elif drop_params: elif drop_params:

View file

@ -466,8 +466,8 @@ class RunwayMLImageGenerationConfig(BaseImageGenerationConfig):
} }
optional_params["ratio"] = size_to_ratio_map.get(size, "1920:1080") optional_params["ratio"] = size_to_ratio_map.get(size, "1920:1080")
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
optional_params[k] = non_default_params[k] optional_params[k] = non_default_params[k]
elif drop_params: elif drop_params:

View file

@ -2561,7 +2561,7 @@ class VertexGeminiConfig(VertexAIBaseConfig, BaseConfig):
) )
if ( if (
"finishReason" in _candidates[0] "finishReason" in _candidates[0]
and _candidates[0]["finishReason"] in content_policy_violations.keys() and _candidates[0]["finishReason"] in content_policy_violations
): ):
return self._handle_content_policy_violation( return self._handle_content_policy_violation(
model_response=model_response, model_response=model_response,

View file

@ -65,7 +65,7 @@ class VertexAIGeminiImageGenerationConfig(BaseImageGenerationConfig, VertexLLM):
mapped_params = {} mapped_params = {}
for k, v in non_default_params.items(): for k, v in non_default_params.items():
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
# Map OpenAI parameters to Gemini format # Map OpenAI parameters to Gemini format
if k == "n": if k == "n":

View file

@ -58,7 +58,7 @@ class VertexAIImagenImageGenerationConfig(BaseImageGenerationConfig, VertexLLM):
mapped_params = {} mapped_params = {}
for k, v in non_default_params.items(): for k, v in non_default_params.items():
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
# Map OpenAI parameters to Imagen format # Map OpenAI parameters to Imagen format
if k == "n": if k == "n":

View file

@ -26,8 +26,8 @@ class XInferenceImageGenerationConfig(BaseImageGenerationConfig):
drop_params: bool, drop_params: bool,
) -> dict: ) -> dict:
supported_params = self.get_supported_openai_params(model) supported_params = self.get_supported_openai_params(model)
for k in non_default_params.keys(): for k in non_default_params:
if k not in optional_params.keys(): if k not in optional_params:
if k in supported_params: if k in supported_params:
optional_params[k] = non_default_params[k] optional_params[k] = non_default_params[k]
elif drop_params: elif drop_params:

View file

@ -2480,7 +2480,7 @@ class MCPServerManager:
# Filter arguments to only include allowed parameters # Filter arguments to only include allowed parameters
disallowed_params = [ disallowed_params = [
param for param in arguments.keys() if param not in allowed_params_list param for param in arguments if param not in allowed_params_list
] ]
if disallowed_params: if disallowed_params:

View file

@ -115,7 +115,7 @@ async def load_openapi_spec_async(filepath: str) -> Dict[str, Any]:
# Local filesystem path # Local filesystem path
if not os.path.exists(filepath): if not os.path.exists(filepath):
raise FileNotFoundError(f"OpenAPI spec not found at {filepath}") raise FileNotFoundError(f"OpenAPI spec not found at {filepath}")
with open(filepath, "r", encoding="utf-8") as f: with open(filepath, encoding="utf-8") as f:
return json.load(f) return json.load(f)

View file

@ -3951,7 +3951,7 @@ class OrgMemberAddRequest(LiteLLMPydanticObjectBase):
if all(isinstance(item, dict) for item in member_data): if all(isinstance(item, dict) for item in member_data):
members = [OrgMember(**item) for item in member_data] members = [OrgMember(**item) for item in member_data]
else: else:
members = [item for item in member_data] members = list(member_data)
# Replace member_data with the list of Member objects # Replace member_data with the list of Member objects
data["member"] = members data["member"] = members
elif isinstance(member_data, dict): elif isinstance(member_data, dict):

View file

@ -40,9 +40,9 @@ def load_token() -> Optional[Dict[str, Any]]:
return None return None
try: try:
with open(token_file, "r") as f: with open(token_file) as f:
return json.load(f) return json.load(f)
except (json.JSONDecodeError, IOError): except (OSError, json.JSONDecodeError):
return None return None

View file

@ -305,7 +305,7 @@ def _load_conversation(
filename += ".json" filename += ".json"
try: try:
with open(filename, "r") as f: with open(filename) as f:
messages = json.load(f) messages = json.load(f)
console.print(f"[green]Conversation loaded from {filename}[/green]") console.print(f"[green]Conversation loaded from {filename}[/green]")
return messages return messages

View file

@ -392,7 +392,7 @@ def _print_summary_table(provider_counts):
def get_model_list_from_yaml_file(yaml_file: str) -> list[dict[str, Any]]: def get_model_list_from_yaml_file(yaml_file: str) -> list[dict[str, Any]]:
"""Load and validate the model list from a YAML file.""" """Load and validate the model list from a YAML file."""
with open(yaml_file, "r") as f: with open(yaml_file) as f:
data = yaml.safe_load(f) data = yaml.safe_load(f)
if not data or "model_list" not in data: if not data or "model_list" not in data:
raise click.ClickException( raise click.ClickException(

View file

@ -285,9 +285,7 @@ def update_db_credential(
# update litellm params # update litellm params
if encrypted_credential.credential_values: if encrypted_credential.credential_values:
# Encrypt any sensitive values # Encrypt any sensitive values
encrypted_params = { encrypted_params = dict(encrypted_credential.credential_values.items())
k: v for k, v in encrypted_credential.credential_values.items()
}
merged_credential.credential_values.update(encrypted_params) merged_credential.credential_values.update(encrypted_params)

View file

@ -1306,7 +1306,7 @@ class DBSpendUpdateWriter:
): ):
# Track which team memberships will be updated for cache invalidation # Track which team memberships will be updated for cache invalidation
team_memberships_to_invalidate: List[tuple[str, str]] = [] team_memberships_to_invalidate: List[tuple[str, str]] = []
for key in team_member_list_transactions.keys(): for key in team_member_list_transactions:
# key is "team_id::<value>::user_id::<value>" # key is "team_id::<value>::user_id::<value>"
team_id = key.split("::")[1] team_id = key.split("::")[1]
user_id = key.split("::")[3] user_id = key.split("::")[3]
@ -1786,7 +1786,7 @@ class DBSpendUpdateWriter:
) )
# Remove processed transactions # Remove processed transactions
for key in transactions_to_process.keys(): for key in transactions_to_process:
daily_spend_transactions.pop(key, None) daily_spend_transactions.pop(key, None)
break break
@ -1809,7 +1809,7 @@ class DBSpendUpdateWriter:
except Exception as e: except Exception as e:
if "transactions_to_process" in locals(): if "transactions_to_process" in locals():
for key in transactions_to_process.keys(): # type: ignore for key in transactions_to_process: # type: ignore
daily_spend_transactions.pop(key, None) daily_spend_transactions.pop(key, None)
_raise_failed_update_spend_exception( _raise_failed_update_spend_exception(
e=e, start_time=start_time, proxy_logging_obj=proxy_logging_obj e=e, start_time=start_time, proxy_logging_obj=proxy_logging_obj

View file

@ -1443,7 +1443,7 @@ async def get_category_yaml(category_name: str):
try: try:
# Read and return the raw content # Read and return the raw content
with open(category_file_path, "r") as f: with open(category_file_path) as f:
content = f.read() content = f.read()
return { return {
@ -1480,7 +1480,7 @@ async def get_major_airlines():
detail="major_airlines.json not found", detail="major_airlines.json not found",
) )
try: try:
with open(airlines_path, "r", encoding="utf-8") as f: with open(airlines_path, encoding="utf-8") as f:
import json import json
airlines = json.load(f) airlines = json.load(f)

View file

@ -268,7 +268,7 @@ class GenericGuardrailAPI(CustomGuardrail):
# Dynamically iterate through GenericGuardrailAPIMetadata fields # Dynamically iterate through GenericGuardrailAPIMetadata fields
# and extract matching fields from the source metadata # and extract matching fields from the source metadata
# Fields in metadata are already prefixed with 'user_api_key_' # Fields in metadata are already prefixed with 'user_api_key_'
for field_name in GenericGuardrailAPIMetadata.__annotations__.keys(): for field_name in GenericGuardrailAPIMetadata.__annotations__:
value = metadata_dict.get(field_name) value = metadata_dict.get(field_name)
if value is not None: if value is not None:
result_metadata[field_name] = value # type: ignore[literal-required] result_metadata[field_name] = value # type: ignore[literal-required]

View file

@ -164,7 +164,7 @@ class IBMGuardrailDetector(CustomGuardrail):
guardrail_provider=self.guardrail_provider, guardrail_provider=self.guardrail_provider,
guardrail_json_response={ guardrail_json_response={
"detections": [ "detections": [
[detection for detection in message_detections] list(message_detections)
for message_detections in response_json for message_detections in response_json
] ]
}, },

View file

@ -168,9 +168,7 @@ class lakeraAI_Moderation(CustomGuardrail):
stringified_roles.append(role.value) stringified_roles.append(role.value)
elif isinstance(role, str): elif isinstance(role, str):
stringified_roles.append(role) stringified_roles.append(role)
lakera_input_dict: Dict = { lakera_input_dict: Dict = dict.fromkeys(INPUT_POSITIONING_MAP.keys())
role: None for role in INPUT_POSITIONING_MAP.keys()
}
system_message = None system_message = None
tool_call_messages: List = [] tool_call_messages: List = []
for message in data["messages"]: for message in data["messages"]:

View file

@ -601,7 +601,7 @@ class ContentFilterGuardrail(CustomGuardrail):
""" """
if file_path.lower().endswith(".json"): if file_path.lower().endswith(".json"):
return self._load_category_file_json(file_path) return self._load_category_file_json(file_path)
with open(file_path, "r") as f: with open(file_path) as f:
data = yaml.safe_load(f) data = yaml.safe_load(f)
# Handle always_block_keywords if present # Handle always_block_keywords if present
@ -627,7 +627,7 @@ class ContentFilterGuardrail(CustomGuardrail):
Each entry has: id, match (pipe-separated phrases), tags, severity (1-4). Each entry has: id, match (pipe-separated phrases), tags, severity (1-4).
Severity mapping: 4,3 -> high; 2 -> medium; 1 -> low. Severity mapping: 4,3 -> high; 2 -> medium; 1 -> low.
""" """
with open(file_path, "r") as f: with open(file_path) as f:
entries = json.load(f) entries = json.load(f)
if not isinstance(entries, list): if not isinstance(entries, list):
entries = [entries] entries = [entries]
@ -733,7 +733,7 @@ class ContentFilterGuardrail(CustomGuardrail):
``` ```
""" """
try: try:
with open(file_path, "r") as f: with open(file_path) as f:
data = yaml.safe_load(f) data = yaml.safe_load(f)
if not isinstance(data, dict) or "blocked_words" not in data: if not isinstance(data, dict) or "blocked_words" not in data:

View file

@ -37,7 +37,7 @@ def _load_jsonl(filename: str) -> List[dict]:
"""Load eval cases from a JSONL file. One JSON object per line.""" """Load eval cases from a JSONL file. One JSON object per line."""
cases = [] cases = []
path = os.path.join(EVAL_DIR, filename) path = os.path.join(EVAL_DIR, filename)
with open(path, "r") as f: with open(path) as f:
for line in f: for line in f:
line = line.strip() line = line.strip()
if not line: if not line:

View file

@ -15,7 +15,7 @@ from typing import Any, Dict, List, Pattern
def _load_patterns_from_json() -> Dict: def _load_patterns_from_json() -> Dict:
"""Load pattern definitions from patterns.json file""" """Load pattern definitions from patterns.json file"""
json_path = os.path.join(os.path.dirname(__file__), "patterns.json") json_path = os.path.join(os.path.dirname(__file__), "patterns.json")
with open(json_path, "r") as f: with open(json_path) as f:
return json.load(f) return json.load(f)
@ -158,7 +158,7 @@ def get_available_content_categories() -> List[Dict[str, str]]:
if filename.endswith(".yaml") or filename.endswith(".yml"): if filename.endswith(".yaml") or filename.endswith(".yml"):
category_file_path = os.path.join(categories_dir, filename) category_file_path = os.path.join(categories_dir, filename)
try: try:
with open(category_file_path, "r") as f: with open(category_file_path) as f:
category_data = yaml.safe_load(f) category_data = yaml.safe_load(f)
if category_data and "category_name" in category_data: if category_data and "category_name" in category_data:

View file

@ -142,7 +142,7 @@ class _OPTIONAL_PresidioPIIMasking(CustomGuardrail):
ad_hoc_recognizers = presidio_ad_hoc_recognizers ad_hoc_recognizers = presidio_ad_hoc_recognizers
if ad_hoc_recognizers is not None: if ad_hoc_recognizers is not None:
try: try:
with open(ad_hoc_recognizers, "r") as file: with open(ad_hoc_recognizers) as file:
self.ad_hoc_recognizers = json.load(file) self.ad_hoc_recognizers = json.load(file)
except FileNotFoundError: except FileNotFoundError:
raise Exception(f"File not found. file_path={ad_hoc_recognizers}") raise Exception(f"File not found. file_path={ad_hoc_recognizers}")

View file

@ -35,7 +35,7 @@ class SemanticGuardRouteLoader:
f"SemanticGuard: unknown route template '{template_name}'. " f"SemanticGuard: unknown route template '{template_name}'. "
f"Available templates: {SemanticGuardRouteLoader.list_builtin_templates()}" f"Available templates: {SemanticGuardRouteLoader.list_builtin_templates()}"
) )
with open(file_path, "r") as f: with open(file_path) as f:
return yaml.safe_load(f) return yaml.safe_load(f)
@staticmethod @staticmethod
@ -55,7 +55,7 @@ class SemanticGuardRouteLoader:
raise ValueError( raise ValueError(
f"SemanticGuard: custom routes file not found: {file_path}" f"SemanticGuard: custom routes file not found: {file_path}"
) )
with open(file_path, "r") as f: with open(file_path) as f:
data = yaml.safe_load(f) data = yaml.safe_load(f)
if isinstance(data, list): if isinstance(data, list):
return data return data

View file

@ -57,7 +57,7 @@ class _PROXY_BatchRedisRequests(CustomLogger):
key_value_dict = {} key_value_dict = {}
in_memory_cache_exists = False in_memory_cache_exists = False
for key in cache.in_memory_cache.cache_dict.keys(): for key in cache.in_memory_cache.cache_dict:
if isinstance(key, str) and key.startswith(cache_key_name): if isinstance(key, str) and key.startswith(cache_key_name):
in_memory_cache_exists = True in_memory_cache_exists = True

View file

@ -173,7 +173,7 @@ class SkillsInjectionHook(CustomLogger):
skill_files = self.prompt_handler.extract_all_files(skill) skill_files = self.prompt_handler.extract_all_files(skill)
if skill_files: if skill_files:
all_skill_files[skill.skill_id] = skill_files all_skill_files[skill.skill_id] = skill_files
for path in skill_files.keys(): for path in skill_files:
if path.endswith(".py"): if path.endswith(".py"):
all_module_paths.append(path) all_module_paths.append(path)
@ -240,7 +240,7 @@ class SkillsInjectionHook(CustomLogger):
if skill_files: if skill_files:
all_skill_files[skill.skill_id] = skill_files all_skill_files[skill.skill_id] = skill_files
# Collect Python module paths # Collect Python module paths
for path in skill_files.keys(): for path in skill_files:
if path.endswith(".py"): if path.endswith(".py"):
all_module_paths.append(path) all_module_paths.append(path)
@ -637,7 +637,7 @@ class SkillsInjectionHook(CustomLogger):
# Look for Python modules in the skill # Look for Python modules in the skill
python_modules = [ python_modules = [
p p
for p in skill_files.keys() for p in skill_files
if p.endswith(".py") and not p.endswith("__init__.py") if p.endswith(".py") and not p.endswith("__init__.py")
] ]

View file

@ -49,7 +49,7 @@ async def get_callback_configs():
"callback_configs.json", "callback_configs.json",
) )
with open(config_path, "r") as f: with open(config_path) as f:
configs = json.load(f) configs = json.load(f)
return configs return configs

View file

@ -199,7 +199,7 @@ async def update_cost_discount_config(
# Validate that all providers are valid LiteLLM providers # Validate that all providers are valid LiteLLM providers
invalid_providers = [] invalid_providers = []
for provider in cost_discount_config.keys(): for provider in cost_discount_config:
if provider not in LlmProvidersSet: if provider not in LlmProvidersSet:
invalid_providers.append(provider) invalid_providers.append(provider)
@ -343,7 +343,7 @@ async def update_cost_margin_config(
# Validate that all providers are valid LiteLLM providers (except "global") # Validate that all providers are valid LiteLLM providers (except "global")
invalid_providers = [] invalid_providers = []
for provider in cost_margin_config.keys(): for provider in cost_margin_config:
if provider != "global" and provider not in LlmProvidersSet: if provider != "global" and provider not in LlmProvidersSet:
invalid_providers.append(provider) invalid_providers.append(provider)

View file

@ -355,7 +355,7 @@ async def new_end_user(
_user_data = data.dict(exclude_none=True) _user_data = data.dict(exclude_none=True)
for k, v in _user_data.items(): for k, v in _user_data.items():
if k not in BudgetNewRequest.model_fields.keys(): if k not in BudgetNewRequest.model_fields:
new_end_user_obj[k] = v new_end_user_obj[k] = v
## Handle Object Permission - MCP Servers, Vector Stores etc. ## Handle Object Permission - MCP Servers, Vector Stores etc.
@ -595,10 +595,10 @@ async def update_end_user(
# budget_id is for linking to existing budget, not for creating new budget # budget_id is for linking to existing budget, not for creating new budget
if k == "budget_id": if k == "budget_id":
update_end_user_table_data[k] = v update_end_user_table_data[k] = v
elif k in LiteLLM_BudgetTable.model_fields.keys(): elif k in LiteLLM_BudgetTable.model_fields:
budget_table_data[k] = v budget_table_data[k] = v
elif k in LiteLLM_EndUserTable.model_fields.keys(): elif k in LiteLLM_EndUserTable.model_fields:
update_end_user_table_data[k] = v update_end_user_table_data[k] = v
## Handle object permission updates (MCP servers, vector stores, etc.) ## Handle object permission updates (MCP servers, vector stores, etc.)

View file

@ -500,7 +500,7 @@ async def new_user(
special_keys = ["token", "token_id"] special_keys = ["token", "token_id"]
response_dict = {} response_dict = {}
for key, value in response.items(): for key, value in response.items():
if key in NewUserResponse.model_fields.keys() and key not in special_keys: if key in NewUserResponse.model_fields and key not in special_keys:
response_dict[key] = value response_dict[key] = value
response_dict["key"] = response.get("token", "") response_dict["key"] = response.get("token", "")

View file

@ -2267,7 +2267,7 @@ if MCP_AVAILABLE:
if _mcp_registry_cache is not None: if _mcp_registry_cache is not None:
return _mcp_registry_cache return _mcp_registry_cache
try: try:
with open(_MCP_REGISTRY_PATH, "r") as f: with open(_MCP_REGISTRY_PATH) as f:
data: Dict[str, Any] = json.load(f) data: Dict[str, Any] = json.load(f)
except Exception as e: except Exception as e:
verbose_proxy_logger.warning( verbose_proxy_logger.warning(
@ -2341,7 +2341,7 @@ if MCP_AVAILABLE:
@functools.lru_cache(maxsize=1) @functools.lru_cache(maxsize=1)
def _load_openapi_registry() -> Dict[str, Any]: def _load_openapi_registry() -> Dict[str, Any]:
with open(_OPENAPI_REGISTRY_PATH, "r") as f: with open(_OPENAPI_REGISTRY_PATH) as f:
data: Dict[str, Any] = json.load(f) data: Dict[str, Any] = json.load(f)
return data return data

View file

@ -559,7 +559,7 @@ async def update_organization(
budget_fields = { budget_fields = {
k: v k: v
for k, v in data.model_dump().items() for k, v in data.model_dump().items()
if k in LiteLLM_BudgetTable.model_fields.keys() and v is not None if k in LiteLLM_BudgetTable.model_fields and v is not None
} }
if budget_fields and existing_organization_row.budget_id: if budget_fields and existing_organization_row.budget_id:
@ -571,7 +571,7 @@ async def update_organization(
) )
# Remove budget fields from organization update data # Remove budget fields from organization update data
for field in LiteLLM_BudgetTable.model_fields.keys(): for field in LiteLLM_BudgetTable.model_fields:
updated_organization_row.pop(field, None) updated_organization_row.pop(field, None)
response = await prisma_client.db.litellm_organizationtable.update( response = await prisma_client.db.litellm_organizationtable.update(

View file

@ -633,7 +633,7 @@ def _load_policy_templates_from_local_backup() -> list:
path = os.path.abspath(backup_path) path = os.path.abspath(backup_path)
if not os.path.exists(path): if not os.path.exists(path):
return [] return []
with open(path, "r") as f: with open(path) as f:
return json.load(f) return json.load(f)

View file

@ -312,7 +312,7 @@ def _accumulate_breakdown(
for day in results: for day in results:
for key, entry in day.get("breakdown", {}).get(dimension, {}).items(): for key, entry in day.get("breakdown", {}).get(dimension, {}).items():
if key not in totals: if key not in totals:
totals[key] = {f: 0.0 for f in fields} totals[key] = dict.fromkeys(fields, 0.0)
m = entry.get("metrics", {}) m = entry.get("metrics", {})
for f in fields: for f in fields:
totals[key][f] += m.get(f, 0) totals[key][f] += m.get(f, 0)

View file

@ -223,7 +223,7 @@ class StorageBackendFileService:
managed_files_obj = cast(Any, managed_files_obj) managed_files_obj = cast(Any, managed_files_obj)
# Create model mappings using storage URL # Create model mappings using storage URL
model_mappings = {model_name: storage_url for model_name in target_model_names} model_mappings = dict.fromkeys(target_model_names, storage_url)
# Create unified file ID # Create unified file ID
file_type = file_data.get("content_type", "application/octet-stream") file_type = file_data.get("content_type", "application/octet-stream")

View file

@ -2499,7 +2499,7 @@ class InitPassThroughEndpointHelpers:
# Keys are in format: "{endpoint_id}:exact:{path}:{methods}" or "{endpoint_id}:subpath:{path}:{methods}" # Keys are in format: "{endpoint_id}:exact:{path}:{methods}" or "{endpoint_id}:subpath:{path}:{methods}"
# For backward compatibility, also support old format: "{endpoint_id}:exact:{path}" or "{endpoint_id}:subpath:{path}" # For backward compatibility, also support old format: "{endpoint_id}:exact:{path}" or "{endpoint_id}:subpath:{path}"
# Extract unique paths from keys for quick checking # Extract unique paths from keys for quick checking
for key in _registered_pass_through_routes.keys(): for key in _registered_pass_through_routes:
parts = key.split(":", 3) # Split into [endpoint_id, type, path, methods?] parts = key.split(":", 3) # Split into [endpoint_id, type, path, methods?]
if len(parts) >= 3: if len(parts) >= 3:
route_type = parts[1] route_type = parts[1]
@ -2521,7 +2521,7 @@ class InitPassThroughEndpointHelpers:
route: str, method: Optional[str] = None route: str, method: Optional[str] = None
) -> Optional[Dict[str, Any]]: ) -> Optional[Dict[str, Any]]:
"""Get passthrough params for a given route and optionally filter by HTTP method""" """Get passthrough params for a given route and optionally filter by HTTP method"""
for key in _registered_pass_through_routes.keys(): for key in _registered_pass_through_routes:
parts = key.split(":", 3) # Split into [endpoint_id, type, path, methods?] parts = key.split(":", 3) # Split into [endpoint_id, type, path, methods?]
if len(parts) >= 3: if len(parts) >= 3:
route_type = parts[1] route_type = parts[1]

View file

@ -60,7 +60,7 @@ class PassthroughGuardrailHandler:
# List of guardrail names - convert to dict # List of guardrail names - convert to dict
if isinstance(guardrails_config, list): if isinstance(guardrails_config, list):
return {name: None for name in guardrails_config} return dict.fromkeys(guardrails_config)
verbose_proxy_logger.debug( verbose_proxy_logger.debug(
"Passthrough guardrails config is not a dict or list, got: %s", "Passthrough guardrails config is not a dict or list, got: %s",
@ -200,9 +200,7 @@ class PassthroughGuardrailHandler:
request_data["metadata"] = {} request_data["metadata"] = {}
# Set guardrails in metadata using dict format for compatibility # Set guardrails in metadata using dict format for compatibility
request_data["metadata"]["guardrails"] = { request_data["metadata"]["guardrails"] = dict.fromkeys(guardrail_names, True)
name: True for name in guardrail_names
}
# Store passthrough guardrails config in request-scoped context # Store passthrough guardrails config in request-scoped context
set_passthrough_guardrails_config(guardrails_config) set_passthrough_guardrails_config(guardrails_config)
@ -260,7 +258,7 @@ class PassthroughGuardrailHandler:
guardrails_to_run: Dict[str, bool] = {} guardrails_to_run: Dict[str, bool] = {}
# Add passthrough-specific guardrails # Add passthrough-specific guardrails
for guardrail_name in normalized_config.keys(): for guardrail_name in normalized_config:
guardrails_to_run[guardrail_name] = True guardrails_to_run[guardrail_name] = True
verbose_proxy_logger.debug( verbose_proxy_logger.debug(
"Added passthrough-specific guardrail: %s", guardrail_name "Added passthrough-specific guardrail: %s", guardrail_name

View file

@ -151,7 +151,7 @@ def get_latest_version_prompt_id(prompt_id: str, all_prompt_ids: Dict[str, Any])
# Find all versions of this prompt # Find all versions of this prompt
matching_versions = [] matching_versions = []
for stored_prompt_id in all_prompt_ids.keys(): for stored_prompt_id in all_prompt_ids:
if get_base_prompt_id(prompt_id=stored_prompt_id) == base_id: if get_base_prompt_id(prompt_id=stored_prompt_id) == base_id:
version_num = get_version_number(prompt_id=stored_prompt_id) version_num = get_version_number(prompt_id=stored_prompt_id)
matching_versions.append((version_num, stored_prompt_id)) matching_versions.append((version_num, stored_prompt_id))

View file

@ -188,7 +188,7 @@ class InMemoryPromptRegistry:
prompts_to_delete = [ prompts_to_delete = [
pid pid
for pid in self.IN_MEMORY_PROMPTS.keys() for pid in self.IN_MEMORY_PROMPTS
if get_base_prompt_id(prompt_id=pid) == base_prompt_id if get_base_prompt_id(prompt_id=pid) == base_prompt_id
] ]

View file

@ -1610,7 +1610,7 @@ try:
): ):
continue continue
try: try:
with open(file_path, "r", encoding="utf-8") as f: with open(file_path, encoding="utf-8") as f:
content = f.read() content = f.read()
# Replace the asset prefix with the server root path # Replace the asset prefix with the server root path
@ -3432,7 +3432,7 @@ class ProxyConfig:
Load and parse a YAML file Load and parse a YAML file
""" """
try: try:
with open(file_path, "r") as file: with open(file_path) as file:
return yaml.safe_load(file) or {} return yaml.safe_load(file) or {}
except Exception as e: except Exception as e:
raise Exception(f"Error loading yaml file {file_path}: {str(e)}") raise Exception(f"Error loading yaml file {file_path}: {str(e)}")
@ -3455,7 +3455,7 @@ class ProxyConfig:
# Load existing config # Load existing config
## Yaml ## Yaml
if os.path.exists(f"{file_path}"): if os.path.exists(f"{file_path}"):
with open(f"{file_path}", "r") as config_file: with open(f"{file_path}") as config_file:
config = yaml.safe_load(config_file) config = yaml.safe_load(config_file)
elif file_path is not None: elif file_path is not None:
raise Exception(f"Config file not found: {file_path}") raise Exception(f"Config file not found: {file_path}")
@ -6254,7 +6254,7 @@ class ProxyConfig:
# Count providers in config # Count providers in config
provider_count = sum( provider_count = sum(
1 1
for k in new_config.keys() for k in new_config
if k != "provider_aliases" and k != "description" if k != "provider_aliases" and k != "description"
) )
verbose_proxy_logger.info( verbose_proxy_logger.info(
@ -15311,7 +15311,7 @@ async def reload_anthropic_beta_headers(
await invalidate_config_param("anthropic_beta_headers_reload_config") await invalidate_config_param("anthropic_beta_headers_reload_config")
provider_count = sum( provider_count = sum(
1 for k in new_config.keys() if k not in ["provider_aliases", "description"] 1 for k in new_config if k not in ["provider_aliases", "description"]
) )
verbose_proxy_logger.info( verbose_proxy_logger.info(
f"Anthropic beta headers config reloaded successfully in current pod. Providers: {provider_count}" f"Anthropic beta headers config reloaded successfully in current pod. Providers: {provider_count}"

View file

@ -350,7 +350,7 @@ async def get_provider_fields() -> List[ProviderCreateInfo]:
"provider_create_fields.json", "provider_create_fields.json",
) )
with open(provider_create_fields_path, "r") as f: with open(provider_create_fields_path) as f:
provider_create_fields = json.load(f) provider_create_fields = json.load(f)
return provider_create_fields return provider_create_fields
@ -440,10 +440,10 @@ async def get_agent_fields() -> List[AgentCreateInfo]:
agent_create_fields_path = os.path.join(base_path, "agent_create_fields.json") agent_create_fields_path = os.path.join(base_path, "agent_create_fields.json")
provider_create_fields_path = os.path.join(base_path, "provider_create_fields.json") provider_create_fields_path = os.path.join(base_path, "provider_create_fields.json")
with open(agent_create_fields_path, "r") as f: with open(agent_create_fields_path) as f:
agent_create_fields = json.load(f) agent_create_fields = json.load(f)
with open(provider_create_fields_path, "r") as f: with open(provider_create_fields_path) as f:
provider_create_fields = json.load(f) provider_create_fields = json.load(f)
# Build a lookup map for providers by name # Build a lookup map for providers by name

View file

@ -118,7 +118,7 @@ def _get_spend_logs_metadata(
# Filter the metadata dictionary to include only the specified keys # Filter the metadata dictionary to include only the specified keys
clean_metadata = SpendLogsMetadata( clean_metadata = SpendLogsMetadata(
**{ # type: ignore **{ # type: ignore
key: metadata.get(key) for key in SpendLogsMetadata.__annotations__.keys() key: metadata.get(key) for key in SpendLogsMetadata.__annotations__
} }
) )
clean_metadata["applied_guardrails"] = applied_guardrails clean_metadata["applied_guardrails"] = applied_guardrails

View file

@ -47,7 +47,7 @@ class ResponsesAPIRequestUtils:
if supported_params is None: if supported_params is None:
return return
unsupported_params = {} unsupported_params = {}
for k in non_default_params.keys(): for k in non_default_params:
if k not in supported_params: if k not in supported_params:
unsupported_params[k] = non_default_params[k] unsupported_params[k] = non_default_params[k]
if unsupported_params: if unsupported_params:
@ -139,7 +139,7 @@ class ResponsesAPIRequestUtils:
special_params=special_params, special_params=special_params,
custom_llm_provider=custom_llm_provider, custom_llm_provider=custom_llm_provider,
additional_drop_params=additional_drop_params, additional_drop_params=additional_drop_params,
default_param_values={k: None for k in valid_keys}, default_param_values=dict.fromkeys(valid_keys),
additional_endpoint_specific_params=["input"], additional_endpoint_specific_params=["input"],
) )
) )

View file

@ -7752,7 +7752,7 @@ class Router:
litellm_params=litellm_params, litellm_params=litellm_params,
model_info=_model_info, model_info=_model_info,
) )
for field in CustomPricingLiteLLMParams.model_fields.keys(): for field in CustomPricingLiteLLMParams.model_fields:
if deployment.litellm_params.get(field) is not None: if deployment.litellm_params.get(field) is not None:
_model_info[field] = deployment.litellm_params[field] _model_info[field] = deployment.litellm_params[field]
@ -8490,7 +8490,7 @@ class Router:
self._add_deployment(deployment=deployment) self._add_deployment(deployment=deployment)
_model_info_dict: dict = deployment.model_info.model_dump(exclude_none=True) _model_info_dict: dict = deployment.model_info.model_dump(exclude_none=True)
for field in CustomPricingLiteLLMParams.model_fields.keys(): for field in CustomPricingLiteLLMParams.model_fields:
field_value = deployment.litellm_params.get(field) field_value = deployment.litellm_params.get(field)
if field_value is not None: if field_value is not None:
_model_info_dict[field] = field_value _model_info_dict[field] = field_value
@ -9664,7 +9664,7 @@ class Router:
else: else:
# When model_name is None, return all model IDs # When model_name is None, return all model IDs
# Use the index map keys for O(n) where n = total deployments # Use the index map keys for O(n) where n = total deployments
for model_id in self.model_id_to_deployment_index_map.keys(): for model_id in self.model_id_to_deployment_index_map:
idx = self.model_id_to_deployment_index_map[model_id] idx = self.model_id_to_deployment_index_map[model_id]
model = self.model_list[idx] model = self.model_list[idx]
if "model_info" in model and "id" in model["model_info"]: if "model_info" in model and "id" in model["model_info"]:

View file

@ -244,8 +244,8 @@ def _check_non_standard_fallback_format(fallbacks: Optional[List[Any]]) -> bool:
if all(isinstance(item, str) for item in fallbacks): if all(isinstance(item, str) for item in fallbacks):
return True return True
elif all(isinstance(item, dict) for item in fallbacks): elif all(isinstance(item, dict) for item in fallbacks):
for key in LiteLLMParamsTypedDict.__annotations__.keys(): for key in LiteLLMParamsTypedDict.__annotations__:
if key in fallbacks[0].keys(): if key in fallbacks[0]:
return True return True
return False return False

View file

@ -251,13 +251,13 @@ def get_secret( # noqa: PLR0915
error_msg = f"Azure OIDC provider failed: {str(e)}" error_msg = f"Azure OIDC provider failed: {str(e)}"
verbose_logger.error(error_msg) verbose_logger.error(error_msg)
raise ValueError(error_msg) raise ValueError(error_msg)
with open(azure_federated_token_file, "r") as f: with open(azure_federated_token_file) as f:
oidc_token = f.read() oidc_token = f.read()
return oidc_token return oidc_token
elif oidc_provider == "file": elif oidc_provider == "file":
# Load token from a file within an allowed credential directory. # Load token from a file within an allowed credential directory.
safe_path = _resolve_oidc_file_path(oidc_aud) safe_path = _resolve_oidc_file_path(oidc_aud)
with open(safe_path, "r") as f: with open(safe_path) as f:
oidc_token = f.read() oidc_token = f.read()
return oidc_token return oidc_token
elif oidc_provider == "env": elif oidc_provider == "env":
@ -271,7 +271,7 @@ def get_secret( # noqa: PLR0915
token_file_path = os.getenv(oidc_aud) token_file_path = os.getenv(oidc_aud)
if token_file_path is None: if token_file_path is None:
raise ValueError(f"Environment variable {oidc_aud} not found") raise ValueError(f"Environment variable {oidc_aud} not found")
with open(token_file_path, "r") as f: with open(token_file_path) as f:
oidc_token = f.read() oidc_token = f.read()
return oidc_token return oidc_token
else: else:

View file

@ -3303,7 +3303,7 @@ def get_optional_params_embeddings( # noqa: PLR0915
if supported_params is None: if supported_params is None:
return return
unsupported_params = {} unsupported_params = {}
for k in non_default_params.keys(): for k in non_default_params:
if k not in supported_params: if k not in supported_params:
unsupported_params[k] = non_default_params[k] unsupported_params[k] = non_default_params[k]
if unsupported_params: if unsupported_params:
@ -3371,7 +3371,7 @@ def get_optional_params_embeddings( # noqa: PLR0915
if ( if (
model is not None model is not None
and "text-embedding-3" not in model and "text-embedding-3" not in model
and "dimensions" in non_default_params.keys() and "dimensions" in non_default_params
and "dimensions" not in (allowed_openai_params or []) and "dimensions" not in (allowed_openai_params or [])
): ):
raise UnsupportedParamsError( raise UnsupportedParamsError(
@ -3712,7 +3712,7 @@ def _remove_unsupported_params(
remove_keys = [] remove_keys = []
if supported_openai_params is None: if supported_openai_params is None:
return {} # no supported params, so no optional openai params to send return {} # no supported params, so no optional openai params to send
for param in non_default_params.keys(): for param in non_default_params:
if param not in supported_openai_params: if param not in supported_openai_params:
remove_keys.append(param) remove_keys.append(param)
for key in remove_keys: for key in remove_keys:
@ -3809,7 +3809,7 @@ class PreProcessNonDefaultParams:
special_params=special_params, special_params=special_params,
custom_llm_provider=custom_llm_provider, custom_llm_provider=custom_llm_provider,
additional_drop_params=additional_drop_params, additional_drop_params=additional_drop_params,
default_param_values={k: None for k in OPENAI_EMBEDDING_PARAMS}, default_param_values=dict.fromkeys(OPENAI_EMBEDDING_PARAMS),
additional_endpoint_specific_params=["input"], additional_endpoint_specific_params=["input"],
) )
) )
@ -3893,7 +3893,7 @@ def remove_sensitive_keys_from_dict(d: dict) -> dict:
""" """
sensitive_key_phrases = ["key", "secret", "access", "credential"] sensitive_key_phrases = ["key", "secret", "access", "credential"]
remove_keys = [] remove_keys = []
for key in d.keys(): for key in d:
if any(phrase in key.lower() for phrase in sensitive_key_phrases): if any(phrase in key.lower() for phrase in sensitive_key_phrases):
remove_keys.append(key) remove_keys.append(key)
for key in remove_keys: for key in remove_keys:
@ -4090,7 +4090,7 @@ def get_optional_params( # noqa: PLR0915
f"\nLiteLLM: Non-Default params passed to completion() {non_default_params}" f"\nLiteLLM: Non-Default params passed to completion() {non_default_params}"
) )
unsupported_params = {} unsupported_params = {}
for k in non_default_params.keys(): for k in non_default_params:
if k not in supported_params: if k not in supported_params:
if k == "user" or k == "stream_options" or k == "stream": if k == "user" or k == "stream_options" or k == "stream":
continue continue
@ -4108,7 +4108,7 @@ def get_optional_params( # noqa: PLR0915
if litellm.drop_params is True or ( if litellm.drop_params is True or (
drop_params is not None and drop_params is True drop_params is not None and drop_params is True
): ):
for k in unsupported_params.keys(): for k in unsupported_params:
non_default_params.pop(k, None) non_default_params.pop(k, None)
else: else:
raise UnsupportedParamsError( raise UnsupportedParamsError(
@ -4692,7 +4692,7 @@ def get_optional_params( # noqa: PLR0915
), ),
) )
# WatsonX-text param check # WatsonX-text param check
for param in passed_params.keys(): for param in passed_params:
if litellm.IBMWatsonXAIConfig().is_watsonx_text_param(param): if litellm.IBMWatsonXAIConfig().is_watsonx_text_param(param):
raise ValueError( raise ValueError(
f"LiteLLM now defaults to Watsonx's `/text/chat` endpoint. Please use the `watsonx_text` provider instead, to call the `/text/generation` endpoint. Param: {param}" f"LiteLLM now defaults to Watsonx's `/text/chat` endpoint. Please use the `watsonx_text` provider instead, to call the `/text/generation` endpoint. Param: {param}"
@ -4853,7 +4853,7 @@ def add_provider_specific_params_to_optional_params(
is False is False
): ):
extra_body = passed_params.pop("extra_body", None) or {} extra_body = passed_params.pop("extra_body", None) or {}
for k in passed_params.keys(): for k in passed_params:
if k not in openai_params and passed_params[k] is not None: if k not in openai_params and passed_params[k] is not None:
extra_body[k] = passed_params[k] extra_body[k] = passed_params[k]
if not isinstance(optional_params.get("extra_body"), dict): if not isinstance(optional_params.get("extra_body"), dict):
@ -4879,7 +4879,7 @@ def add_provider_specific_params_to_optional_params(
extra_body=processed_extra_body extra_body=processed_extra_body
) )
else: else:
for k in passed_params.keys(): for k in passed_params:
if k not in openai_params and passed_params[k] is not None: if k not in openai_params and passed_params[k] is not None:
if _should_drop_param( if _should_drop_param(
k=k, additional_drop_params=additional_drop_params k=k, additional_drop_params=additional_drop_params
@ -7153,7 +7153,7 @@ def read_config_args(config_path) -> dict:
import os import os
os.getcwd() os.getcwd()
with open(config_path, "r") as config_file: with open(config_path) as config_file:
config = json.load(config_file) config = json.load(config_file)
# read keys/ values from config file and return them # read keys/ values from config file and return them