Merge branch 'main' into litellm_use_redis_for_updates

This commit is contained in:
Ishaan Jaff 2025-03-28 20:12:29 -07:00
commit 7e8a02099c
140 changed files with 2806 additions and 427 deletions

View file

@ -24,6 +24,7 @@ from typing import (
get_type_hints,
)
from litellm.constants import DEFAULT_MAX_RECURSE_DEPTH
from litellm.types.utils import (
ModelResponse,
ModelResponseStream,
@ -462,6 +463,8 @@ async def proxy_startup_event(app: FastAPI):
if premium_user is False:
premium_user = _license_check.is_premium()
## CHECK MASTER KEY IN ENVIRONMENT ##
master_key = get_secret_str("LITELLM_MASTER_KEY")
### LOAD CONFIG ###
worker_config: Optional[Union[str, dict]] = get_secret("WORKER_CONFIG") # type: ignore
env_config_yaml: Optional[str] = get_secret_str("CONFIG_FILE_PATH")
@ -509,9 +512,6 @@ async def proxy_startup_event(app: FastAPI):
if isinstance(worker_config, dict):
await initialize(**worker_config)
### LOAD MASTER KEY ###
# check if master key set in environment - load from there
master_key = get_secret("LITELLM_MASTER_KEY", None) # type: ignore
# check if DATABASE_URL in environment - load from there
if prisma_client is None:
_db_url: Optional[str] = get_secret("DATABASE_URL", None) # type: ignore
@ -1320,7 +1320,7 @@ class ProxyConfig:
yaml.dump(new_config, config_file, default_flow_style=False)
def _check_for_os_environ_vars(
self, config: dict, depth: int = 0, max_depth: int = 10
self, config: dict, depth: int = 0, max_depth: int = DEFAULT_MAX_RECURSE_DEPTH
) -> dict:
"""
Check for os.environ/ variables in the config and replace them with the actual values.
@ -1769,6 +1769,7 @@ class ProxyConfig:
if master_key and master_key.startswith("os.environ/"):
master_key = get_secret(master_key) # type: ignore
if not isinstance(master_key, str):
raise Exception(
"Master key must be a string. Current type - {}".format(
@ -3231,6 +3232,7 @@ async def model_list(
else:
proxy_model_list = llm_router.get_model_names()
model_access_groups = llm_router.get_model_access_groups()
key_models = get_key_models(
user_api_key_dict=user_api_key_dict,
proxy_model_list=proxy_model_list,
@ -3240,6 +3242,7 @@ async def model_list(
team_models: List[str] = user_api_key_dict.team_models
if team_id:
key_models = []
team_object = await get_team_object(
team_id=team_id,
prisma_client=prisma_client,
@ -3256,7 +3259,7 @@ async def model_list(
)
all_models = get_complete_model_list(
key_models=key_models if not team_models else [],
key_models=key_models,
team_models=team_models,
proxy_model_list=proxy_model_list,
user_model=user_model,
@ -6690,6 +6693,14 @@ async def login(request: Request): # noqa: PLR0915
user_email = getattr(_user_row, "user_email", "unknown")
_password = getattr(_user_row, "password", "unknown")
if _password is None:
raise ProxyException(
message="User has no password set. Please set a password for the user via `/user/update`.",
type=ProxyErrorTypes.auth_error,
param="password",
code=status.HTTP_401_UNAUTHORIZED,
)
# check if password == _user_row.password
hash_password = hash_token(token=password)
if secrets.compare_digest(password, _password) or secrets.compare_digest(