mirror of
https://github.com/BerriAI/litellm.git
synced 2025-04-26 11:14:04 +00:00
Before: ```shell $ env -i PATH=$PATH poetry run pytest litellm/tests/test_proxy_server.py ====================================== test session starts ====================================== platform darwin -- Python 3.12.3, pytest-7.4.4, pluggy-1.5.0 rootdir: /Users/abramowi/Code/OpenSource/litellm plugins: anyio-4.3.0, asyncio-0.23.6, mock-3.14.0 asyncio: mode=Mode.STRICT collected 12 items litellm/tests/test_proxy_server.py s..........s [100%] ======================================= warnings summary ======================================== ../../../Library/Caches/pypoetry/virtualenvs/litellm-Fe7WjZrx-py3.12/lib/python3.12/site-packages/pydantic/_internal/_config.py:284: 25 warnings /Users/abramowi/Library/Caches/pypoetry/virtualenvs/litellm-Fe7WjZrx-py3.12/lib/python3.12/site-packages/pydantic/_internal/_config.py:284: PydanticDeprecatedSince20: Support for class-based `config` is deprecated, use ConfigDict instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/ warnings.warn(DEPRECATION_MESSAGE, DeprecationWarning) litellm/proxy/_types.py:225 /Users/abramowi/Code/OpenSource/litellm/litellm/proxy/_types.py:225: PydanticDeprecatedSince20: Pydantic V1 style `@root_validator` validators are deprecated. You should migrate to Pydantic V2 style `@model_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/ @root_validator(pre=True) litellm/proxy/_types.py:312 /Users/abramowi/Code/OpenSource/litellm/litellm/proxy/_types.py:312: PydanticDeprecatedSince20: `pydantic.config.Extra` is deprecated, use literal values instead (e.g. `extra='allow'`). Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/ extra = Extra.allow # Allow extra fields litellm/proxy/_types.py:315 /Users/abramowi/Code/OpenSource/litellm/litellm/proxy/_types.py:315: PydanticDeprecatedSince20: Pydantic V1 style `@root_validator` validators are deprecated. You should migrate to Pydantic V2 style `@model_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/ @root_validator(pre=True) litellm/proxy/_types.py:344 /Users/abramowi/Code/OpenSource/litellm/litellm/proxy/_types.py:344: PydanticDeprecatedSince20: Pydantic V1 style `@root_validator` validators are deprecated. You should migrate to Pydantic V2 style `@model_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/ @root_validator(pre=True) litellm/proxy/_types.py:391 /Users/abramowi/Code/OpenSource/litellm/litellm/proxy/_types.py:391: PydanticDeprecatedSince20: Pydantic V1 style `@root_validator` validators are deprecated. You should migrate to Pydantic V2 style `@model_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/ @root_validator(pre=True) litellm/proxy/_types.py:460 /Users/abramowi/Code/OpenSource/litellm/litellm/proxy/_types.py:460: PydanticDeprecatedSince20: Pydantic V1 style `@root_validator` validators are deprecated. You should migrate to Pydantic V2 style `@model_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/ @root_validator(pre=True) litellm/proxy/_types.py:480 /Users/abramowi/Code/OpenSource/litellm/litellm/proxy/_types.py:480: PydanticDeprecatedSince20: Pydantic V1 style `@root_validator` validators are deprecated. You should migrate to Pydantic V2 style `@model_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/ @root_validator(pre=True) litellm/proxy/_types.py:493 /Users/abramowi/Code/OpenSource/litellm/litellm/proxy/_types.py:493: PydanticDeprecatedSince20: Pydantic V1 style `@root_validator` validators are deprecated. You should migrate to Pydantic V2 style `@model_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/ @root_validator(pre=True) litellm/proxy/_types.py:538 /Users/abramowi/Code/OpenSource/litellm/litellm/proxy/_types.py:538: PydanticDeprecatedSince20: Pydantic V1 style `@root_validator` validators are deprecated. You should migrate to Pydantic V2 style `@model_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/ @root_validator(pre=True) litellm/proxy/_types.py:575 /Users/abramowi/Code/OpenSource/litellm/litellm/proxy/_types.py:575: PydanticDeprecatedSince20: Pydantic V1 style `@root_validator` validators are deprecated. You should migrate to Pydantic V2 style `@model_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/ @root_validator(pre=True) litellm/proxy/_types.py:870 /Users/abramowi/Code/OpenSource/litellm/litellm/proxy/_types.py:870: PydanticDeprecatedSince20: Pydantic V1 style `@root_validator` validators are deprecated. You should migrate to Pydantic V2 style `@model_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/ @root_validator(pre=True) litellm/proxy/_types.py:897 /Users/abramowi/Code/OpenSource/litellm/litellm/proxy/_types.py:897: PydanticDeprecatedSince20: Pydantic V1 style `@root_validator` validators are deprecated. You should migrate to Pydantic V2 style `@model_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/ @root_validator(pre=True) litellm/proxy/_types.py:918 /Users/abramowi/Code/OpenSource/litellm/litellm/proxy/_types.py:918: PydanticDeprecatedSince20: Pydantic V1 style `@root_validator` validators are deprecated. You should migrate to Pydantic V2 style `@model_validator` validators, see the migration guide for more details. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.7/migration/ @root_validator(pre=True) litellm/utils.py:43 /Users/abramowi/Code/OpenSource/litellm/litellm/utils.py:43: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html import pkg_resources # type: ignore litellm/tests/test_proxy_server.py::test_bedrock_embedding litellm/tests/test_proxy_server.py::test_chat_completion litellm/tests/test_proxy_server.py::test_chat_completion_azure litellm/tests/test_proxy_server.py::test_chat_completion_optional_params litellm/tests/test_proxy_server.py::test_embedding litellm/tests/test_proxy_server.py::test_engines_model_chat_completions litellm/tests/test_proxy_server.py::test_health litellm/tests/test_proxy_server.py::test_img_gen litellm/tests/test_proxy_server.py::test_openai_deployments_model_chat_completions_azure /Users/abramowi/Library/Caches/pypoetry/virtualenvs/litellm-Fe7WjZrx-py3.12/lib/python3.12/site-packages/httpx/_client.py:680: DeprecationWarning: The 'app' shortcut is now deprecated. Use the explicit style 'transport=WSGITransport(app=...)' instead. warnings.warn(message, DeprecationWarning) -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html ========================== 10 passed, 2 skipped, 48 warnings in 9.83s =========================== ``` After: ```shell $ env -i PATH=$PATH poetry run pytest litellm/tests/test_proxy_server.py ====================================== test session starts ====================================== platform darwin -- Python 3.12.3, pytest-7.4.4, pluggy-1.5.0 rootdir: /Users/abramowi/Code/OpenSource/litellm plugins: anyio-4.3.0, asyncio-0.23.6, mock-3.14.0 asyncio: mode=Mode.STRICT collected 12 items litellm/tests/test_proxy_server.py s..........s [100%] ======================================= warnings summary ======================================== litellm/utils.py:43 /Users/abramowi/Code/OpenSource/litellm/litellm/utils.py:43: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html import pkg_resources # type: ignore litellm/tests/test_proxy_server.py::test_bedrock_embedding litellm/tests/test_proxy_server.py::test_chat_completion litellm/tests/test_proxy_server.py::test_chat_completion_azure litellm/tests/test_proxy_server.py::test_chat_completion_optional_params litellm/tests/test_proxy_server.py::test_embedding litellm/tests/test_proxy_server.py::test_engines_model_chat_completions litellm/tests/test_proxy_server.py::test_health litellm/tests/test_proxy_server.py::test_img_gen litellm/tests/test_proxy_server.py::test_openai_deployments_model_chat_completions_azure /Users/abramowi/Library/Caches/pypoetry/virtualenvs/litellm-Fe7WjZrx-py3.12/lib/python3.12/site-packages/httpx/_client.py:680: DeprecationWarning: The 'app' shortcut is now deprecated. Use the explicit style 'transport=WSGITransport(app=...)' instead. warnings.warn(message, DeprecationWarning) -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html ========================== 10 passed, 2 skipped, 10 warnings in 9.62s =========================== ```
283 lines
8.1 KiB
Python
283 lines
8.1 KiB
Python
# What is this?
|
|
## Unit tests for ProxyConfig class
|
|
|
|
|
|
import sys, os
|
|
import traceback
|
|
from dotenv import load_dotenv
|
|
from pydantic import ConfigDict
|
|
|
|
load_dotenv()
|
|
import os, io
|
|
|
|
sys.path.insert(
|
|
0, os.path.abspath("../..")
|
|
) # Adds the parent directory to the, system path
|
|
import pytest, litellm
|
|
from pydantic import BaseModel
|
|
from litellm.proxy.proxy_server import ProxyConfig
|
|
from litellm.proxy.utils import encrypt_value, ProxyLogging, DualCache
|
|
from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo
|
|
from typing import Literal
|
|
|
|
|
|
class DBModel(BaseModel):
|
|
model_id: str
|
|
model_name: str
|
|
model_info: dict
|
|
litellm_params: dict
|
|
model_config = ConfigDict(protected_namespaces=())
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_delete_deployment():
|
|
"""
|
|
- Ensure the global llm router is not being reset
|
|
- Ensure invalid model is deleted
|
|
- Check if model id != model_info["id"], the model_info["id"] is picked
|
|
"""
|
|
import base64
|
|
|
|
litellm_params = LiteLLM_Params(
|
|
model="azure/chatgpt-v-2",
|
|
api_key=os.getenv("AZURE_API_KEY"),
|
|
api_base=os.getenv("AZURE_API_BASE"),
|
|
api_version=os.getenv("AZURE_API_VERSION"),
|
|
)
|
|
encrypted_litellm_params = litellm_params.dict(exclude_none=True)
|
|
|
|
master_key = "sk-1234"
|
|
|
|
setattr(litellm.proxy.proxy_server, "master_key", master_key)
|
|
|
|
for k, v in encrypted_litellm_params.items():
|
|
if isinstance(v, str):
|
|
encrypted_value = encrypt_value(v, master_key)
|
|
encrypted_litellm_params[k] = base64.b64encode(encrypted_value).decode(
|
|
"utf-8"
|
|
)
|
|
|
|
deployment = Deployment(model_name="gpt-3.5-turbo", litellm_params=litellm_params)
|
|
deployment_2 = Deployment(
|
|
model_name="gpt-3.5-turbo-2", litellm_params=litellm_params
|
|
)
|
|
|
|
llm_router = litellm.Router(
|
|
model_list=[
|
|
deployment.to_json(exclude_none=True),
|
|
deployment_2.to_json(exclude_none=True),
|
|
]
|
|
)
|
|
setattr(litellm.proxy.proxy_server, "llm_router", llm_router)
|
|
print(f"llm_router: {llm_router}")
|
|
|
|
pc = ProxyConfig()
|
|
|
|
db_model = DBModel(
|
|
model_id=deployment.model_info.id,
|
|
model_name="gpt-3.5-turbo",
|
|
litellm_params=encrypted_litellm_params,
|
|
model_info={"id": deployment.model_info.id},
|
|
)
|
|
|
|
db_models = [db_model]
|
|
deleted_deployments = await pc._delete_deployment(db_models=db_models)
|
|
|
|
assert deleted_deployments == 1
|
|
assert len(llm_router.model_list) == 1
|
|
|
|
"""
|
|
Scenario 2 - if model id != model_info["id"]
|
|
"""
|
|
|
|
llm_router = litellm.Router(
|
|
model_list=[
|
|
deployment.to_json(exclude_none=True),
|
|
deployment_2.to_json(exclude_none=True),
|
|
]
|
|
)
|
|
print(f"llm_router: {llm_router}")
|
|
setattr(litellm.proxy.proxy_server, "llm_router", llm_router)
|
|
pc = ProxyConfig()
|
|
|
|
db_model = DBModel(
|
|
model_id="12340523",
|
|
model_name="gpt-3.5-turbo",
|
|
litellm_params=encrypted_litellm_params,
|
|
model_info={"id": deployment.model_info.id},
|
|
)
|
|
|
|
db_models = [db_model]
|
|
deleted_deployments = await pc._delete_deployment(db_models=db_models)
|
|
|
|
assert deleted_deployments == 1
|
|
assert len(llm_router.model_list) == 1
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_add_existing_deployment():
|
|
"""
|
|
- Only add new models
|
|
- don't re-add existing models
|
|
"""
|
|
import base64
|
|
|
|
litellm_params = LiteLLM_Params(
|
|
model="gpt-3.5-turbo",
|
|
api_key=os.getenv("AZURE_API_KEY"),
|
|
api_base=os.getenv("AZURE_API_BASE"),
|
|
api_version=os.getenv("AZURE_API_VERSION"),
|
|
)
|
|
deployment = Deployment(model_name="gpt-3.5-turbo", litellm_params=litellm_params)
|
|
deployment_2 = Deployment(
|
|
model_name="gpt-3.5-turbo-2", litellm_params=litellm_params
|
|
)
|
|
|
|
llm_router = litellm.Router(
|
|
model_list=[
|
|
deployment.to_json(exclude_none=True),
|
|
deployment_2.to_json(exclude_none=True),
|
|
]
|
|
)
|
|
|
|
init_len_list = len(llm_router.model_list)
|
|
print(f"llm_router: {llm_router}")
|
|
master_key = "sk-1234"
|
|
setattr(litellm.proxy.proxy_server, "llm_router", llm_router)
|
|
setattr(litellm.proxy.proxy_server, "master_key", master_key)
|
|
pc = ProxyConfig()
|
|
|
|
encrypted_litellm_params = litellm_params.dict(exclude_none=True)
|
|
|
|
for k, v in encrypted_litellm_params.items():
|
|
if isinstance(v, str):
|
|
encrypted_value = encrypt_value(v, master_key)
|
|
encrypted_litellm_params[k] = base64.b64encode(encrypted_value).decode(
|
|
"utf-8"
|
|
)
|
|
db_model = DBModel(
|
|
model_id=deployment.model_info.id,
|
|
model_name="gpt-3.5-turbo",
|
|
litellm_params=encrypted_litellm_params,
|
|
model_info={"id": deployment.model_info.id},
|
|
)
|
|
|
|
db_models = [db_model]
|
|
num_added = pc._add_deployment(db_models=db_models)
|
|
|
|
assert init_len_list == len(llm_router.model_list)
|
|
|
|
|
|
litellm_params = LiteLLM_Params(
|
|
model="azure/chatgpt-v-2",
|
|
api_key=os.getenv("AZURE_API_KEY"),
|
|
api_base=os.getenv("AZURE_API_BASE"),
|
|
api_version=os.getenv("AZURE_API_VERSION"),
|
|
)
|
|
|
|
deployment = Deployment(model_name="gpt-3.5-turbo", litellm_params=litellm_params)
|
|
deployment_2 = Deployment(model_name="gpt-3.5-turbo-2", litellm_params=litellm_params)
|
|
|
|
|
|
def _create_model_list(flag_value: Literal[0, 1], master_key: str):
|
|
"""
|
|
0 - empty list
|
|
1 - list with an element
|
|
"""
|
|
import base64
|
|
|
|
new_litellm_params = LiteLLM_Params(
|
|
model="azure/chatgpt-v-2-3",
|
|
api_key=os.getenv("AZURE_API_KEY"),
|
|
api_base=os.getenv("AZURE_API_BASE"),
|
|
api_version=os.getenv("AZURE_API_VERSION"),
|
|
)
|
|
|
|
encrypted_litellm_params = new_litellm_params.dict(exclude_none=True)
|
|
|
|
for k, v in encrypted_litellm_params.items():
|
|
if isinstance(v, str):
|
|
encrypted_value = encrypt_value(v, master_key)
|
|
encrypted_litellm_params[k] = base64.b64encode(encrypted_value).decode(
|
|
"utf-8"
|
|
)
|
|
db_model = DBModel(
|
|
model_id="12345",
|
|
model_name="gpt-3.5-turbo",
|
|
litellm_params=encrypted_litellm_params,
|
|
model_info={"id": "12345"},
|
|
)
|
|
|
|
db_models = [db_model]
|
|
|
|
if flag_value == 0:
|
|
return []
|
|
elif flag_value == 1:
|
|
return db_models
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"llm_router",
|
|
[
|
|
None,
|
|
litellm.Router(),
|
|
litellm.Router(
|
|
model_list=[
|
|
deployment.to_json(exclude_none=True),
|
|
deployment_2.to_json(exclude_none=True),
|
|
]
|
|
),
|
|
],
|
|
)
|
|
@pytest.mark.parametrize(
|
|
"model_list_flag_value",
|
|
[0, 1],
|
|
)
|
|
@pytest.mark.asyncio
|
|
async def test_add_and_delete_deployments(llm_router, model_list_flag_value):
|
|
"""
|
|
Test add + delete logic in 3 scenarios
|
|
- when router is none
|
|
- when router is init but empty
|
|
- when router is init and not empty
|
|
"""
|
|
|
|
master_key = "sk-1234"
|
|
setattr(litellm.proxy.proxy_server, "llm_router", llm_router)
|
|
setattr(litellm.proxy.proxy_server, "master_key", master_key)
|
|
pc = ProxyConfig()
|
|
pl = ProxyLogging(DualCache())
|
|
|
|
async def _monkey_patch_get_config(*args, **kwargs):
|
|
print(f"ENTERS MP GET CONFIG")
|
|
if llm_router is None:
|
|
return {}
|
|
else:
|
|
print(f"llm_router.model_list: {llm_router.model_list}")
|
|
return {"model_list": llm_router.model_list}
|
|
|
|
pc.get_config = _monkey_patch_get_config
|
|
|
|
model_list = _create_model_list(
|
|
flag_value=model_list_flag_value, master_key=master_key
|
|
)
|
|
|
|
if llm_router is None:
|
|
prev_llm_router_val = None
|
|
else:
|
|
prev_llm_router_val = len(llm_router.model_list)
|
|
|
|
await pc._update_llm_router(new_models=model_list, proxy_logging_obj=pl)
|
|
|
|
llm_router = getattr(litellm.proxy.proxy_server, "llm_router")
|
|
|
|
if model_list_flag_value == 0:
|
|
if prev_llm_router_val is None:
|
|
assert prev_llm_router_val == llm_router
|
|
else:
|
|
assert prev_llm_router_val == len(llm_router.model_list)
|
|
else:
|
|
if prev_llm_router_val is None:
|
|
assert len(llm_router.model_list) == len(model_list)
|
|
else:
|
|
assert len(llm_router.model_list) == len(model_list) + prev_llm_router_val
|