diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index b4f64a76fd1..30f24dcde7a 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -1,6 +1,6 @@ import enum import json -from datetime import datetime +from datetime import datetime, timezone from typing import TYPE_CHECKING, Any, Callable, Dict, List, Literal, Optional, Union import httpx @@ -803,6 +803,23 @@ class GenerateRequestBase(LiteLLMPydanticObjectBase): aliases: Optional[dict] = {} object_permission: Optional[LiteLLM_ObjectPermissionBase] = None + @model_validator(mode="after") + def validate_budget_reset_at(self) -> "GenerateRequestBase": + """Validate that budget_reset_at is not in the past""" + if self.budget_reset_at is not None: + # Ensure timezone-aware for comparison + reset_at = self.budget_reset_at + if reset_at.tzinfo is None: + reset_at = reset_at.replace(tzinfo=timezone.utc) + + current_time = datetime.now(timezone.utc) + if reset_at < current_time: + raise ValueError( + f"budget_reset_at cannot be in the past. " + f"Provided: {reset_at.isoformat()}, Current time: {current_time.isoformat()}" + ) + return self + class AllowedVectorStoreIndexItem(LiteLLMPydanticObjectBase): index_name: str