mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-11 08:38:24 +00:00
fix(proxy): tag the deprecation email cache calls with their service family
This commit is contained in:
parent
67d4d01911
commit
50e1bf12eb
2 changed files with 33 additions and 0 deletions
|
|
@ -13,6 +13,7 @@ from typing import TYPE_CHECKING, Final, Protocol
|
|||
|
||||
from pydantic import BaseModel, ConfigDict, Field, ValidationError
|
||||
|
||||
from litellm._internal_context import with_service_target
|
||||
from litellm._logging import verbose_proxy_logger
|
||||
from litellm.constants import EMAIL_MODEL_DEPRECATION_LOCK_ID
|
||||
from litellm.integrations.email_alerting import (
|
||||
|
|
@ -288,6 +289,9 @@ def render_model_deprecation_email(
|
|||
return subject, body + EMAIL_FOOTER
|
||||
|
||||
|
||||
_DEPRECATION_EMAIL_TARGET: Final = "model_deprecation_emails"
|
||||
|
||||
|
||||
_ENTERPRISE_BASE_EMAIL_LOGGER: Final = (
|
||||
"litellm_enterprise.enterprise_callbacks.send_emails.base_email",
|
||||
"BaseEmailLogger",
|
||||
|
|
@ -351,6 +355,7 @@ async def _stamp_pass(cache: DeprecationEmailCache) -> None:
|
|||
)
|
||||
|
||||
|
||||
@with_service_target(_DEPRECATION_EMAIL_TARGET)
|
||||
async def email_pass_done_today(cache: DeprecationEmailCache) -> bool:
|
||||
return (await cache.async_get_cache(key=SlackAlertingCacheKeys.deprecation_email_pass_key.value)) is not None
|
||||
|
||||
|
|
@ -390,6 +395,7 @@ async def _send_team_notification(notification: TeamNotification, ctx: Deprecati
|
|||
return True
|
||||
|
||||
|
||||
@with_service_target(_DEPRECATION_EMAIL_TARGET)
|
||||
async def send_model_deprecation_emails(ctx: DeprecationEmailContext) -> int:
|
||||
"""One pass: resolve affected teams, claim the day only when there is something to send, deliver, then stamp
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from unittest.mock import MagicMock
|
|||
|
||||
import pytest
|
||||
|
||||
from litellm._internal_context import current_service_target
|
||||
from litellm.caching.caching import DualCache
|
||||
from litellm.constants import EMAIL_MODEL_DEPRECATION_LOCK_ID
|
||||
from litellm.models.team import LiteLLM_TeamTable
|
||||
|
|
@ -469,6 +470,20 @@ class _RecordingCache:
|
|||
self.ttls[key] = ttl
|
||||
|
||||
|
||||
class _TargetRecordingCache(_RecordingCache):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.targets = []
|
||||
|
||||
async def async_get_cache(self, *, key: str) -> object:
|
||||
self.targets.append(current_service_target())
|
||||
return await super().async_get_cache(key=key)
|
||||
|
||||
async def async_set_cache(self, *, key: str, value: float, ttl: float) -> None:
|
||||
self.targets.append(current_service_target())
|
||||
await super().async_set_cache(key=key, value=value, ttl=ttl)
|
||||
|
||||
|
||||
def _team_row(team_id: str, alias: str = "Team") -> Mapping[str, object]:
|
||||
return {
|
||||
"team_id": team_id,
|
||||
|
|
@ -707,6 +722,18 @@ async def test_should_report_whether_the_daily_pass_already_ran():
|
|||
assert await email_pass_done_today(cache) is True
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_should_tag_every_cache_read_and_write_with_the_deprecation_email_family():
|
||||
cache: Final = _TargetRecordingCache()
|
||||
ctx: Final = _context(_router([DEAD_DEPLOYMENT]), _prisma(TWO_TEAMS[:1], TWO_ADMINS), _Deliverer(), cache)
|
||||
|
||||
assert await email_pass_done_today(cache) is False
|
||||
assert await send_model_deprecation_emails(ctx) == 1
|
||||
assert len(cache.targets) >= 3
|
||||
assert set(cache.targets) == {"model_deprecation_emails"}
|
||||
assert current_service_target() is None
|
||||
|
||||
|
||||
class TestMakeEmailDeliverer:
|
||||
@pytest.mark.asyncio
|
||||
async def test_should_use_the_configured_email_logger_once_per_recipient(self):
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue