mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-10 08:28:25 +00:00
Merge 073df7b8f5 into e16d79d635
This commit is contained in:
commit
311a03dffa
2 changed files with 43 additions and 7 deletions
|
|
@ -54,6 +54,16 @@ class LiteLLMKeyType(str, enum.Enum):
|
|||
DEFAULT = "default" # Uses default allowed routes
|
||||
|
||||
|
||||
def _is_mapping(value: object) -> TypeIs[Mapping[object, object]]: # guard-ok: raw before-validator payload
|
||||
return isinstance(value, Mapping)
|
||||
|
||||
|
||||
def _reject_expires(values: object) -> object:
|
||||
if _is_mapping(values) and "expires" in values:
|
||||
raise ValueError('expires is not supported on key requests. Set duration instead, e.g. "3600s" or "30d"')
|
||||
return values
|
||||
|
||||
|
||||
class GenerateKeyRequest(KeyRequestBase):
|
||||
tpm_limit: int | None = Field(default=None, ge=0)
|
||||
rpm_limit: int | None = Field(default=None, ge=0)
|
||||
|
|
@ -71,6 +81,11 @@ class GenerateKeyRequest(KeyRequestBase):
|
|||
organization_id: str | None = None
|
||||
project_id: str | None = None
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
def reject_expires(cls, values: object) -> object:
|
||||
return _reject_expires(values)
|
||||
|
||||
@field_validator("team_id", "organization_id", "project_id", mode="before")
|
||||
@classmethod
|
||||
def treat_cleared_id_as_unset(cls, v: object) -> object:
|
||||
|
|
@ -79,10 +94,6 @@ class GenerateKeyRequest(KeyRequestBase):
|
|||
return v
|
||||
|
||||
|
||||
def _is_mapping(value: object) -> TypeIs[Mapping[object, object]]: # guard-ok: raw before-validator payload
|
||||
return isinstance(value, Mapping)
|
||||
|
||||
|
||||
class UpdateKeyRequest(KeyRequestBase):
|
||||
tpm_limit: int | None = Field(default=None, ge=0)
|
||||
rpm_limit: int | None = Field(default=None, ge=0)
|
||||
|
|
@ -103,6 +114,11 @@ class UpdateKeyRequest(KeyRequestBase):
|
|||
description="Omit to retain the project, or send null to detach. Assigning a different project is not supported.",
|
||||
)
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
def reject_expires(cls, values: object) -> object:
|
||||
return _reject_expires(values)
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
def drop_blank_team_id(cls, values: object) -> object:
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ from fastapi.testclient import TestClient
|
|||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
from fastapi import HTTPException
|
||||
from pydantic import JsonValue
|
||||
from pydantic import JsonValue, ValidationError
|
||||
|
||||
import inspect
|
||||
|
||||
|
|
@ -108,6 +108,28 @@ from litellm.types.proxy.management_endpoints.key_management_endpoints import (
|
|||
client = TestClient(app)
|
||||
|
||||
|
||||
def test_key_request_models_reject_expires() -> None:
|
||||
for request_model, request_values in (
|
||||
(GenerateKeyRequest, {"expires": "2026-01-01T00:00:00Z"}),
|
||||
(UpdateKeyRequest, {"key": "sk-x", "expires": "2026-01-01T00:00:00Z"}),
|
||||
(RegenerateKeyRequest, {"expires": "2026-01-01T00:00:00Z"}),
|
||||
(GenerateKeyRequest, {"expires": None}),
|
||||
):
|
||||
with pytest.raises(ValidationError) as exc_info:
|
||||
request_model.model_validate(request_values)
|
||||
assert "duration" in str(exc_info.value)
|
||||
|
||||
|
||||
def test_generate_key_response_preserves_expires() -> None:
|
||||
expires: Final = datetime(2026, 1, 1, tzinfo=timezone.utc)
|
||||
|
||||
assert GenerateKeyResponse(key="sk-x", expires=expires).expires == expires
|
||||
|
||||
|
||||
def test_generate_key_request_accepts_duration_without_expires() -> None:
|
||||
assert GenerateKeyRequest.model_validate({"duration": "1h"}).duration == "1h"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_keys():
|
||||
mock_prisma_client = AsyncMock()
|
||||
|
|
@ -23305,5 +23327,3 @@ def test_key_info_database_not_connected_sanitized_500(
|
|||
finally:
|
||||
proxy_server.app.dependency_overrides.pop(user_api_key_auth, None)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue