(Bug fix) - Langfuse / Callback settings stored in DB (#8251)

* fix _decrypt_and_set_db_env_variables

* fix proxy config

* test callbacks in DB

* test langfuse callbacks in db

* test_e2e_langfuse_callbacks_in_db

* proxy_store_model_in_db_tests

* fix proxy_store_model_in_db_tests

* proxy_store_model_in_db_tests

* fix store_model_db_config.yaml

* fix check_langfuse_request

* fix test langfuse base url

* ci/cd run again
This commit is contained in:
Ishaan Jaff 2025-02-04 21:09:37 -08:00 committed by GitHub
parent 1d5370b9e6
commit 7e1b79d446
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 255 additions and 36 deletions

View file

@ -1689,7 +1689,7 @@ class ProxyConfig:
# default to file
config = await self._get_config_from_file(config_file_path=config_file_path)
## UPDATE CONFIG WITH DB
if prisma_client is not None:
if prisma_client is not None and store_model_in_db is True:
config = await self._update_config_from_db(
config=config,
prisma_client=prisma_client,
@ -2525,6 +2525,16 @@ class ProxyConfig:
Adds environment variables from DB config to litellm
"""
environment_variables = config_data.get("environment_variables", {})
self._decrypt_and_set_db_env_variables(environment_variables)
def _decrypt_and_set_db_env_variables(self, environment_variables: dict) -> None:
"""
Decrypts a dictionary of environment variables and then sets them in the environment
Args:
environment_variables: dict - dictionary of environment variables to decrypt and set
eg. `{"LANGFUSE_PUBLIC_KEY": "kFiKa1VZukMmD8RB6WXB9F......."}`
"""
for k, v in environment_variables.items():
try:
decrypted_value = decrypt_value_helper(value=v)
@ -2653,19 +2663,43 @@ class ProxyConfig:
def _update_config_fields(
self,
current_config: dict,
param_name: str,
param_name: Literal[
"general_settings",
"router_settings",
"litellm_settings",
"environment_variables",
],
db_param_value: Any,
) -> dict:
"""
Updates the config fields with the new values from the DB
Args:
current_config (dict): Current configuration dictionary to update
param_name (Literal): Name of the parameter to update
db_param_value (Any): New value from the database
Returns:
dict: Updated configuration dictionary
"""
if param_name == "environment_variables":
self._decrypt_and_set_db_env_variables(db_param_value)
return current_config
# If param doesn't exist in config, add it
if param_name not in current_config:
current_config[param_name] = db_param_value
return current_config
# For dictionary values, update only non-empty values
if isinstance(current_config[param_name], dict):
# if dict exists (e.g. litellm_settings),
# go through each key and value,
# and update if new value is not None/empty dict
for key, value in db_param_value.items():
if value:
current_config[param_name][key] = value
# Only keep non None values from db_param_value
non_empty_values = {k: v for k, v in db_param_value.items() if v}
# Update the config with non-empty values
current_config[param_name].update(non_empty_values)
else:
current_config[param_name] = db_param_value
return current_config
async def _update_config_from_db(
@ -2674,7 +2708,6 @@ class ProxyConfig:
config: dict,
store_model_in_db: Optional[bool],
):
if store_model_in_db is not True:
verbose_proxy_logger.info(
"'store_model_in_db' is not True, skipping db updates"
@ -2696,24 +2729,21 @@ class ProxyConfig:
responses = await asyncio.gather(*_tasks)
for response in responses:
if response is not None:
param_name = getattr(response, "param_name", None)
if param_name == "litellm_settings":
verbose_proxy_logger.info(
f"litellm_settings: {response.param_value}"
)
param_value = getattr(response, "param_value", None)
if param_name is not None and param_value is not None:
# check if param_name is already in the config
if param_name in config:
config = self._update_config_fields(
current_config=config,
param_name=param_name,
db_param_value=param_value,
)
else:
# if it's not in the config - then add it
config[param_name] = param_value
if response is None:
continue
param_name = getattr(response, "param_name", None)
param_value = getattr(response, "param_value", None)
verbose_proxy_logger.debug(
f"param_name={param_name}, param_value={param_value}"
)
if param_name is not None and param_value is not None:
config = self._update_config_fields(
current_config=config,
param_name=param_name,
db_param_value=param_value,
)
return config
@ -5786,7 +5816,7 @@ async def token_counter(request: TokenCountRequest):
model=model_to_use,
text=prompt,
messages=messages,
custom_tokenizer=_tokenizer_used,
custom_tokenizer=_tokenizer_used, # type: ignore
)
return TokenCountResponse(
total_tokens=total_tokens,