Coverage for .venv/lib/python3.13/site-packages/litellm/proxy/analytics_endpoints/analytics_endpoints.py: 52%

19 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 12:01 +0000

1#### Analytics Endpoints ##### 

2from datetime import datetime, timezone 

3from typing import Annotated, Final 

4 

5import fastapi 

6from fastapi import APIRouter, Depends, HTTPException, status 

7 

8from litellm.proxy._types import * 

9from litellm.proxy.analytics_endpoints.cache_activity import CacheActivityResponse, get_cache_activity 

10from litellm.proxy.auth.user_api_key_auth import user_api_key_auth 

11 

12router: Final = APIRouter() 

13 

14 

15def _parse_date(value: str, param_name: str) -> datetime: 

16 try: 

17 return datetime.strptime(value, "%Y-%m-%d").replace(tzinfo=timezone.utc) 

18 except ValueError: 

19 raise HTTPException( 

20 status_code=status.HTTP_400_BAD_REQUEST, 

21 detail={"error": f"{param_name} must be a YYYY-MM-DD date, got {value!r}"}, 

22 ) 

23 

24 

25@router.get( 

26 "/global/activity/cache_hits", 

27 tags=["Budget & Spend Tracking"], 

28 dependencies=[Depends(user_api_key_auth)], 

29 response_model=CacheActivityResponse, 

30 include_in_schema=False, 

31) 

32async def get_global_activity( 

33 start_date: Annotated[str, fastapi.Query(description="Time from which to start viewing spend")], 

34 end_date: Annotated[str, fastapi.Query(description="Time till which to view spend")], 

35 key_aliases: Annotated[ 

36 list[str] | None, fastapi.Query(description="Only include spend from these key aliases") 

37 ] = None, 

38 models: Annotated[list[str] | None, fastapi.Query(description="Only include spend for these models")] = None, 

39) -> CacheActivityResponse: 

40 """ 

41 Cache activity for the Admin UI cache dashboard, aggregated per call_type: 

42 cache hits vs successful LLM API requests vs failed requests, plus totals 

43 for the stat cards and the available key-alias/model filter options. 

44 """ 

45 from litellm.proxy.proxy_server import prisma_client 

46 

47 if prisma_client is None: 

48 raise HTTPException( 

49 status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, 

50 detail={ 

51 "error": "Database not connected. Connect a database to your proxy - https://docs.litellm.ai/docs/simple_proxy#managing-auth---virtual-keys" 

52 }, 

53 ) 

54 

55 return await get_cache_activity( 

56 prisma_client=prisma_client, 

57 start_date=_parse_date(start_date, "start_date"), 

58 end_date=_parse_date(end_date, "end_date"), 

59 key_aliases=key_aliases or [], 

60 models=models or [], 

61 )