mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-13 08:52:02 +00:00
refactor(alerts): unify model deprecation helper routes
This commit is contained in:
parent
6267dd7bc8
commit
1747cdbddb
8 changed files with 155 additions and 155 deletions
|
|
@ -39,7 +39,7 @@ def _require_admin(user: UserAPIKeyAuth, *, write: bool) -> None:
|
|||
raise HTTPException(status_code=403, detail="Only gateway admins can manage model deprecation alerts")
|
||||
|
||||
|
||||
@router.get("/alerting/model-deprecations/state", tags=["alerting"], response_model=DeprecationAlertState)
|
||||
@router.get("/alerts/model-deprecations/state", tags=["alerts"], response_model=DeprecationAlertState)
|
||||
async def get_deprecation_alert_state(
|
||||
model: Annotated[str, Query(min_length=1, max_length=1024)],
|
||||
deprecation_date: date,
|
||||
|
|
@ -53,7 +53,7 @@ async def get_deprecation_alert_state(
|
|||
return DeprecationAlertState.model_validate(record.param_value)
|
||||
|
||||
|
||||
@router.put("/alerting/model-deprecations/state", tags=["alerting"], response_model=DeprecationAlertState)
|
||||
@router.put("/alerts/model-deprecations/state", tags=["alerts"], response_model=DeprecationAlertState)
|
||||
async def update_deprecation_alert_state(
|
||||
data: DeprecationAlertUpdate,
|
||||
user: Annotated[UserAPIKeyAuth, Depends(user_api_key_auth)],
|
||||
|
|
@ -69,7 +69,7 @@ async def update_deprecation_alert_state(
|
|||
return state
|
||||
|
||||
|
||||
@router.get("/alerting/model-deprecations/tags", tags=["alerting"], response_model=tuple[DeprecationTagUsage, ...])
|
||||
@router.get("/alerts/model-deprecations/tags", tags=["alerts"], response_model=tuple[DeprecationTagUsage, ...])
|
||||
async def get_deprecation_usage_tags(
|
||||
model: Annotated[str, Query(min_length=1, max_length=1024)],
|
||||
api_keys: Annotated[tuple[str, ...], Query(min_length=1, max_length=100)],
|
||||
|
|
|
|||
|
|
@ -123,9 +123,9 @@ class AlertInput(BaseModel, frozen=True):
|
|||
if self.range_start > self.range_end:
|
||||
raise ValueError("range_start must not follow range_end")
|
||||
if (self.kind == "model_deprecation") != (self.deprecation is not None):
|
||||
raise ValueError("Model deprecation issues require deprecation details")
|
||||
raise ValueError("Model deprecation alerts require deprecation details")
|
||||
if (self.kind == "model_deprecation") != (self.family == "retirement"):
|
||||
raise ValueError("Only model deprecation issues use the retirement family")
|
||||
raise ValueError("Only model deprecation alerts use the retirement family")
|
||||
if self.observed_at.tzinfo is None:
|
||||
raise ValueError("observed_at must include a timezone")
|
||||
return self
|
||||
|
|
@ -139,7 +139,7 @@ class Alert(AlertInput, frozen=True):
|
|||
scope_label: str | None = None
|
||||
active: bool = True
|
||||
can_update_status: bool | None = Field(
|
||||
default=None, description="Current reader's status permission, evaluated by the issue-detail endpoint"
|
||||
default=None, description="Current reader's status permission, evaluated by the alert detail endpoint"
|
||||
)
|
||||
can_view_activity: bool | None = Field(
|
||||
default=None, description="Current reader's permission to inspect Activity, keys, users and impact"
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ def client() -> Iterator[tuple[TestClient, UserAPIKeyAuth]]:
|
|||
|
||||
IDENTITY = {"model": "anthropic/claude-sonnet-4-5", "deprecation_date": "2026-11-30"}
|
||||
UPDATE = {**IDENTITY, "status": "resolved", "last_seen_date": "2026-11-04", "last_seen_requests": 123}
|
||||
PATH = "/alerting/model-deprecations/state"
|
||||
PATH = "/alerts/model-deprecations/state"
|
||||
|
||||
|
||||
def test_new_alert_is_open(client: tuple[TestClient, UserAPIKeyAuth]) -> None:
|
||||
|
|
@ -109,7 +109,7 @@ def test_tags_are_scoped_to_model_dates_and_the_visible_keys(client: tuple[TestC
|
|||
table=SimpleNamespace(group_by=grouped)
|
||||
)
|
||||
response = http.get(
|
||||
"/alerting/model-deprecations/tags",
|
||||
"/alerts/model-deprecations/tags",
|
||||
params={
|
||||
"model": "openai/gpt-4-turbo",
|
||||
"api_keys": ["reporting-one", "reporting-two"],
|
||||
|
|
@ -146,7 +146,7 @@ def test_tag_access_matches_alert_visibility(
|
|||
table=SimpleNamespace(group_by=grouped)
|
||||
)
|
||||
response = http.get(
|
||||
"/alerting/model-deprecations/tags",
|
||||
"/alerts/model-deprecations/tags",
|
||||
params={"model": "test-model", "api_keys": ["one"], "start_date": "2026-10-06", "end_date": "2026-11-04"},
|
||||
)
|
||||
assert response.status_code == expected
|
||||
|
|
@ -168,7 +168,7 @@ def test_tag_query_rejects_more_than_100_keys_before_database_access(client: tup
|
|||
table=SimpleNamespace(group_by=grouped)
|
||||
)
|
||||
response = http.get(
|
||||
"/alerting/model-deprecations/tags",
|
||||
"/alerts/model-deprecations/tags",
|
||||
params={
|
||||
"model": "test-model",
|
||||
"api_keys": [f"reporting-{index}" for index in range(101)],
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ export default function MigrationDetail({
|
|||
queryKey: ["deprecationUsageTags", scope, model, range, keys],
|
||||
enabled: keys.length > 0,
|
||||
queryFn: async ({ signal }: { signal: AbortSignal }) => {
|
||||
const { data } = await backgroundFetchClient.GET("/alerting/model-deprecations/tags", {
|
||||
const { data } = await backgroundFetchClient.GET("/alerts/model-deprecations/tags", {
|
||||
params: { query: { ...range, model, api_keys: keys } },
|
||||
signal,
|
||||
});
|
||||
|
|
@ -141,7 +141,7 @@ export default function MigrationDetail({
|
|||
last_seen_date: selected.lastUsedDate,
|
||||
last_seen_requests: selected.lastDayRequests,
|
||||
};
|
||||
const { data } = await backgroundFetchClient.PUT("/alerting/model-deprecations/state", { body });
|
||||
const { data } = await backgroundFetchClient.PUT("/alerts/model-deprecations/state", { body });
|
||||
if (!data) throw new Error("Could not save alert status");
|
||||
return data;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ describe("model migration impact", () => {
|
|||
body: request.method === "PUT" ? await request.clone().json() : null,
|
||||
};
|
||||
calls.push(call);
|
||||
if (url.pathname === "/alerting/model-deprecations/tags") return apiResponse([]);
|
||||
if (request.method === "PUT" && url.pathname === "/alerting/model-deprecations/state")
|
||||
if (url.pathname === "/alerts/model-deprecations/tags") return apiResponse([]);
|
||||
if (request.method === "PUT" && url.pathname === "/alerts/model-deprecations/state")
|
||||
return apiResponse({ status: "resolved" });
|
||||
if (url.pathname.endsWith("/aggregated/keys")) {
|
||||
const offset = Number(url.searchParams.get("offset") || 0);
|
||||
|
|
@ -111,7 +111,7 @@ describe("model migration impact", () => {
|
|||
};
|
||||
await waitFor(() =>
|
||||
expect(
|
||||
calls.find((call) => call.method === "PUT" && call.path === "/alerting/model-deprecations/state")?.body,
|
||||
calls.find((call) => call.method === "PUT" && call.path === "/alerts/model-deprecations/state")?.body,
|
||||
).toEqual(expectedAcknowledgement),
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ describe("deprecation alert API wiring", () => {
|
|||
renderWithProviders(<AlertsHost />);
|
||||
expect(await screen.findByText("1 alerts")).toBeInTheDocument();
|
||||
expect(backgroundFetchClient.GET).toHaveBeenLastCalledWith(
|
||||
"/alerting/model-deprecations/state",
|
||||
"/alerts/model-deprecations/state",
|
||||
expect.objectContaining({
|
||||
params: { query: { model: model.litellm_model, deprecation_date: model.deprecation_date } },
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export function useDeprecationAlerts(accessToken: string | null) {
|
|||
const alerts = usedDeprecationAlerts(models, activity.results ?? []);
|
||||
return Promise.all(
|
||||
alerts.map(async (alert) => {
|
||||
const { data: state } = await backgroundFetchClient.GET("/alerting/model-deprecations/state", {
|
||||
const { data: state } = await backgroundFetchClient.GET("/alerts/model-deprecations/state", {
|
||||
params: { query: { model: alert.usageModel, deprecation_date: alert.model.deprecation_date } },
|
||||
signal,
|
||||
});
|
||||
|
|
|
|||
276
ui/litellm-dashboard/src/lib/http/schema.d.ts
generated
vendored
276
ui/litellm-dashboard/src/lib/http/schema.d.ts
generated
vendored
|
|
@ -944,44 +944,6 @@ export interface paths {
|
|||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/alerting/model-deprecations/state": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** Get Deprecation Alert State */
|
||||
get: operations["get_deprecation_alert_state_alerting_model_deprecations_state_get"];
|
||||
/** Update Deprecation Alert State */
|
||||
put: operations["update_deprecation_alert_state_alerting_model_deprecations_state_put"];
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/alerting/model-deprecations/tags": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/**
|
||||
* Get Deprecation Usage Tags
|
||||
* @description Distinct tags observed with this model for a page of affected reporting key IDs.
|
||||
*/
|
||||
get: operations["get_deprecation_usage_tags_alerting_model_deprecations_tags_get"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/alerting/settings": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
|
|
@ -1053,6 +1015,44 @@ export interface paths {
|
|||
patch: operations["update_alert_default_alerts_defaults__family__patch"];
|
||||
trace?: never;
|
||||
};
|
||||
"/alerts/model-deprecations/state": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/** Get Deprecation Alert State */
|
||||
get: operations["get_deprecation_alert_state_alerts_model_deprecations_state_get"];
|
||||
/** Update Deprecation Alert State */
|
||||
put: operations["update_deprecation_alert_state_alerts_model_deprecations_state_put"];
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/alerts/model-deprecations/tags": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/**
|
||||
* Get Deprecation Usage Tags
|
||||
* @description Distinct tags observed with this model for a page of affected reporting key IDs.
|
||||
*/
|
||||
get: operations["get_deprecation_usage_tags_alerts_model_deprecations_tags_get"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/alerts/models": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
|
|
@ -27280,7 +27280,7 @@ export interface components {
|
|||
active: boolean;
|
||||
/**
|
||||
* Can Update Status
|
||||
* @description Current reader's status permission, evaluated by the issue-detail endpoint
|
||||
* @description Current reader's status permission, evaluated by the alert detail endpoint
|
||||
*/
|
||||
can_update_status?: boolean | null;
|
||||
/**
|
||||
|
|
@ -55147,105 +55147,6 @@ export interface operations {
|
|||
};
|
||||
};
|
||||
};
|
||||
get_deprecation_alert_state_alerting_model_deprecations_state_get: {
|
||||
parameters: {
|
||||
query: {
|
||||
model: string;
|
||||
deprecation_date: string;
|
||||
};
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["DeprecationAlertState"];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
update_deprecation_alert_state_alerting_model_deprecations_state_put: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["DeprecationAlertUpdate"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["DeprecationAlertState"];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
get_deprecation_usage_tags_alerting_model_deprecations_tags_get: {
|
||||
parameters: {
|
||||
query: {
|
||||
model: string;
|
||||
api_keys: string[];
|
||||
start_date: string;
|
||||
end_date: string;
|
||||
};
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["DeprecationTagUsage"][];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
alerting_settings_alerting_settings_get: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
|
|
@ -55358,6 +55259,105 @@ export interface operations {
|
|||
};
|
||||
};
|
||||
};
|
||||
get_deprecation_alert_state_alerts_model_deprecations_state_get: {
|
||||
parameters: {
|
||||
query: {
|
||||
model: string;
|
||||
deprecation_date: string;
|
||||
};
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["DeprecationAlertState"];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
update_deprecation_alert_state_alerts_model_deprecations_state_put: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["DeprecationAlertUpdate"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["DeprecationAlertState"];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
get_deprecation_usage_tags_alerts_model_deprecations_tags_get: {
|
||||
parameters: {
|
||||
query: {
|
||||
model: string;
|
||||
api_keys: string[];
|
||||
start_date: string;
|
||||
end_date: string;
|
||||
};
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["DeprecationTagUsage"][];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
list_alert_models_alerts_models_get: {
|
||||
parameters: {
|
||||
query?: {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue