Merge pull request #3664 from BerriAI/litellm_revert_3600

[Fix] Revert #3600 https://github.com/BerriAI/litellm/pull/3600
This commit is contained in:
Ishaan Jaff
2024-05-15 20:19:35 -07:00
committed by GitHub
7 changed files with 89 additions and 189 deletions
+49 -60
View File
@@ -1,37 +1,11 @@
from pydantic import ConfigDict, BaseModel, Field, root_validator, Json, VERSION
from pydantic import BaseModel, Extra, Field, root_validator, Json, validator
from dataclasses import fields
import enum
from typing import Optional, List, Union, Dict, Literal, Any
from datetime import datetime
import uuid
import json
import uuid, json, sys, os
from litellm.types.router import UpdateRouterConfig
try:
from pydantic import model_validator # type: ignore
except ImportError:
from pydantic import root_validator # pydantic v1
def model_validator(mode): # type: ignore
pre = mode == "before"
return root_validator(pre=pre)
# Function to get Pydantic version
def is_pydantic_v2() -> int:
return int(VERSION.split(".")[0])
def get_model_config(arbitrary_types_allowed: bool = False) -> ConfigDict:
# Version-specific configuration
if is_pydantic_v2() >= 2:
model_config = ConfigDict(extra="allow", arbitrary_types_allowed=arbitrary_types_allowed, protected_namespaces=()) # type: ignore
else:
from pydantic import Extra
model_config = ConfigDict(extra=Extra.allow, arbitrary_types_allowed=arbitrary_types_allowed) # type: ignore
return model_config
def hash_token(token: str):
import hashlib
@@ -61,7 +35,8 @@ class LiteLLMBase(BaseModel):
# if using pydantic v1
return self.__fields_set__
model_config = get_model_config()
class Config:
protected_namespaces = ()
class LiteLLM_UpperboundKeyGenerateParams(LiteLLMBase):
@@ -104,11 +79,6 @@ class LiteLLMRoutes(enum.Enum):
"/v1/models",
]
# NOTE: ROUTES ONLY FOR MASTER KEY - only the Master Key should be able to Reset Spend
master_key_only_routes: List = [
"/global/spend/reset",
]
info_routes: List = [
"/key/info",
"/team/info",
@@ -119,6 +89,11 @@ class LiteLLMRoutes(enum.Enum):
"/v2/key/info",
]
# NOTE: ROUTES ONLY FOR MASTER KEY - only the Master Key should be able to Reset Spend
master_key_only_routes: List = [
"/global/spend/reset",
]
sso_only_routes: List = [
"/key/generate",
"/key/update",
@@ -259,7 +234,7 @@ class LiteLLMPromptInjectionParams(LiteLLMBase):
llm_api_system_prompt: Optional[str] = None
llm_api_fail_call_string: Optional[str] = None
@model_validator(mode="before")
@root_validator(pre=True)
def check_llm_api_params(cls, values):
llm_api_check = values.get("llm_api_check")
if llm_api_check is True:
@@ -317,7 +292,8 @@ class ProxyChatCompletionRequest(LiteLLMBase):
deployment_id: Optional[str] = None
request_timeout: Optional[int] = None
model_config = get_model_config()
class Config:
extra = "allow" # allow params not defined here, these fall in litellm.completion(**kwargs)
class ModelInfoDelete(LiteLLMBase):
@@ -344,9 +320,11 @@ class ModelInfo(LiteLLMBase):
]
]
model_config = get_model_config()
class Config:
extra = Extra.allow # Allow extra fields
protected_namespaces = ()
@model_validator(mode="before")
@root_validator(pre=True)
def set_model_info(cls, values):
if values.get("id") is None:
values.update({"id": str(uuid.uuid4())})
@@ -372,9 +350,10 @@ class ModelParams(LiteLLMBase):
litellm_params: dict
model_info: ModelInfo
model_config = get_model_config()
class Config:
protected_namespaces = ()
@model_validator(mode="before")
@root_validator(pre=True)
def set_model_info(cls, values):
if values.get("model_info") is None:
values.update({"model_info": ModelInfo()})
@@ -410,7 +389,8 @@ class GenerateKeyRequest(GenerateRequestBase):
{}
) # {"gpt-4": 5.0, "gpt-3.5-turbo": 5.0}, defaults to {}
model_config = get_model_config()
class Config:
protected_namespaces = ()
class GenerateKeyResponse(GenerateKeyRequest):
@@ -420,7 +400,7 @@ class GenerateKeyResponse(GenerateKeyRequest):
user_id: Optional[str] = None
token_id: Optional[str] = None
@model_validator(mode="before")
@root_validator(pre=True)
def set_model_info(cls, values):
if values.get("token") is not None:
values.update({"key": values.get("token")})
@@ -460,7 +440,8 @@ class LiteLLM_ModelTable(LiteLLMBase):
created_by: str
updated_by: str
model_config = get_model_config()
class Config:
protected_namespaces = ()
class NewUserRequest(GenerateKeyRequest):
@@ -488,7 +469,7 @@ class UpdateUserRequest(GenerateRequestBase):
user_role: Optional[str] = None
max_budget: Optional[float] = None
@model_validator(mode="before")
@root_validator(pre=True)
def check_user_info(cls, values):
if values.get("user_id") is None and values.get("user_email") is None:
raise ValueError("Either user id or user email must be provided")
@@ -508,7 +489,7 @@ class NewEndUserRequest(LiteLLMBase):
None # if no equivalent model in allowed region - default all requests to this model
)
@model_validator(mode="before")
@root_validator(pre=True)
def check_user_info(cls, values):
if values.get("max_budget") is not None and values.get("budget_id") is not None:
raise ValueError("Set either 'max_budget' or 'budget_id', not both.")
@@ -521,7 +502,7 @@ class Member(LiteLLMBase):
user_id: Optional[str] = None
user_email: Optional[str] = None
@model_validator(mode="before")
@root_validator(pre=True)
def check_user_info(cls, values):
if values.get("user_id") is None and values.get("user_email") is None:
raise ValueError("Either user id or user email must be provided")
@@ -546,7 +527,8 @@ class TeamBase(LiteLLMBase):
class NewTeamRequest(TeamBase):
model_aliases: Optional[dict] = None
model_config = get_model_config()
class Config:
protected_namespaces = ()
class GlobalEndUsersSpend(LiteLLMBase):
@@ -565,7 +547,7 @@ class TeamMemberDeleteRequest(LiteLLMBase):
user_id: Optional[str] = None
user_email: Optional[str] = None
@model_validator(mode="before")
@root_validator(pre=True)
def check_user_info(cls, values):
if values.get("user_id") is None and values.get("user_email") is None:
raise ValueError("Either user id or user email must be provided")
@@ -599,9 +581,10 @@ class LiteLLM_TeamTable(TeamBase):
budget_reset_at: Optional[datetime] = None
model_id: Optional[int] = None
model_config = get_model_config()
class Config:
protected_namespaces = ()
@model_validator(mode="before")
@root_validator(pre=True)
def set_model_info(cls, values):
dict_fields = [
"metadata",
@@ -637,7 +620,8 @@ class LiteLLM_BudgetTable(LiteLLMBase):
model_max_budget: Optional[dict] = None
budget_duration: Optional[str] = None
model_config = get_model_config()
class Config:
protected_namespaces = ()
class NewOrganizationRequest(LiteLLM_BudgetTable):
@@ -687,7 +671,8 @@ class KeyManagementSettings(LiteLLMBase):
class TeamDefaultSettings(LiteLLMBase):
team_id: str
model_config = get_model_config()
class Config:
extra = "allow" # allow params not defined here, these fall in litellm.completion(**kwargs)
class DynamoDBArgs(LiteLLMBase):
@@ -828,7 +813,8 @@ class ConfigYAML(LiteLLMBase):
description="litellm router object settings. See router.py __init__ for all, example router.num_retries=5, router.timeout=5, router.max_retries=5, router.retry_after=5",
)
model_config = get_model_config()
class Config:
protected_namespaces = ()
class LiteLLM_VerificationToken(LiteLLMBase):
@@ -862,7 +848,8 @@ class LiteLLM_VerificationToken(LiteLLMBase):
user_id_rate_limits: Optional[dict] = None
team_id_rate_limits: Optional[dict] = None
model_config = get_model_config()
class Config:
protected_namespaces = ()
class LiteLLM_VerificationTokenView(LiteLLM_VerificationToken):
@@ -892,7 +879,7 @@ class UserAPIKeyAuth(
user_role: Optional[Literal["proxy_admin", "app_owner", "app_user"]] = None
allowed_model_region: Optional[Literal["eu"]] = None
@model_validator(mode="before")
@root_validator(pre=True)
def check_api_key(cls, values):
if values.get("api_key") is not None:
values.update({"token": hash_token(values.get("api_key"))})
@@ -919,7 +906,7 @@ class LiteLLM_UserTable(LiteLLMBase):
tpm_limit: Optional[int] = None
rpm_limit: Optional[int] = None
@model_validator(mode="before")
@root_validator(pre=True)
def set_model_info(cls, values):
if values.get("spend") is None:
values.update({"spend": 0.0})
@@ -927,7 +914,8 @@ class LiteLLM_UserTable(LiteLLMBase):
values.update({"models": []})
return values
model_config = get_model_config()
class Config:
protected_namespaces = ()
class LiteLLM_EndUserTable(LiteLLMBase):
@@ -939,13 +927,14 @@ class LiteLLM_EndUserTable(LiteLLMBase):
default_model: Optional[str] = None
litellm_budget_table: Optional[LiteLLM_BudgetTable] = None
@model_validator(mode="before")
@root_validator(pre=True)
def set_model_info(cls, values):
if values.get("spend") is None:
values.update({"spend": 0.0})
return values
model_config = get_model_config()
class Config:
protected_namespaces = ()
class LiteLLM_SpendLogs(LiteLLMBase):
+1 -1
View File
@@ -38,7 +38,7 @@ def reset_callbacks():
@pytest.mark.skip(reason="Local test")
def test_response_model_none():
"""
Addresses: https://github.com/BerriAI/litellm/issues/2972
Addresses:https://github.com/BerriAI/litellm/issues/2972
"""
x = completion(
model="mymodel",
+4 -20
View File
@@ -5,7 +5,6 @@
import sys, os
import traceback
from dotenv import load_dotenv
from pydantic import ConfigDict
load_dotenv()
import os, io
@@ -14,36 +13,21 @@ sys.path.insert(
0, os.path.abspath("../..")
) # Adds the parent directory to the, system path
import pytest, litellm
from pydantic import BaseModel, VERSION
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
# Function to get Pydantic version
def is_pydantic_v2() -> int:
return int(VERSION.split(".")[0])
def get_model_config(arbitrary_types_allowed: bool = False) -> ConfigDict:
# Version-specific configuration
if is_pydantic_v2() >= 2:
model_config = ConfigDict(extra="allow", arbitrary_types_allowed=arbitrary_types_allowed, protected_namespaces=()) # type: ignore
else:
from pydantic import Extra
model_config = ConfigDict(extra=Extra.allow, arbitrary_types_allowed=arbitrary_types_allowed) # type: ignore
return model_config
class DBModel(BaseModel):
model_id: str
model_name: str
model_info: dict
litellm_params: dict
model_config = get_model_config()
class Config:
protected_namespaces = ()
@pytest.mark.asyncio
+5 -20
View File
@@ -1,27 +1,10 @@
from typing import List, Optional, Union, Iterable, cast
from typing import List, Optional, Union, Iterable
from pydantic import ConfigDict, BaseModel, validator, VERSION
from pydantic import BaseModel, validator
from typing_extensions import Literal, Required, TypedDict
# Function to get Pydantic version
def is_pydantic_v2() -> int:
return int(VERSION.split(".")[0])
def get_model_config() -> ConfigDict:
# Version-specific configuration
if is_pydantic_v2() >= 2:
model_config = ConfigDict(extra="allow", protected_namespaces=()) # type: ignore
else:
from pydantic import Extra
model_config = ConfigDict(extra=Extra.allow) # type: ignore
return model_config
class ChatCompletionSystemMessageParam(TypedDict, total=False):
content: Required[str]
"""The contents of the system message."""
@@ -208,4 +191,6 @@ class CompletionRequest(BaseModel):
api_key: Optional[str] = None
model_list: Optional[List[str]] = None
model_config = get_model_config()
class Config:
extra = "allow"
protected_namespaces = ()
+5 -19
View File
@@ -1,23 +1,6 @@
from typing import List, Optional, Union
from pydantic import ConfigDict, BaseModel, validator, VERSION
# Function to get Pydantic version
def is_pydantic_v2() -> int:
return int(VERSION.split(".")[0])
def get_model_config(arbitrary_types_allowed: bool = False) -> ConfigDict:
# Version-specific configuration
if is_pydantic_v2() >= 2:
model_config = ConfigDict(extra="allow", arbitrary_types_allowed=arbitrary_types_allowed, protected_namespaces=()) # type: ignore
else:
from pydantic import Extra
model_config = ConfigDict(extra=Extra.allow, arbitrary_types_allowed=arbitrary_types_allowed) # type: ignore
return model_config
from pydantic import BaseModel, validator
class EmbeddingRequest(BaseModel):
@@ -34,4 +17,7 @@ class EmbeddingRequest(BaseModel):
litellm_call_id: Optional[str] = None
litellm_logging_obj: Optional[dict] = None
logger_fn: Optional[str] = None
model_config = get_model_config()
class Config:
# allow kwargs
extra = "allow"
+20 -50
View File
@@ -1,42 +1,19 @@
from typing import List, Optional, Union, Dict, Tuple, Literal, TypedDict
import httpx
from pydantic import (
ConfigDict,
BaseModel,
validator,
Field,
__version__ as pydantic_version,
VERSION,
)
from pydantic import BaseModel, validator, Field
from .completion import CompletionRequest
from .embedding import EmbeddingRequest
import uuid, enum
# Function to get Pydantic version
def is_pydantic_v2() -> int:
return int(VERSION.split(".")[0])
def get_model_config(arbitrary_types_allowed: bool = False) -> ConfigDict:
# Version-specific configuration
if is_pydantic_v2() >= 2:
model_config = ConfigDict(extra="allow", arbitrary_types_allowed=arbitrary_types_allowed, protected_namespaces=()) # type: ignore
else:
from pydantic import Extra
model_config = ConfigDict(extra=Extra.allow, arbitrary_types_allowed=arbitrary_types_allowed) # type: ignore
return model_config
class ModelConfig(BaseModel):
model_name: str
litellm_params: Union[CompletionRequest, EmbeddingRequest]
tpm: int
rpm: int
model_config = get_model_config()
class Config:
protected_namespaces = ()
class RouterConfig(BaseModel):
@@ -67,7 +44,8 @@ class RouterConfig(BaseModel):
"latency-based-routing",
] = "simple-shuffle"
model_config = get_model_config()
class Config:
protected_namespaces = ()
class UpdateRouterConfig(BaseModel):
@@ -87,7 +65,8 @@ class UpdateRouterConfig(BaseModel):
fallbacks: Optional[List[dict]] = None
context_window_fallbacks: Optional[List[dict]] = None
model_config = get_model_config()
class Config:
protected_namespaces = ()
class ModelInfo(BaseModel):
@@ -105,7 +84,8 @@ class ModelInfo(BaseModel):
id = str(id)
super().__init__(id=id, **params)
model_config = get_model_config()
class Config:
extra = "allow"
def __contains__(self, key):
# Define custom behavior for the 'in' operator
@@ -200,15 +180,9 @@ class GenericLiteLLMParams(BaseModel):
max_retries = int(max_retries) # cast to int
super().__init__(max_retries=max_retries, **args, **params)
model_config = get_model_config(arbitrary_types_allowed=True)
if pydantic_version.startswith("1"):
# pydantic v2 warns about using a Config class.
# But without this, pydantic v1 will raise an error:
# RuntimeError: no validator found for <class 'openai.Timeout'>,
# see `arbitrary_types_allowed` in Config
# Putting arbitrary_types_allowed = True in the ConfigDict doesn't work in pydantic v1.
class Config:
arbitrary_types_allowed = True
class Config:
extra = "allow"
arbitrary_types_allowed = True
def __contains__(self, key):
# Define custom behavior for the 'in' operator
@@ -267,16 +241,9 @@ class LiteLLM_Params(GenericLiteLLMParams):
max_retries = int(max_retries) # cast to int
super().__init__(max_retries=max_retries, **args, **params)
model_config = get_model_config(arbitrary_types_allowed=True)
if pydantic_version.startswith("1"):
# pydantic v2 warns about using a Config class.
# But without this, pydantic v1 will raise an error:
# RuntimeError: no validator found for <class 'openai.Timeout'>,
# see `arbitrary_types_allowed` in Config
# Putting arbitrary_types_allowed = True in the ConfigDict doesn't work in pydantic v1.
class Config:
arbitrary_types_allowed = True
class Config:
extra = "allow"
arbitrary_types_allowed = True
def __contains__(self, key):
# Define custom behavior for the 'in' operator
@@ -306,7 +273,8 @@ class updateDeployment(BaseModel):
litellm_params: Optional[updateLiteLLMParams] = None
model_info: Optional[ModelInfo] = None
model_config = get_model_config()
class Config:
protected_namespaces = ()
class LiteLLMParamsTypedDict(TypedDict, total=False):
@@ -380,7 +348,9 @@ class Deployment(BaseModel):
# if using pydantic v1
return self.dict(**kwargs)
model_config = get_model_config()
class Config:
extra = "allow"
protected_namespaces = ()
def __contains__(self, key):
# Define custom behavior for the 'in' operator
+5 -19
View File
@@ -19,7 +19,7 @@ from functools import wraps, lru_cache
import datetime, time
import tiktoken
import uuid
from pydantic import ConfigDict, BaseModel, VERSION
from pydantic import BaseModel
import aiohttp
import textwrap
import logging
@@ -185,23 +185,6 @@ last_fetched_at_keys = None
# }
# Function to get Pydantic version
def is_pydantic_v2() -> int:
return int(VERSION.split(".")[0])
def get_model_config(arbitrary_types_allowed: bool = False) -> ConfigDict:
# Version-specific configuration
if is_pydantic_v2() >= 2:
model_config = ConfigDict(extra="allow", arbitrary_types_allowed=arbitrary_types_allowed, protected_namespaces=()) # type: ignore
else:
from pydantic import Extra
model_config = ConfigDict(extra=Extra.allow, arbitrary_types_allowed=arbitrary_types_allowed) # type: ignore
return model_config
class UnsupportedParamsError(Exception):
def __init__(self, status_code, message):
self.status_code = status_code
@@ -348,7 +331,10 @@ class HiddenParams(OpenAIObject):
original_response: Optional[str] = None
model_id: Optional[str] = None # used in Router for individual deployments
api_base: Optional[str] = None # returns api base used for making completion call
model_config = get_model_config()
class Config:
extra = "allow"
protected_namespaces = ()
def get(self, key, default=None):
# Custom .get() method to access attributes with a default value if the attribute doesn't exist