
    ^hJ                    @   S SK r S SKJrJr  S SKJrJr  S SKrS SKJrJrJ	r	J
r
Jr  S SKrS SKJr  S SK7  S SKJrJr  S SKJr  S S	KJr  S S
KJr  \" 5       r\R3                  SS/\" \5      /SS9S 5       r\R3                  SS/\" \5      /SS9\R6                  " SSS94S\\   4S jj5       r\R3                  SS/\" \5      /SS\\   00S9\R6                  " SSS9\R6                  " SSS94S\\   S\\   4S jj5       rS\ S\S\4S jr!\R3                  S S/\" \5      /SS\\   00SS!9\R6                  " SS"S9\R6                  " SS#S9\" \5      4S\\   S\\   S\ 4S$ jj5       r"S\ S\S\4S% jr#\R3                  S&S/\" \5      /SS\\   00SS!9\R6                  " SS"S9\R6                  " SS#S9\" \5      4S\\   S\\   S\ 4S' jj5       r$\R3                  S(S/\" \5      /SS\\   00SS!9\R6                  " S)S*9\R6                  " SS"S9\R6                  " SS#S94S+\S\\   S\\   4S, jj5       r%\R3                  S-S/\" \5      /SS\\   00SS!9\R6                  " S)S*9\R6                  " SS"S9\R6                  " SS#S94S+\S\\   S\\   4S. jj5       r&\R3                  S/S/\" \5      /SSS\\   00S09\R6                  " SS"S9\R6                  " SS#S9\" \5      4S\\   S\\   S\ 4S1 jj5       r'\R3                  S2S/\" \5      /SS\\   00S9\R6                  " SS"S9\R6                  " SS#S9\R6                  " S3S4S9\R6                  " SS5S9\R6                  " SS6S9\R6                  " SS7S9\R6                  " SS8S94S\\   S\\   S9\\(S:      S;\\   S<\\   S=\\   S>\\   4S? jj5       r)\R3                  S@S/\" \5      /SSS\\   00S09SA 5       r*\R3                  SBS/\" \5      /SS\\   00S9\R6                  " SSS9\R6                  " SSS9\R6                  " SSCS94S\\   S\\   SD\\   4SE jj5       r+S\S\4SF jr,\R[                  SGS/\" \5      /SSHSISJSKSL.00S9SM\.4SN j5       r/\R3                  SOS/\" \5      /SS\\   00S9\R6                  " SSPS9\R6                  " SSQS9\R6                  " SSRS9\R6                  " SSS9\R6                  " SSS9\" \5      4S;\\   S\\   SS\\   S\\   S\\   S\ 4ST jj5       r0\R[                  SUS/\" \5      /SV9SW 5       r1\R[                  SXS/\" \5      /SS9SY 5       r2S\" \5      4S;\\   S\ 4SZ jjr3\R3                  S[S/\" \5      /SS9\R6                  " SS\S9\" \5      4S;\\   S\ 4S] jj5       r4\R3                  S^S/\" \5      /SS9S_ 5       r5 SwS\ Sa\64Sb jjr7\R3                  ScS/\" \5      /SS9\R6                  " SSdS9\" \5      4Sa\6S\ 4Se jj5       r8\R3                  SfS/\" \5      /SS9Sg 5       r9\R3                  ShS/\" \5      /SS9Si 5       r:\R[                  SjS/\" \5      /SS9SxSk\\;   4Sl jj5       r< SwS\ Sa\64Sm jjr=\R3                  SnS/\" \5      /SS9\R6                  " S`SoS9\" \5      4Sa\6S\ 4Sp jj5       r>\R[                  SqS/\" \5      /SS9SM\
4Sr j5       r?\R3                  Ss\St9Su\4Sv j5       r@g)y    N)datetime	timedelta)ListOptional)	APIRouterDependsHTTPExceptionRequeststatus)verbose_proxy_logger)*)ProviderBudgetResponseProviderBudgetResponseObject)user_api_key_auth)get_spend_by_team_and_customer)handle_exception_on_proxyz/spend/keyszBudget & Spend TrackingF)tagsdependenciesinclude_in_schemac                     #    SSK Jn    U c  [        S5      eU R                  SSS9I Sh  vN nU$  N! [         a(  n[	        [
        R                  S[        U5      0S	9eSnAff = f7f)
z
View all keys created, ordered by spend

Example Request:
```
curl -X GET "http://0.0.0.0:8000/spend/keys" -H "Authorization: Bearer sk-1234"
```
r   prisma_clientNDatabase not connected. Connect a database to your proxy - https://docs.litellm.ai/docs/simple_proxy#managing-auth---virtual-keyskeyfind_all
table_name
query_typeerrorstatus_codedetaillitellm.proxy.proxy_serverr   	Exceptionget_datar	   r   HTTP_400_BAD_REQUESTstr)r   key_infoes      q/home/james-whalen/.local/lib/python3.13/site-packages/litellm/proxy/spend_tracking/spend_management_endpoints.pyspend_key_fnr,      s     " 9
  T  '//5Z/XX Y  
33SV$
 	

s0   A)!4 24 A)4 
A&#A!!A&&A)z/spend/userszGet User Table row for user_id)defaultdescriptionuser_idc                   #    SSK Jn   Uc  [        S5      eU b  UR                  SSU S9I Sh  vN nU/$ UR                  SSS	9I Sh  vN nU$  N! N! [         a(  n[	        [
        R                  S
[        U5      0S9eSnAff = f7f)a  
View all users created, ordered by spend

Example Request:
```
curl -X GET "http://0.0.0.0:8000/spend/users" -H "Authorization: Bearer sk-1234"
```

View User Table row for user_id
```
curl -X GET "http://0.0.0.0:8000/spend/users?user_id=1234" -H "Authorization: Bearer sk-1234"
```
r   r   Nr   userfind_unique)r   r   r/   r   r   r   r    r#   )r/   r   	user_infor*   s       r+   spend_user_fnr4   9   s     6 9
  T  +44!mW 5  I ;+44!j 5  I 
  
33SV$
 	

sT   B
%A AA B
A 
AA B
A A 
B#BBB
z/spend/tags   model)r   r   	responsesz*Time from which to start viewing key spendz!Time till which to view key spend
start_dateend_datec                   #    SSK Jn  SSKJn   Uc  [	        S5      e U" XUS9I Sh  vN nU$  N! [         a  n[        U[        5      (       aH  [        [        USS[        U5       S	35      S
[        USS5      [        US[        R                  5      S9e[        U[        5      (       a  Ue[        S[        U5      -   S
[        USS5      [        R                  S9eSnAff = f7f)aA  
LiteLLM Enterprise - View Spend Per Request Tag

Example Request:
```
curl -X GET "http://0.0.0.0:8000/spend/tags" -H "Authorization: Bearer sk-1234"
```

Spend with Start Date and End Date
```
curl -X GET "http://0.0.0.0:8000/spend/tags?start_date=2022-01-01&end_date=2022-02-01" -H "Authorization: Bearer sk-1234"
```
r   )get_spend_by_tagsr   Nr   )r8   r9   r   r"   /spend/tags Error()internal_errorparamNoner!   messagetyper?   code/spend/tags Error)enterprise.utilsr;   r$   r   r%   
isinstancer	   ProxyExceptiongetattrr(   r   HTTP_500_INTERNAL_SERVER_ERROR)r8   r9   r;   r   responser*   s         r+   view_spend_tagsrL   o   s     D 38#
  T 
	 +!M
 
 	

  
a'' 8/A#a&-KL%a&1Qv/T/TU	  >**G'#a&0!!Wf-66	
 	

s1   C)2 02 C)2 
C&B%C!!C&&C)user_api_key_dictc                    #    SSK Jn  Uc  [        SSS0S9eU R                  nUc  [        SSS0S9eSnUR                  R                  XQX$5      I S h  vN nU$  N7f)	Nr   r     r   No db connectedr    No user_id founda0  
    SELECT
        date_trunc('day', "startTime") AS date,
        COUNT(*) AS api_requests,
        SUM(total_tokens) AS total_tokens
    FROM "LiteLLM_SpendLogs"
    WHERE "startTime" BETWEEN $1::date AND $2::date + interval '1 day'
    AND "user" = $3
    GROUP BY date_trunc('day', "startTime")
    r$   r   r	   r/   db	query_rawrM   r8   r9   r   r/   	sql_querydb_responses          r+   !get_global_activity_internal_userrX      s|      9W>O4PQQ''GW>P4QRR	I &((22x K 	   AAAAz/global/activity)r   r   r7   r   z&Time from which to start viewing spendzTime till which to view spendc                 J  #    U b  Uc  [        [        R                  SS0S9e[        R                  " U S5      n[        R                  " US5      nSSKJn   Uc  [        S5      eUR                  [        R                  :X  d  UR                  [        R                  :X  a  [        X#U5      I Sh  vN nO&S	nUR                  R                  XsU5      I Sh  vN nUc  / $ SnSn	/ n
U Hi  n[        R                  " US
   5      nUR!                  S5      US
'   U
R#                  U5        XR%                  SS5      -  nXR%                  SS5      -  n	Mk     ['        U
S S9n
U
UU	S.nU$  N N! [         a(  n[        [        R                  S[)        U5      0S9eSnAff = f7f)a  
Get number of API Requests, total tokens through proxy

{
    "daily_data": [
            const chartdata = [
            {
            date: 'Jan 22',
            api_requests: 10,
            total_tokens: 2000
            },
            {
            date: 'Jan 23',
            api_requests: 10,
            total_tokens: 12
            },
    ],
    "sum_api_requests": 20,
    "sum_total_tokens": 2012
}
Nr   &Please provide start_date and end_dater    %Y-%m-%dr   r   r   a\  
            SELECT
                date_trunc('day', "startTime") AS date,
                COUNT(*) AS api_requests,
                SUM(total_tokens) AS total_tokens
            FROM "LiteLLM_SpendLogs"
            WHERE "startTime" BETWEEN $1::date AND $2::date + interval '1 day'
            GROUP BY date_trunc('day', "startTime")
            date%b %dapi_requeststotal_tokensc                     U S   $ Nr]    xs    r+   <lambda>%get_global_activity.<locals>.<lambda>8      ai    r   
daily_datasum_api_requestssum_total_tokens)r	   r   r'   r   strptimer$   r   r%   	user_roleLitellmUserRolesINTERNAL_USERINTERNAL_USER_VIEW_ONLYrX   rS   rT   fromisoformatstrftimeappendgetsortedr(   )r8   r9   rM   start_date_objend_date_objr   rW   rV   rm   rn   rl   row	_date_objdata_to_returnr*   s                  r+   get_global_activityr~      s    T X-33EF
 	

 &&z:>N$$Xz:L8:
  T 
 ''+;+I+II **.>.V.VV A!<! K
I !. 0 0 : :<! K I
C ..s6{;I#,,W5CKc" :: ::  J,?@
 % 0 0
 U<  
33SV$
 	

s\   AF#AE. 1E*2&E. E,E. !F#"BE. )F#*E. ,E. .
F 8#FF  F#c                    #    SSK Jn  Uc  [        SSS0S9eU R                  nUc  [        SSS0S9eSnUR                  R                  XQX$5      I S h  vN nU$  N7f)	Nr   r   rO   r   rP   r    rQ   aR  
    SELECT
        model_group,
        date_trunc('day', "startTime") AS date,
        COUNT(*) AS api_requests,
        SUM(total_tokens) AS total_tokens
    FROM "LiteLLM_SpendLogs"
    WHERE "startTime" BETWEEN $1::date AND $2::date + interval '1 day'
    AND "user" = $3
    GROUP BY model_group, date_trunc('day', "startTime")
    rR   rU   s          r+   'get_global_activity_model_internal_userr   I  s|      9W>O4PQQ''GW>P4QRR
I &((22x K 	rY   z/global/activity/modelc                 T  #    U b  Uc  [        [        R                  SS0S9e[        R                  " U S5      n[        R                  " US5      nSSKJn   Uc  [        S5      eUR                  [        R                  :X  d  UR                  [        R                  :X  a  [        X#U5      I Sh  vN nO&S	nUR                  R                  XsU5      I Sh  vN nUc  / $ 0 nU H  n	U	S
   n
X;  a  / SSS.X'   [        R                  " U	S   5      nUR!                  S5      U	S'   X   S   R#                  U	5        X   S==   U	R%                  SS5      -  ss'   X   S==   U	R%                  SS5      -  ss'   M     ['        [)        UR+                  5       S SS9SS 5      n/ nUR+                  5        H/  u  p[)        US   S S9nUR#                  UUUS   US   S.5        M1     U$  GN< GN! [         a(  n[        [        R,                  S[/        U5      0S9eSnAff = f7f)a  
Get number of API Requests, total tokens through proxy - Grouped by MODEL

[
    {
        "model": "gpt-4",
        "daily_data": [
                const chartdata = [
                {
                date: 'Jan 22',
                api_requests: 10,
                total_tokens: 2000
                },
                {
                date: 'Jan 23',
                api_requests: 10,
                total_tokens: 12
                },
        ],
        "sum_api_requests": 20,
        "sum_total_tokens": 2012

    },
    {
        "model": "azure/gpt-4-turbo",
        "daily_data": [
                const chartdata = [
                {
                date: 'Jan 22',
                api_requests: 10,
                total_tokens: 2000
                },
                {
                date: 'Jan 23',
                api_requests: 10,
                total_tokens: 12
                },
        ],
        "sum_api_requests": 20,
        "sum_total_tokens": 2012

    },
]
Nr   r[   r    r\   r   r   r   a  
            SELECT
                model_group,
                date_trunc('day', "startTime") AS date,
                COUNT(*) AS api_requests,
                SUM(total_tokens) AS total_tokens
            FROM "LiteLLM_SpendLogs"
            WHERE "startTime" BETWEEN $1::date AND $2::date + interval '1 day'
            GROUP BY model_group, date_trunc('day', "startTime")
            model_grouprk   r]   r^   rl   rm   r_   rn   r`   c                     U S   S   $ )N   rm   rc   rd   s    r+   rf   +get_global_activity_model.<locals>.<lambda>  s    ad#56ri   Tr   reverse
   c                     U S   $ rb   rc   rd   s    r+   rf   r         &	ri   rj   )r6   rl   rm   rn   )r	   r   r'   r   ro   r$   r   r%   rp   rq   rr   rs   r   rS   rT   rt   ru   rv   rw   dictrx   itemsrJ   r(   )r8   r9   rM   ry   rz   r   rW   rV   model_ui_datar{   _modelr|   rK   r6   data_sort_daily_datar*   s                    r+   get_global_activity_modelr   g  sy    B X-33EF
 	

 &&z:>N$$Xz:L8N
  T 
 ''+;+I+II **.>.V.VV G!<! K
	I !. 0 0 : :<! K I  	 C'F*"$()())%
 !..s6{;I#,,W5CK!,/66s;!"45QR9SS5!"45QR9SS5   ##%6 r	
 (..0KE%d<&8>QROO""2(,-?(@(,-?(@	 1 }b  
==SV$
 	

s\   AH(AG3 1G-2&G3 G0G3 !H("D
G3 ,H(-G3 0G3 3
H%=#H  H%%H(z&/global/activity/exceptions/deploymentzFilter by model group)r.   r   c                 b  #    Ub  Uc  [        [        R                  SS0S9e[        R                  " US5      n[        R                  " US5      nSSKJn   Uc  [        S5      eS	nUR                  R                  XcX@5      I Sh  vN nUc  / $ 0 nU Hv  n	U	S
   n
X;  a  / SS.X'   [        R                  " U	S   5      nUR                  S5      U	S'   X   S   R                  U	5        X   S==   U	R                  SS5      -  ss'   Mx     [        [        UR!                  5       S SS9SS 5      n/ nUR!                  5        H+  u  p[        US   S S9nUR                  UUUS   S.5        M-     U$  N! [         a(  n[        [        R"                  S[%        U5      0S9eSnAff = f7f)a  
Get number of 429 errors - Grouped by deployment

[
    {
        "deployment": "https://azure-us-east-1.openai.azure.com/",
        "daily_data": [
                const chartdata = [
                {
                date: 'Jan 22',
                num_rate_limit_exceptions: 10
                },
                {
                date: 'Jan 23',
                num_rate_limit_exceptions: 12
                },
        ],
        "sum_num_rate_limit_exceptions": 20,

    },
    {
        "deployment": "https://azure-us-east-1.openai.azure.com/",
        "daily_data": [
                const chartdata = [
                {
                date: 'Jan 22',
                num_rate_limit_exceptions: 10,
                },
                {
                date: 'Jan 23',
                num_rate_limit_exceptions: 12
                },
        ],
        "sum_num_rate_limit_exceptions": 20,

    },
]
Nr   r[   r    r\   r   r   r   a  
        SELECT
            api_base,
            date_trunc('day', "startTime")::date AS date,
            COUNT(*) AS num_rate_limit_exceptions
        FROM
            "LiteLLM_ErrorLogs"
        WHERE
            "startTime" >= $1::date
            AND "startTime" < ($2::date + INTERVAL '1 day')
            AND model_group = $3
            AND status_code = '429'
        GROUP BY
            api_base,
            date_trunc('day', "startTime")
        ORDER BY
            date;
        api_baserl   sum_num_rate_limit_exceptionsr]   r^   rl   r   num_rate_limit_exceptionsc                     U S   S   $ )Nr   r   rc   rd   s    r+   rf   ?get_global_activity_exceptions_per_deployment.<locals>.<lambda>  s    ad#BCri   Tr   r   c                     U S   $ rb   rc   rd   s    r+   rf   r     r   ri   rj   )r   rl   r   )r	   r   r'   r   ro   r$   r   r%   rS   rT   rt   ru   rv   rw   r   rx   r   rJ   r(   )r   r8   r9   ry   rz   r   rV   rW   r   r{   r   r|   rK   r6   r   r   r*   s                    r+   -get_global_activity_exceptions_per_deploymentr     s    z X-33EF
 	

 &&z:>N$$Xz:L8N
  T 	$ *,,66|
 
 I  	 C_F*"$56)% !..s6{;I#,,W5CK!,/66s;!"ABcgg+QG B   ##%C r	
 (..0KE%d<&8>QROO %"25976 1 a
d  
==SV$
 	

sI   AF//E: E8E: F/C&E: 7F/8E: :
F,#F''F,,F/z/global/activity/exceptionsc                 v  #    Ub  Uc  [        [        R                  SS0S9e[        R                  " US5      n[        R                  " US5      nSSKJn   Uc  [        S5      eS	nUR                  R                  XcX@5      I Sh  vN nUc  / $ Sn/ n	U HU  n
[        R                  " U
S
   5      nUR                  S5      U
S
'   U	R                  U
5        XR                  SS5      -  nMW     [        U	S S9n	U	US.nU$  Nz! [         a(  n[        [        R                  S[        U5      0S9eSnAff = f7f)a^  
Get number of API Requests, total tokens through proxy

{
    "daily_data": [
            const chartdata = [
            {
            date: 'Jan 22',
            num_rate_limit_exceptions: 10,
            },
            {
            date: 'Jan 23',
            num_rate_limit_exceptions: 10,
            },
    ],
    "sum_api_exceptions": 20,
}
Nr   r[   r    r\   r   r   r   a  
        SELECT
            date_trunc('day', "startTime")::date AS date,
            COUNT(*) AS num_rate_limit_exceptions
        FROM
            "LiteLLM_ErrorLogs"
        WHERE
            "startTime" >= $1::date
            AND "startTime" < ($2::date + INTERVAL '1 day')
            AND model_group = $3
            AND status_code = '429'
        GROUP BY
            date_trunc('day', "startTime")
        ORDER BY
            date;
        r]   r^   r   c                     U S   $ rb   rc   rd   s    r+   rf   0get_global_activity_exceptions.<locals>.<lambda>  rh   ri   rj   r   )r	   r   r'   r   ro   r$   r   r%   rS   rT   rt   ru   rv   rw   rx   r(   )r   r8   r9   ry   rz   r   rV   rW   r   rl   r{   r|   r}   r*   s                 r+   get_global_activity_exceptionsr     sn    R X-33EF
 	

 &&z:>N$$Xz:L85
  T 	  *,,66|
 
 I()%
C ..s6{;I#,,W5CKc")WW5PRS-TT)  J,?@
 %-J

 3
6  
33SV$
 	

sI   AD9/D DD D9A0D D9D 
D6#D11D66D9z/global/spend/provider)r   r   r   r7   c                 z  #    SSK Jn  U b  Uc  [        [        R                  SS0S9e[
        R                  " U S5      n[
        R                  " US5      nSSKJnJ	n   Uc  [        S	5      eUR                  [        R                  :X  d  UR                  [        R                  :X  aB  UR                  nUc  [        S
SS0S9eSn	UR                   R#                  XXX5      I Sh  vN n
O&Sn	UR                   R#                  XU5      I Sh  vN n
U
c  / $ / nU" [$        5      nU
 H  nUS   nSnUc  M  UR'                  US9nUc  M#   [(        R*                  " UR,                  R.                  UR,                  R0                  UR,                  R2                  UR,                  S9u  nn  nX==   US   -  ss'   M     UR5                  5        H  u  nnUR7                  UUS.5        M     U$  GN
 N! [         a     M  f = f! [         a(  n[        [        R                  S[9        U5      0S9eSnAff = f7f)z
Get breakdown of spend per provider
[
    {
        "provider": "Azure OpenAI",
        "spend": 20
    },
    {
        "provider": "OpenAI",
        "spend": 10
    },
    {
        "provider": "VertexAI",
        "spend": 30
    }
]
r   )defaultdictNr   r[   r    r\   )
llm_routerr   r     rQ   a  
            SELECT
            model_id,
            SUM(spend) AS spend
            FROM "LiteLLM_SpendLogs"
            WHERE "startTime" BETWEEN $1::date AND $2::date 
            AND length(model_id) > 0
            AND "user" = $3
            GROUP BY model_id
            z
            SELECT
            model_id,
            SUM(spend) AS spend
            FROM "LiteLLM_SpendLogs"
            WHERE "startTime" BETWEEN $1::date AND $2::date AND length(model_id) > 0
            GROUP BY model_id
            model_idUnknown)r   )r6   custom_llm_providerr   litellm_paramsspend)providerr   )collectionsr   r	   r   r'   r   ro   r$   r   r   r%   rp   rq   rr   rs   r/   rS   rT   intget_deploymentlitellmget_llm_providerr   r6   r   r   r   rv   r(   )r8   r9   rM   r   ry   rz   r   r   r/   rV   rW   ui_responseprovider_spend_mappingr{   	_model_id	_provider_deployment_r   r   r*   s                        r+   get_global_spend_providerr   	  sf    J (X-33EF
 	

 &&z:>N$$Xz:LDN
  T 
 ''+;+I+II **.>.V.VV'//G# #W6H,I 	I !. 0 0 : :<! KI !. 0 0 : :<! K I .9#.>CJI!I%(777K*	-4-E-E"-"<"<"B"B0;0J0J0^0^%0%?%?%H%H+6+E+E	.*9a /9S\I9 "  6;;=OHeHuEF  > ]8 %   
33SV$
 	

s   AH; BH &G0'&H G3H H;H 6H A1G5<3H /H;0H 3H 5
H?H HH 
H8#H33H88H;z/global/spend/reportteamz3Group spend by internal team or customer or api_keyz;View spend for a specific api_key. Example api_key='sk-1234zJView spend for a specific internal_user_id. Example internal_user_id='1234z8View spend for a specific team_id. Example team_id='1234zrView spend for a specific customer_id. Example customer_id='1234. Can be used in conjunction with team_id as well.group_by)r   customerapi_keyr   internal_user_idteam_idcustomer_idc                   #    U b  Uc  [        [        R                  SS0S9e[        R                  " U S5      n[        R                  " US5      nSSKJn	Jn
   U
c  [        S5      eU	S	La<  [        R                  " S
5        [        S[        R                  R                  -   5      eUbc  [        R                  " SU5        UR                  S5      (       a	  [!        US9nSnU
R"                  R%                  XX5      I Sh  vN nUc  / $ U$ UbD  [        R                  " SU5        SnU
R"                  R%                  XX5      I Sh  vN nUc  / $ U$ Ub  Ub  ['        XxXVU
5      I Sh  vN $ US:X  a-  SnU
R"                  R%                  XU5      I Sh  vN nUc  / $ U$ US:X  a-  SnU
R"                  R%                  XU5      I Sh  vN nUc  / $ U$ US:X  a-  SnU
R"                  R%                  XU5      I Sh  vN nUc  / $ U$ g GN N N Ny NH N! [         a(  n[        [        R                  S[)        U5      0S9eSnAff = f7f)an  
Get Daily Spend per Team, based on specific startTime and endTime. Per team, view usage by each key, model
[
    {
        "group-by-day": "2024-05-10",
        "teams": [
            {
                "team_name": "team-1"
                "spend": 10,
                "keys": [
                    "key": "1213",
                    "usage": {
                        "model-1": {
                                "cost": 12.50,
                                "input_tokens": 1000,
                                "output_tokens": 5000,
                                "requests": 100
                            },
                            "audio-modelname1": {
                            "cost": 25.50,
                            "seconds": 25,
                            "requests": 50
                    },
                    }
                }
        ]
    ]
}
Nr   r[   r    r\   r   )premium_userr   r   Tz.accessing /spend/report but not a premium userz/spend/report endpoint zGetting /spend for api_key: %ssk-tokenad  
                WITH SpendByModelApiKey AS (
                    SELECT
                        sl.api_key,
                        sl.model,
                        SUM(sl.spend) AS model_cost,
                        SUM(sl.prompt_tokens) AS model_input_tokens,
                        SUM(sl.completion_tokens) AS model_output_tokens
                    FROM
                        "LiteLLM_SpendLogs" sl
                    WHERE
                        sl."startTime" BETWEEN $1::date AND $2::date AND sl.api_key = $3
                    GROUP BY
                        sl.api_key,
                        sl.model
                )
                SELECT
                    api_key,
                    SUM(model_cost) AS total_cost,
                    SUM(model_input_tokens) AS total_input_tokens,
                    SUM(model_output_tokens) AS total_output_tokens,
                    jsonb_agg(jsonb_build_object(
                        'model', model,
                        'total_cost', model_cost,
                        'total_input_tokens', model_input_tokens,
                        'total_output_tokens', model_output_tokens
                    )) AS model_details
                FROM
                    SpendByModelApiKey
                GROUP BY
                    api_key
                ORDER BY
                    total_cost DESC;
            z'Getting /spend for internal_user_id: %saa  
                WITH SpendByModelApiKey AS (
                    SELECT
                        sl.api_key,
                        sl.model,
                        SUM(sl.spend) AS model_cost,
                        SUM(sl.prompt_tokens) AS model_input_tokens,
                        SUM(sl.completion_tokens) AS model_output_tokens
                    FROM
                        "LiteLLM_SpendLogs" sl
                    WHERE
                        sl."startTime" BETWEEN $1::date AND $2::date AND sl.user = $3
                    GROUP BY
                        sl.api_key,
                        sl.model
                )
                SELECT
                    api_key,
                    SUM(model_cost) AS total_cost,
                    SUM(model_input_tokens) AS total_input_tokens,
                    SUM(model_output_tokens) AS total_output_tokens,
                    jsonb_agg(jsonb_build_object(
                        'model', model,
                        'total_cost', model_cost,
                        'total_input_tokens', model_input_tokens,
                        'total_output_tokens', model_output_tokens
                    )) AS model_details
                FROM
                    SpendByModelApiKey
                GROUP BY
                    api_key
                ORDER BY
                    total_cost DESC;
            r   a  

            WITH SpendByModelApiKey AS (
                SELECT
                    date_trunc('day', sl."startTime") AS group_by_day,
                    COALESCE(tt.team_alias, 'Unassigned Team') AS team_name,
                    sl.model,
                    sl.api_key,
                    SUM(sl.spend) AS model_api_spend,
                    SUM(sl.total_tokens) AS model_api_tokens
                FROM 
                    "LiteLLM_SpendLogs" sl
                LEFT JOIN 
                    "LiteLLM_TeamTable" tt 
                ON 
                    sl.team_id = tt.team_id
                WHERE
                    sl."startTime" BETWEEN $1::date AND $2::date
                GROUP BY
                    date_trunc('day', sl."startTime"),
                    tt.team_alias,
                    sl.model,
                    sl.api_key
            )
                SELECT
                    group_by_day,
                    jsonb_agg(jsonb_build_object(
                        'team_name', team_name,
                        'total_spend', total_spend,
                        'metadata', metadata
                    )) AS teams
                FROM (
                    SELECT
                        group_by_day,
                        team_name,
                        SUM(model_api_spend) AS total_spend,
                        jsonb_agg(jsonb_build_object(
                            'model', model,
                            'api_key', api_key,
                            'spend', model_api_spend,
                            'total_tokens', model_api_tokens
                        )) AS metadata
                    FROM 
                        SpendByModelApiKey
                    GROUP BY
                        group_by_day,
                        team_name
                ) AS aggregated
                GROUP BY
                    group_by_day
                ORDER BY
                    group_by_day;
                r   a  

            WITH SpendByModelApiKey AS (
                SELECT
                    date_trunc('day', sl."startTime") AS group_by_day,
                    sl.end_user AS customer,
                    sl.model,
                    sl.api_key,
                    SUM(sl.spend) AS model_api_spend,
                    SUM(sl.total_tokens) AS model_api_tokens
                FROM
                    "LiteLLM_SpendLogs" sl
                WHERE
                    sl."startTime" BETWEEN $1::date AND $2::date
                GROUP BY
                    date_trunc('day', sl."startTime"),
                    customer,
                    sl.model,
                    sl.api_key
            )
            SELECT
                group_by_day,
                jsonb_agg(jsonb_build_object(
                    'customer', customer,
                    'total_spend', total_spend,
                    'metadata', metadata
                )) AS customers
            FROM
                (
                    SELECT
                        group_by_day,
                        customer,
                        SUM(model_api_spend) AS total_spend,
                        jsonb_agg(jsonb_build_object(
                            'model', model,
                            'api_key', api_key,
                            'spend', model_api_spend,
                            'total_tokens', model_api_tokens
                        )) AS metadata
                    FROM
                        SpendByModelApiKey
                    GROUP BY
                        group_by_day,
                        customer
                ) AS aggregated
            GROUP BY
                group_by_day
            ORDER BY
                group_by_day;
                r   aP  
                WITH SpendByModelApiKey AS (
                    SELECT
                        sl.api_key,
                        sl.model,
                        SUM(sl.spend) AS model_cost,
                        SUM(sl.prompt_tokens) AS model_input_tokens,
                        SUM(sl.completion_tokens) AS model_output_tokens
                    FROM
                        "LiteLLM_SpendLogs" sl
                    WHERE
                        sl."startTime" BETWEEN $1::date AND $2::date
                    GROUP BY
                        sl.api_key,
                        sl.model
                )
                SELECT
                    api_key,
                    SUM(model_cost) AS total_cost,
                    SUM(model_input_tokens) AS total_input_tokens,
                    SUM(model_output_tokens) AS total_output_tokens,
                    jsonb_agg(jsonb_build_object(
                        'model', model,
                        'total_cost', model_cost,
                        'total_input_tokens', model_input_tokens,
                        'total_output_tokens', model_output_tokens
                    )) AS model_details
                FROM
                    SpendByModelApiKey
                GROUP BY
                    api_key
                ORDER BY
                    total_cost DESC;
            )r	   r   r'   r   ro   r$   r   r   r%   r   debug
ValueErrorCommonProxyErrorsnot_premium_uservalue
startswith
hash_tokenrS   rT   r   r(   )r8   r9   r   r   r   r   r   ry   rz   r   r   rV   rW   r*   s                 r+   get_global_spend_reportr     s    F X-33EF
 	

 &&z:>N$$Xz:LFU
  T  t# &&'WX),=,N,N,T,TT   &&'GQ!!%(($73!ID !. 0 0 : :<! K "	) &&9;K!ID !. 0 0 : :<! K "	 [%<7gM   v4Il !. 0 0 : :<! K "	#1If !. 0 0 : :<! K "	"!ID !. 0 0 : :<! K "	S #kZzxT  
33SV$
 	

s  AIB)H HH IH I;H 
HH IH IH ,H-H 0I1'H HH !I"H #I$'H HH IH I'H >H?H IH 	IH H H H H H 
I
"#II

Iz/global/spend/all_tag_namesc                  X  #     SSK Jn   U c  [        S5      eSnU R                  R	                  U5      I S h  vN nUc  / $ / nU H#  nUR                  UR                  S5      5        M%     SU0$  N8! [         a  n[        U[        5      (       aH  [        [        USS[        U5       S	35      S
[        USS5      [        US[        R                  5      S9e[        U[        5      (       a  Ue[        S[        U5      -   S
[        USS5      [        R                  S9eS nAff = f7f)Nr   r   r   z
        SELECT DISTINCT
            jsonb_array_elements_text(request_tags) AS individual_request_tag
        FROM "LiteLLM_SpendLogs";
        individual_request_tag	tag_namesr"   z/spend/all_tag_names Error(r=   r>   r?   r@   r!   rA   z/spend/all_tag_names Error)r$   r   r%   rS   rT   rv   rw   rG   r	   rH   rI   r(   r   rJ   )r   rV   rW   
_tag_namesr{   r*   s         r+   global_get_all_tag_namesr     s9    '
<  T 	 *,,66yAAI
Ccgg&>?@  Z(( B  
a'' 8/J3q6(RS-TU%a&1Qv/T/TU	  >**G03q69!!Wf-66	
 	

sE   D*4A3 A1A3 D*.A3 0D*1A3 3
D'=B%D""D''D*z/global/spend/tagsz"comman separated tags to filter onr   c                 >  #    SSK nSSKJn  SSKJn   Uc  [        S5      eUb  U c  [        SSS[        R                  S9eU" U UUUS	9I Sh  vN nU$  N! [
         a  nUR                  5       n[        U5      S
-   U-   n	[        U[        5      (       a?  [        [        USSU	 S35      S[        USS5      [        US[        R                  5      S9e[        U[        5      (       a  Ue[        SU	-   S[        USS5      [        R                  S9eSnAff = f7f)aU  
LiteLLM Enterprise - View Spend Per Request Tag. Used by LiteLLM UI

Example Request:
```
curl -X GET "http://0.0.0.0:4000/spend/tags" -H "Authorization: Bearer sk-1234"
```

Spend with Start Date and End Date
```
curl -X GET "http://0.0.0.0:4000/spend/tags?start_date=2022-01-01&end_date=2022-02-01" -H "Authorization: Bearer sk-1234"
```
r   N)ui_get_spend_by_tagsr   r   r[   bad_requestrA   )r8   r9   tags_strr   
r"   r<   r=   r>   r?   r@   r!   rE   )	tracebackrF   r   r$   r   r%   rH   r   r'   
format_excr(   rG   r	   rI   rJ   )
r8   r9   r   r   r   r   rK   r*   error_trace	error_strs
             r+   global_view_spend_tagsr   &  sG    J 58&
  T  z1 @"00	  .!'	
 
 
  
**,FTMK/	a'' 8/A)A-NO%a&1Qv/T/TU	  >**G')3!!Wf-66	
 	

s;   D:A AA DA 
D!B4DDDc                 |  #    SSK Jn  Uc  [        R                  " S5        g  SnUR                  R                  X0U5      I S h  vN nSnUR                  R                  X0U5      I S h  vN nXE4$  N- N	! [         a8  n[        R                  " SR                  [        U5      5      5         S nAg S nAff = f7f)Nr   r   zZDatabase not connected. Connect a database to your proxy for weekly, monthly spend reportsa  
        SELECT
            t.team_alias,
            SUM(s.spend) AS total_spend
        FROM
            "LiteLLM_SpendLogs" s
        LEFT JOIN
            "LiteLLM_TeamTable" t ON s.team_id = t.team_id
        WHERE
            s."startTime"::DATE >= $1::date AND s."startTime"::DATE <= $2::date
        GROUP BY
            t.team_alias
        ORDER BY
            total_spend DESC;
        a@  
        SELECT 
        jsonb_array_elements_text(request_tags) AS individual_request_tag,
        SUM(spend) AS total_spend
        FROM "LiteLLM_SpendLogs"
        WHERE "startTime"::DATE >= $1::date AND "startTime"::DATE <= $2::date
        GROUP BY individual_request_tag
        ORDER BY total_spend DESC;
        z(Exception in _get_daily_spend_reports {})	r$   r   r   r   rS   rT   r%   formatr(   )r8   r9   r   rV   rK   spend_per_tagr*   s          r+    _get_spend_report_for_time_ranger   y  s      9""h	
 %
	 '))33I8TT	 ,..888
 
 &&# U

  
""6==c!fE	
 	

sR   !B<!A7 A3%A7 +A5,A7 2B<3A7 5A7 7
B9.B4/B<4B99B<z/spend/calculatecostzThe calculated cost        float)r.   examplerC   requestc                   #     SSK Jn  SSKJn  SSKJn  SnU R                  GbE  U R                  c
  [        SSS9eSnSnUb  UR                  b`  U R                  UR                  ;   aF  UR                  U R                     nUR                   H  nUR                  S	5      U:X  d  M  UnM     O6UR                   H&  nUR                  S	5      U R                  :X  d  M$  UnM(      Ubd  UR                  S
5      n	U	R                  S5      n
U	R                  S5      nU	R                  S5      nUc  Ub  U" UUS9nU" U
U R                  US9nOZU" U R                  U R                  S9nO>U R                  b'  [         R                  " S0 U R                  D6nU" US9nO
[        SSS9eSU0$ ! [         a  n[        U[        5      (       aO  [!        [#        US[%        U5      5      [#        USS5      [#        USS5      [#        US[&        R(                  5      S9e[%        U5       n[!        [#        USU5      [#        USS5      [#        USS5      [#        USS5      S9eSnAff = f7f)a  
Accepts all the params of completion_cost.

Calculate spend **before** making call:

Note: If you see a spend of $0.0 you need to set custom_pricing for your model: https://docs.litellm.ai/docs/proxy/custom_pricing

```
curl --location 'http://localhost:4000/spend/calculate'
--header 'Authorization: Bearer sk-1234'
--header 'Content-Type: application/json'
--data '{
    "model": "anthropic.claude-v2",
    "messages": [{"role": "user", "content": "Hey, how'''s it going?"}]
}'
```

Calculate spend **after** making call:

```
curl --location 'http://localhost:4000/spend/calculate'
--header 'Authorization: Bearer sk-1234'
--header 'Content-Type: application/json'
--data '{
    "completion_response": {
        "id": "chatcmpl-123",
        "object": "chat.completion",
        "created": 1677652288,
        "model": "gpt-3.5-turbo-0125",
        "system_fingerprint": "fp_44709d6fcb",
        "choices": [{
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "Hello there, how may I assist you today?"
            },
            "logprobs": null,
            "finish_reason": "stop"
        }]
        "usage": {
            "prompt_tokens": 9,
            "completion_tokens": 12,
            "total_tokens": 21
        }
    }
}'
```
r   )completion_cost)CostPerTokenr   Nr   z>Bad Request - messages must be provided if 'model' is providedr    
model_namer   r6   input_cost_per_tokenoutput_cost_per_token)r   r   )r6   messagescustom_cost_per_token)r6   r   )completion_responsezFBad Request - Either 'model' or 'completion_response' must be providedr   r"   rC   r@   r?   r!   rA   rB   rO   rc   )r   r   litellm.cost_calculatorr   r$   r   r6   r   r	   model_group_alias
model_listrw   r   ModelResponser%   rG   rH   rI   r(   r   r'   )r   r   r   r   _cost_model_in_llm_routercost_per_token_model_group_namer6   _litellm_params_litellm_model_namer   r   _completion_responser*   	error_msgs                   r+   calculate_spendr     s    ~V
+89==$'# #[  $( 59N%00<)E)EE )3(D(DW]](S%!+!6!6 99\26GG380 "7 ",!6!6 99\2gmmC380 "7 $/"6":":;K"L&5&9&9'&B#'6':':;Q'R$(7(;(;<S(T%(4,8%1-A.C&N
 (-$--*8 (gmmgFVFVW((4#*#8#8#W7;V;V#W #8LME_   
a'' 8SV4Q/a&1Qv/J/JK	  1vh	Ay)4FF+!Wf-M3/	
 	

s7   I'B"F- *3F- !CF- ,I'-
I$7B(II$$I'z/spend/logszGet spend logs based on api keyzGet spend logs based on user_idzjrequest_id to get spend logs for specific request_id. If none passed then pass spend logs for all requests
request_idc                 
  #    SSK Jn  UR                  [        R                  :X  d  UR                  [        R
                  :X  a  UR                  n [        R                  " S5        Uc  [        S5      e/ nUGb  [        U[        5      (       Ga  UGb  [        U[        5      (       Ga  [        R                  " US5      n[        R                  " US5      n	SUU	S.0n
U b  [        U [        5      (       a  X
S	'   O9Ub  [        U[        5      (       a  X*S
'   OUb  [        U[        5      (       a  XS'   UR                  R                  R!                  / SQU
SS0S9I Sh  vN n[        U["        5      (       Ga  [%        U5      S:  Ga  [        US   [&        5      (       Ga  0 nU GHN  n[        R                  " [        US   5      S5      nUR)                  5       nX;  a  0 0 S.X'   US	   n US   nUS   nX   R+                  SS5      UR+                  S0 5      R+                  SS5      -   X   S'   X   R+                  U S5      UR+                  S0 5      R+                  SS5      -   X   U '   X   S   R+                  US5      UR+                  S0 5      R+                  SS5      -   X   S   U'   X   S   R+                  US5      UR+                  S0 5      R+                  SS5      -   X   S   U'   GMQ     / nSn[-        UR/                  5       5       H  u  nnUR1                  0 UESU0E5        UnM!     U	R)                  5       nUbB  UU:  a<  U[3        SS9-   nUU::  a*  UR1                  US0 0 S.5        U[3        SS9-  nUU::  a  M*  U$ U$ U bs  [        U [        5      (       a^  U R5                  S5      (       a  UR7                  U S9nOU nUR9                  SSS	US.S9I Sh  vN n[        U["        5      (       a  U$ U/$ Ub  UR9                  SSS
US.S9I Sh  vN nU/$ Ub6  UR9                  SSSUS.S9I Sh  vN n[        U["        5      (       a  U$ U/$ UR9                  SSS9I Sh  vN nU$  GN N N_ N? N! [         a  n[        U[:        5      (       aH  [=        [?        US S![        U5       S"35      S#[?        US$S%5      [?        US&[@        RB                  5      S'9e[        U[<        5      (       a  Ue[=        S([        U5      -   S#[?        US$S%5      [@        RB                  S'9eSnAff = f7f))a  
View all spend logs, if request_id is provided, only logs for that request_id will be returned

Example Request for all logs
```
curl -X GET "http://0.0.0.0:8000/spend/logs" -H "Authorization: Bearer sk-1234"
```

Example Request for specific request_id
```
curl -X GET "http://0.0.0.0:8000/spend/logs?request_id=chatcmpl-6dcb2540-d3d7-4e49-bb27-291f863f112e" -H "Authorization: Bearer sk-1234"
```

Example Request for specific api_key
```
curl -X GET "http://0.0.0.0:8000/spend/logs?api_key=sk-Fn8Ej39NkBQmUagFEoUWPQ" -H "Authorization: Bearer sk-1234"
```

Example Request for specific user_id
```
curl -X GET "http://0.0.0.0:8000/spend/logs?user_id=ishaan@berri.ai" -H "Authorization: Bearer sk-1234"
```
r   r   zinside view_spend_logsNr   r\   	startTime)gtelter   r   r1   )r   r1   r6   r   r   T)bywheresumz%Y-%m-%dT%H:%M:%S.%fZ)usersmodelsr6   _sumr   r  r   days)r   r   r   r  r   r   r   )r   r   )r   r   key_valr2   r   r"   z/spend/logs Error(r=   r>   r?   r@   r!   rA   z/spend/logs Error)"r$   r   rp   rq   rr   rs   r/   r   r   r%   rG   r(   r   ro   rS   litellm_spendlogsr   listlenr   r]   rw   rx   r   rv   r   r   r   r&   r	   rH   rI   r   rJ   )r   r/   r   r8   r9   rM   r   
spend_logsry   rz   filter_queryrK   resultrecord	dt_objectr]   r6   return_list
final_datekvend_date_datecurrent_datehashed_token	spend_logr*   s                             r+   view_spend_logsr  E  s    t 9 	##'7'E'EE&&*:*R*RR#++T
""#;<  T  
":s++$8S)) &..z:FN#,,XzBL )'L "z'3'?'?*1Y''Jz3,G,G-7\*$GS)A)A'.V$ +--??HH<"T I  H 8T**MA%x{D11!&F ( 1 1F;/02I!I %>>+D)13r'B$Y/G$VnG"7OE,2L,<,<Wa,H6::Lc'1o-&FL) -3L,<,<Wa,H6::Lc'1o-&FL) 6<\'5J5N5N6

62.227A>6?FL)'2 5;L4J4N4Nq5

62.227A>5?FL*51' ', !!
"6<<>2DAq&&'<!'<[!'<=!"J 3 !- 1 1 3)j=.H#-	q0A#AL&-7#**-9)*)+*,	 %	q(99 '-7 #"O Z%=%=!!%((,77g7F&+44"% )LA 5  I
 )T**  !{"#+44"( ,zB 5  I
 ; +44"% &9 5  I
 )T**  !{",55"z  6   J CD  
a'' 8/A#a&-KL%a&1Qv/T/TU	  >**G'#a&0!!Wf-66	
 	

s   AUDR #R$H-R R UR UAR .R/R 	U
R UR 'R(R .U/R 	R	
R $U%R 'U(R ;R<R UR R R 	R R 
UB%T<<UUz/global/spend/reset)r   r   c                    #    SSK Jn   U c  [        SSS[        R                  S9eU R
                  R                  R                  SS	00 S
9I Sh  vN   U R
                  R                  R                  SS	00 S
9I Sh  vN   SSS.$  N7 N7f)a+  
ADMIN ONLY / MASTER KEY Only Endpoint

Globally reset spend for All API Keys and Teams, maintain LiteLLM_SpendLogs

1. LiteLLM_SpendLogs will maintain the logs on spend, no data gets deleted from there
2. LiteLLM_VerificationTokens spend will be set = 0
3. LiteLLM_TeamTable spend will be set = 0

r   r   N Prisma Client is not initializedr>   r@   rA   r   r   )r   r   z3Spend for all API Keys and Teams reset successfullysuccessrB   r   )	r$   r   rH   r   HTTP_401_UNAUTHORIZEDrS   litellm_verificationtokenupdate_manylitellm_teamtabler   s    r+   global_spend_resetr    s       96!--	
 	
 


4
4
@
@s^2 A    


,
,
8
8wnTV
8
WWW I  Xs$   ABB-B=B	>
B	Bz/global/spend/refreshc                    ^	#    SSK Jm	  T	c  [        SSS[        R                  S9eS[
        4U	4S	 jjn U " 5       I Sh  vN nU(       a  S
n SSKJn  SSK Jn  SSK	J
n  [        R                  " S5      nUc  [        UR                  R                  5      eU" UUSS0S9nUR                   R#                  5       I Sh  vN   UR                   R%                  U5      I Sh  vN   [&        R(                  " S5        SSS.$ g N NE N$! [         a=  n[&        R*                  " SR-                  [/        U5      5      5        SSS.s SnA$ SnAff = f7f)zW
ADMIN ONLY / MASTER KEY Only Endpoint

Globally refresh spend MonthlyGlobalSpend view
r   r   Nr  r>   r@   rA   returnc                     >#    Sn  TR                   R                  U 5      I Sh  vN nUS   S   S:X  d   eg N! [         a     gf = f7f)z5
Return True if materialized view exists

Else False
zy
        SELECT relname, relkind
        FROM pg_class
        WHERE relname = 'MonthlyGlobalSpend';            
        Nr   relkindmTF)rS   rT   r%   )rV   respr   s     r+   !is_materialized_global_spend_view?global_spend_refresh.<locals>.is_materialized_global_spend_viewZ  s]     	
	&))33I>>D79%,,, ?  		s1   A; 9; A; 
AAAAzE
        REFRESH MATERIALIZED VIEW "MonthlyGlobalSpend";    
        )r   )proxy_logging_obj)PrismaClientDATABASE_URLtimeoutip  )database_urlr(  http_clientz!MonthlyGlobalSpend view refreshedr  r  z(Failed to refresh materialized view - {}z#Failed to refresh materialized viewfailure)r$   r   rH   r   r  boollitellm.proxy._typesr   r(  litellm.proxy.utilsr)  osgetenvr%   db_not_connected_errorr   rS   connectrT   r   info	exceptionr   r(   )
r&  view_existsrV   r   r(  r)  db_url
new_clientr*   r   s
            @r+   global_spend_refreshr;  C  sK     96!--	
 	
T & :;;K		>D8YY~.F~ 1 H H N NOO%#"3tJ --'')))--)))444 %%&IJ># /  <, *4  	 **:AA#a&I A# 		se   <ED EA1D	 ?D "D	 "D#D	 ED	 D	 	
E2EEEEEc                   #    SSK Jn  Uc  [        SSS[        R                  S9e UR
                  nUc  [        S5      eU b(  SnUR                  R                  X@U5      I S h  vN nU$ S	nUR                  R                  XC5      I S h  vN nU$  N- N! [         a)  n[        R                  " S
[        U5       35        UeS nAff = f7f)Nr   r   r  r>   r@   rA   z)/global/spend/logs Error: User ID is Nonez
                SELECT * FROM "MonthlyGlobalSpendPerUserPerKey"
                WHERE "api_key" = $1 AND "user" = $2
                ORDER BY "date";
                zSSELECT * FROM "MonthlyGlobalSpendPerUserPerKey"  WHERE "user" = $1 ORDER BY "date";/global/spend/logs Error: )r$   r   rH   r   rJ   r/   r   rS   rT   r%   r   r   r(   )r   rM   r   r/   rV   rK   r*   s          r+   global_spend_for_internal_userr>    s      96!66	
 	
#++?HIII +--77	GTTHOm	&))33IGG U H  ""%?Ax#HIsX   $C>B %B&B +C, B BB CB B 
C
!$CC

Cz/global/spend/logszMAPI Key to get global spend (spend per day for last 30d). Admin-only endpointc                   #    SSK nSSKJnJn  SSKJn   Uc  [        SSS[        R                  S9eUR                  [        R                  :X  d  UR                  [        R                  :X  a  [        XS	9I Sh  vN nU$ U" 5       nU(       a  U" U S
9I Sh  vN nU$ U c%  SnUR                  R                  US9I Sh  vN nU$ SnUR                  R                  X5      I Sh  vN nU$  Ns NW N1 N! [          a  n	UR#                  5       n
[%        U	5      S-   U
-   n[&        R(                  " SU 35        [+        U	[,        5      (       a?  [        [/        U	SSU S35      S[/        U	SS5      [/        U	S[        R                  5      S9e[+        U	[        5      (       a  U	e[        SU-   S[/        U	SS5      [        R                  S9eSn	A	ff = f7f)z
[BETA] This is a beta endpoint. It will change.

Use this to get global spend (spend per day for last 30d). Admin-only endpoint

More efficient implementation of /spend/logs, by creating a view over the spend logs table.
r   N)get_daily_spend_from_prometheusis_prometheus_connectedr   r  r>   r@   rA   )r   rM   )r   z3SELECT * FROM "MonthlyGlobalSpend" ORDER BY "date";queryz
                    SELECT * FROM "MonthlyGlobalSpendPerKey"
                    WHERE "api_key" = $1
                    ORDER BY "date";
                    r   r=  r"   z/global/spend/logs Error(r=   r?   r!   z/global/spend/logs Error)r   6litellm.integrations.prometheus_helpers.prometheus_apir@  rA  r$   r   rH   r   rJ   rp   rq   rr   rs   r>  rS   rT   r%   r   r(   r   r   rG   r	   rI   )r   rM   r   r@  rA  r   rK   prometheus_api_enabledrV   r*   r   r   s               r+   global_spend_logsrF    s    (  9<
  :%::	  ''+;+I+II **.>.V.VV; H O!8!:!<WMMHOU	!.!1!1!;!;)!;!LL	 "/!1!1!;!;I!OO7 N M P  
**,FTMK/	""%?	{#KLa'' 8/HST-UV%a&1Qv/T/TU	  >**G.:!!Wf-66	
 	

s   GA%C7 ;C/<C7 GC7 C1C7 G !C7 C3C7 G C7 (C5)C7 .G/C7 1C7 3C7 5C7 7
GCGGGz/global/spendc                    #    SSK n SSKJn   SnUc  [        SSS0S9eS	nUR                  R                  US
9I Sh  vN nUb9  [        U[        5      (       a$  [        U5      S:  a  US   R                  SS5      nU[        R                  S.$  NS! [         a  nU R                  5       n[        U5      S-   U-   n[        U[        5      (       a?  [        [!        USSU S35      S[!        USS5      [!        US["        R$                  5      S9e[        U[        5      (       a  Ue[        SU-   S[!        USS5      ["        R$                  S9eSnAff = f7f)zY
[BETA] This is a beta endpoint. It will change.

View total spend across all proxy keys
r   Nr   r   rO   r   rP   r    z;SELECT SUM(spend) as total_spend FROM "MonthlyGlobalSpend";rB  total_spend)r   
max_budgetr   r"   z/global/spend Error(r=   r>   r?   r@   r!   rA   z/global/spend Error)r   r$   r   r	   rS   rT   rG   r  r  rw   r   rI  r%   r   r(   rH   rI   r   rJ   )r   r   rH  rV   rK   r*   r   r   s           r+   global_spendrJ    s]     8
 CBS8TUUU	&))33)3DD(D))c(ma.?&qkoomSA$G4F4FGG E  
**,FTMK/	a'' 8/CI;a-PQ%a&1Qv/T/TU	  >**G)I5!!Wf-66	
 	

s:   E/B BAB EB 
EB4EEEr   limitc                    #    SSK Jn  Uc  [        SSS0S9eU R                  nUc  [        SSS0S9eSnUR                  R                  XCU5      I S h  vN nU$  N7f)	Nr   r   rO   r   rP   r    rQ   a  
            WITH top_api_keys AS (
            SELECT 
                api_key,
                SUM(spend) as total_spend
            FROM 
                "LiteLLM_SpendLogs"
            WHERE 
                "user" = $1
            GROUP BY 
                api_key
            ORDER BY 
                total_spend DESC
            LIMIT $2  -- Adjust this number to get more or fewer top keys
        )
        SELECT 
            t.api_key,
            t.total_spend,
            v.key_alias,
            v.key_name
        FROM 
            top_api_keys t
        LEFT JOIN 
            "LiteLLM_VerificationToken" v ON t.api_key = v.token
        ORDER BY 
            t.total_spend DESC;
    
    rR   rM   rK  r   r/   rV   rK   s         r+   global_spend_key_internal_userrN  H  su      9W>O4PQQ''GW>P4QRRI: #%%//	EJJHO KrY   z/global/spend/keysz0Number of keys to get. Will return Top 'n' keys.c                 ,  #    SSK Jn  UR                  [        R                  :X  d  UR                  [        R
                  :X  a  [        US9I Sh  vN nU$ Uc  [        SSS0S9eS	U  S
3nUR                  R                  US9I Sh  vN nU$  N> N7f)}
[BETA] This is a beta endpoint. It will change.

Use this to get the top 'n' keys with the highest spend, ordered by spend.
r   r   )rM   NrO   r   rP   r    z)SELECT * FROM "Last30dKeysBySpend" LIMIT ;rB  )
r$   r   rp   rq   rr   rs   rN  r	   rS   rT   rK  rM   r   rK   rV   s        r+   global_spend_keysrS  v  s     $ 9 	##'7'E'EE&&*:*R*RR7/
 
 W>O4PQQ=eWAHI"%%//i/@@HO
 A$   ABB7B	B
BBz/global/spend/teamsc                    #    SSK Jn   U c  [        SSS0S9eSnU R                  R	                  US	9I Sh  vN n0 n[        5       n0 nU Ht  nUS
   nUc  M  US   nUc  SnUR                  U5        Xs;   a  US   n	[        U	S5      n	X7   n
XU'   OUS   n	[        U	S5      n	X0X7'   X;   a  XX==   U	-  ss'   Mp  XU'   Mv     / n[        [        UR                  5       S SS95      nU H/  n[        U5      S:  a    OUc  SnUR                  XU   S.5        M1     / nU H  nX>   nUR                  SU0UE5        M     U[        U5      US.$  GN7f)zo
[BETA] This is a beta endpoint. It will change.

Use this to get daily spend, grouped by `team_id` and `date`
r   r   NrO   r   rP   r    a  
        SELECT
            t.team_alias as team_alias,
            DATE(s."startTime") AS spend_date,
            SUM(s.spend) AS total_spend
        FROM
            "LiteLLM_SpendLogs" s
        LEFT JOIN
            "LiteLLM_TeamTable" t ON s.team_id = t.team_id
        WHERE
            s."startTime" >= CURRENT_DATE - INTERVAL '30 days'
        GROUP BY
            t.team_alias,
            DATE(s."startTime")
        ORDER BY
            spend_date;
        rB  
spend_date
team_alias
UnassignedrH     c                     U S   $ )Nr   rc   )items    r+   rf   'global_spend_per_team.<locals>.<lambda>  s    d1gri   Tr   r   )r   rH  r]   )daily_spendteamstotal_spend_per_team)r$   r   r	   rS   rT   setaddroundr   rx   r   r  rv   r  )r   rV   rK   spend_by_dateteam_aliasesr_  r{   row_daterW  r   current_date_entriestotal_spend_per_team_uir   response_datar   r   s                   r+   global_spend_per_teamri    s     9W>O4PQQI" #%%//i/@@H M5L|$&
%J$$ &E%OE#0#: /4,&E%OE'1&9M#- ,5,/4,/ 2 !#))+1EtT (&'2-?"G&&W0MN	
 ( M"fc3U34 
 %l# 7 k As   4EEDEz/global/all_end_usersc                     #    SSK Jn   U c  [        SSS0S9eSnU R                  R	                  US	9I Sh  vN nUc  / $ / nU H  nUR                  US
   5        M     SU0$  N,7f)zb
[BETA] This is a beta endpoint. It will change.

Use this to just get all the unique `end_users`
r   r   NrO   r   rP   r    z;
    SELECT DISTINCT end_user FROM "LiteLLM_SpendLogs"
    rB  end_user	end_users)r$   r   r	   rS   rT   rv   )r   rV   rW   
_end_usersr{   s        r+   global_view_all_end_usersrn    s      9W>O4PQQI &((222CCK	J#j/*  $$ Ds   4A%A#-A%z/global/spend/end_usersr   c                 p  #    SSK Jn  Uc  [        SSS0S9e SnSnSnU b$  U R                  nU R                  nU R
                  nU=(       d    [        R                  " 5       [        SS	9-
  nU=(       d    [        R                  " 5       nS
nUR                  R                  XRX45      I Sh  vN nU$  N7f)rP  r   r   NrO   r   rP   r       r  a8  
SELECT end_user, COUNT(*) AS total_count, SUM(spend) AS total_spend
FROM "LiteLLM_SpendLogs"
WHERE "startTime" >= $1::timestamp
  AND "startTime" < $2::timestamp
  AND (
    CASE
      WHEN $3::TEXT IS NULL THEN TRUE
      ELSE api_key = $3
    END
  )
GROUP BY end_user
ORDER BY total_spend DESC
LIMIT 100
    )r$   r   r	   r   endTimer   r   nowr   rS   rT   )r   r   r   rq  selected_api_keyrV   rK   s          r+   global_spend_end_usersrt  	  s      9W>O4PQQ IGNN	,,<<@X\\^iR.@@I'GI #%%//g H O	s   B+B6-B4.B6c                    #    SSK Jn  Uc  [        SSS0S9eU R                  nUc  [        SSS0S9eSnUR                  R                  XCU5      I S h  vN nU$  N7f)	Nr   r   rO   r   rP   r    rQ   a7  
        SELECT 
            model,
            SUM(spend) as total_spend,
            SUM(total_tokens) as total_tokens
        FROM 
            "LiteLLM_SpendLogs"
        WHERE 
            "user" = $1
        GROUP BY 
            model
        ORDER BY 
            total_spend DESC
        LIMIT $2;
    rR   rM  s         r+   !global_spend_models_internal_userrv  N	  su      9W>O4PQQ''GW>P4QRRI  #%%//	EJJHO KrY   z/global/spend/modelsz4Number of models to get. Will return Top 'n' models.c                 ,  #    SSK Jn  UR                  [        R                  :X  d  UR                  [        R
                  :X  a  [        XS9I Sh  vN nU$ Uc  [        SSS0S9eS	U  S
3nUR                  R                  US9I Sh  vN nU$  N> N7f)z
[BETA] This is a beta endpoint. It will change.

Use this to get the top 'n' models with the highest spend, ordered by spend.
r   r   )rM   rK  NrO   r   rP   r    z+SELECT * FROM "Last30dModelsBySpend" LIMIT rQ  rB  )
r$   r   rp   rq   rr   rs   rv  r	   rS   rT   rR  s        r+   global_spend_modelsrx  o	  s     $ 9 	##'7'E'EE&&*:*R*RR:/
 
 W>O4PQQ?waJI"%%//i/@@HO
 ArT  z/global/predict/spend/logsc                 |   #    SSK Jn  U R                  5       I S h  vN nUR                  S5      nU" U5      $  N7f)Nr   )_forecast_daily_costr   )rF   rz  jsonrw   )r   rz  r   s      r+   global_predict_spend_logsr|  	  s6      6D88FD%%  s   <:<z/provider/budgets)response_modelr!  c                  f  #    SSK Jn    U c  [        SSS0S9eU R                  nUc  [	        S5      e0 nUR                  5        H  u  p4U R                  c  [	        S	5      eU R                  R                  U5      I Sh  vN =(       d    S
nU R                  R                  U5      I Sh  vN n[        UR                  UR                  UUS9nXrU'   M     [        US9$  Na N7! [         a>  n[        R                  " SR!                  [#        U5      5      5        [%        U5      eSnAff = f7f)a.  
Provider Budget Routing - Get Budget, Spend Details https://docs.litellm.ai/docs/proxy/provider_budget_routing

Use this endpoint to check current budget, spend and budget reset time for a provider

Example Request

```bash
curl -X GET http://localhost:4000/provider/budgets     -H "Content-Type: application/json"     -H "Authorization: Bearer sk-1234"
```

Example Response

```json
{
    "providers": {
        "openai": {
            "budget_limit": 1e-12,
            "time_period": "1d",
            "spend": 0.0,
            "budget_reset_at": null
        },
        "azure": {
            "budget_limit": 100.0,
            "time_period": "1d",
            "spend": 0.0,
            "budget_reset_at": null
        },
        "anthropic": {
            "budget_limit": 100.0,
            "time_period": "10d",
            "spend": 0.0,
            "budget_reset_at": null
        },
        "vertex_ai": {
            "budget_limit": 100.0,
            "time_period": "12d",
            "spend": 0.0,
            "budget_reset_at": null
        }
    }
}
```

r   r   NrO   r   zNo llm_router foundr    zNo provider budget config found. Please set a provider budget config in the router settings. https://docs.litellm.ai/docs/proxy/provider_budget_routingzNo router budget logger foundr   )budget_limittime_periodr   budget_reset_at)	providersz)/provider/budgets: Exception occured - {})r$   r   r	   provider_budget_configr   r   router_budget_logger_get_current_provider_spend%_get_current_provider_budget_reset_atr   r  r  r   r%   r   r7  r   r(   r   )	r   r  provider_budget_response_dictr   _budget_info_provider_spend_provider_budget_ttlprovider_budget_response_objectr*   s	            r+   provider_budgetsr  	  sa    b 6%+2G(H  ",!B!B!) j  RT%'='C'C'E#I..6 !@AA 55QQ   	  *4)H)H)n)n* $  /K)66(44% 4	/+ 8W)4% (F& &0MNN
$  +&&7>>s1vF	
 (**	+sM   D1A6C&  C"+C& ,C$-4C& !D1"C& $C& &
D.09D))D..D1)r   )N)Ar2  r   r   typingr   r   fastapir   r   r	   r
   r   r   litellm._loggingr   r0  r   r   $litellm.proxy.auth.user_api_key_authr   1litellm.proxy.spend_tracking.spend_tracking_utilsr   r1  r   routerrw   r,   Queryr(   r4   LiteLLM_SpendLogsrL   UserAPIKeyAuthrX   r~   r   r   r   r   r   Literalr   r   r   r   postSpendCalculateRequestr   r  r  r;  r>  rF  rJ  r   rN  rS  ri  rn  GlobalEndUsersSpendrt  rv  rx  r|  r  rc   ri   r+   <module>r     ss   	 ( !  F F  1 " U B :	 
#	$+,-	  

: 
#	$+,-	   %]]4-
c]-
-
` 
#	$+,-gt-./	   !(@! &mm7@
@

 sm@
@
F%3;GO: 
#	$+,-gt-./    !(<! &mm3 )00A(Bf
f

 smf
 &f
f
R%3;GO< 
#	$+,-gt-./    !(<! &mm3 )00A(BQ
Q

 smQ
 &Q
Q
h ,
#	$+,-gt-./    }}+ !(<! &mm3M
M
 	M
 smM
M
` !
#	$+,-gt-./    }}+ !(<! &mm3`
`
 	`
 sm`
`
F 
#	$+,-gt-./   !(<! &mm3 )00A(Bw
w

 smw
 &w
w
t 
#	$+,-gt-./	   !(<! &mm3 BIIB %]]Q '.mm`' %]]N ") I"3[
[

 sm[
 w<=>[
 c][
" sm#[
* c]+[
2 #3[
[
|
 !
#	$+,-gt-./  (
(
V 
#	$+,-gt-./	   !(@! &mm7 "--8H
H

 smH
 3-H
H
V1
1
1
h 
#	$+,-4
	  G
#8 G
G
T 
#	$+,-gt-./	   %]]5 %]]5 !( A! !(@! &mm7 )00A(B+N
c]N

 c]N
 N
 N
" sm#N
* &+N
N
b 
#	$+,-  

@ 
#	$+,-	  IIZ "(/0A(B$c]$%$N 
#	$+,-	   %]]c )00A(BR
c]R

 &R
R
j 
#	$+,-	  (
(
X 57+%+.1+\ 
#	$+,-	   F )00A(B
 &@ 
#	$+,-	  TTn 
#	$+,-	  %%4 
#	$+,-	  ,x0C'D ,,` 57%.1B 
#	$+,-	   J )00A(B
 &B  
#	$+,-	  &W && 0FGW+ 6 W+ HW+ri   