Merge pull request #45922 from BerriAI/litellm_whats_new_local_default_rc_1_106_0

fix(home): serve the bundled whats_new.json by default on rc/1.106.0
This commit is contained in:
Mateo Wang 2026-10-10 23:03:42 -07:00 • committed by GitHub
commit c7a3fee491
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 36 additions and 15 deletions

View file

@ -439,10 +439,7 @@ autorouter_presets_url: str = os.getenv(
"LITELLM_AUTOROUTER_PRESETS_URL",
"https://raw.githubusercontent.com/BerriAI/litellm/main/litellm/proxy/public_endpoints/autorouter_presets.json",
)
whats_new_url: str = os.getenv(
"LITELLM_WHATS_NEW_URL",
"https://raw.githubusercontent.com/BerriAI/litellm/main/litellm/proxy/public_endpoints/whats_new.json",
)
whats_new_url: str | None = os.getenv("LITELLM_WHATS_NEW_URL")
suppress_debug_info: bool = False
dynamodb_table_name: Optional[str] = None
s3_callback_params: Optional[Dict] = None

View file

@ -591,8 +591,8 @@ async def _fetch_remote_whats_new(url: str) -> WhatsNewResponse:
return WhatsNewResponse.model_validate_json(await _fetch_remote_bytes(url))
async def _resolve_whats_new(url: str, fetch: Callable[[str], Awaitable[WhatsNewResponse]]) -> WhatsNewResponse:
if os.getenv("LITELLM_LOCAL_WHATS_NEW", "").lower() == "true":
async def _resolve_whats_new(url: str | None, fetch: Callable[[str], Awaitable[WhatsNewResponse]]) -> WhatsNewResponse:
if url is None or os.getenv("LITELLM_LOCAL_WHATS_NEW", "").lower() == "true":
return _load_bundled_whats_new()
try:
return await fetch(url)
@ -611,7 +611,7 @@ class _WhatsNewCache:
async def get_whats_new(
url: str,
url: str | None,
fetch: Callable[[str], Awaitable[WhatsNewResponse]] = _fetch_remote_whats_new,
) -> WhatsNewResponse:
cached: Final = _WhatsNewCache.launches
@ -637,10 +637,10 @@ async def get_public_whats_new() -> WhatsNewResponse:
"""
Return the launches the dashboard Home page shows under What's new.
Resolved once per process: fetched from ``litellm.whats_new_url`` (override with ``LITELLM_WHATS_NEW_URL``)
on the first request, falling back to the list bundled with the package on any failure, so an airgapped
proxy serves the bundled list without retrying. Set ``LITELLM_LOCAL_WHATS_NEW=True`` to skip the fetch.
A restart picks up a newly published list.
Serves the list bundled with this release. Set ``LITELLM_WHATS_NEW_URL`` to fetch a remote list instead,
resolved once per process on the first request and falling back to the bundled list on any failure, so an
airgapped proxy serves the bundled list without retrying. ``LITELLM_LOCAL_WHATS_NEW=True`` forces the
bundled list even when a URL is set. A restart picks up a newly published list.
"""
return await get_whats_new(url=litellm.whats_new_url)

View file

@ -1,4 +1,5 @@
import json
import os
import re
from datetime import datetime, timezone
from importlib.resources import files
@ -8,6 +9,8 @@ from unittest.mock import AsyncMock, MagicMock, patch
import pytest
import litellm
from fastapi import FastAPI
from fastapi.testclient import TestClient
@ -1586,6 +1589,27 @@ def test_get_whats_new_local_mode_serves_bundled_list(
assert len(served.launches) > 0
@pytest.mark.asyncio
async def test_get_whats_new_serves_bundled_list_without_fetching_when_no_url_is_configured(
monkeypatch: pytest.MonkeyPatch, reset_whats_new_cache: None
) -> None:
from litellm.proxy.public_endpoints.public_endpoints import _load_bundled_whats_new, get_whats_new
monkeypatch.delenv("LITELLM_LOCAL_WHATS_NEW", raising=False)
async def forbidden_fetch(url: str) -> WhatsNewResponse:
raise AssertionError(f"no URL is configured, so nothing may be fetched, got {url}")
served = await get_whats_new(url=None, fetch=forbidden_fetch)
assert served == _load_bundled_whats_new()
assert len(served.launches) > 0
def test_whats_new_url_defaults_to_unset_so_only_the_env_var_opts_into_a_remote_list() -> None:
assert litellm.whats_new_url == os.getenv("LITELLM_WHATS_NEW_URL")
@pytest.mark.asyncio
async def test_get_whats_new_fetches_once_per_process(
monkeypatch: pytest.MonkeyPatch, reset_whats_new_cache: None

View file

@ -14163,10 +14163,10 @@ export interface paths {
* Get Public Whats New
* @description Return the launches the dashboard Home page shows under What's new.
*
* Resolved once per process: fetched from ``litellm.whats_new_url`` (override with ``LITELLM_WHATS_NEW_URL``)
* on the first request, falling back to the list bundled with the package on any failure, so an airgapped
* proxy serves the bundled list without retrying. Set ``LITELLM_LOCAL_WHATS_NEW=True`` to skip the fetch.
* A restart picks up a newly published list.
* Serves the list bundled with this release. Set ``LITELLM_WHATS_NEW_URL`` to fetch a remote list instead,
* resolved once per process on the first request and falling back to the bundled list on any failure, so an
* airgapped proxy serves the bundled list without retrying. ``LITELLM_LOCAL_WHATS_NEW=True`` forces the
* bundled list even when a URL is set. A restart picks up a newly published list.
*/
get: operations["get_public_whats_new_public_whats_new_get"];
put?: never;