
    h"                     H    d Z ddlmZmZ ddlmZmZmZ ddlZ G d d      Z	y)z4Database connection and data extraction for LiteLLM.    )datetime	timedelta)AnyDictOptionalNc                       e Zd ZdZd Zddedee   dej                  fdZ
deeef   fdZdedefd	Zdeeef   fd
Zy)LiteLLMDatabasez;Handle LiteLLM PostgreSQL database connections and queries.c                 .    ddl m} 	 |t        d      |S )Nr   )prisma_clientzDatabase not connected. Connect a database to your proxy - https://docs.litellm.ai/docs/simple_proxy#managing-auth---virtual-keys)litellm.proxy.proxy_serverr   	Exception)selfr   s     c/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/integrations/cloudzero/database.py_ensure_prisma_clientz%LiteLLMDatabase._ensure_prisma_client   s)    <0  T      target_hourlimitreturnc           	        K   | j                         }|j                  ddd      }|t        d      z   }|j                         }|j                         }d}|r|d| z  }	 |j                  j                  |||       d{   }	|	rt        j                  |	      S t        j                         S 7 /# t        $ r}
t        d| d	t        |
             d}
~
ww xY ww)
zSRetrieve spend logs for a specific hour from LiteLLM_SpendLogs table with batching.r   )minutesecondmicrosecond   )hoursz
        SELECT *
        FROM "LiteLLM_SpendLogs"
        WHERE "startTime" >= $1::timestamp 
          AND "startTime" < $2::timestamp
        ORDER BY "startTime" ASC
        z LIMIT Nz%Error retrieving spend logs for hour z: )
r   replacer   	isoformatdb	query_rawpl	DataFramer   str)r   r   r   client
hour_starthour_endhour_start_strhour_end_strquerydb_responsees              r   get_usage_data_for_hourz'LiteLLMDatabase.get_usage_data_for_hour(   s     ++- !((!(K
	 22 $--/))+ wug&&E	] &		 3 3E>< XXK0;2<<,OO Y  	]CK=PRSVWXSYRZ[\\	]sH   A C # B5 B3B5 C B5 2C 3B5 5	C>CCC c                   K   | j                         }	 | j                  d       d{   }d}|j                  j                  |       d{   }||d|idS 7 17 # t        $ r}t	        dt        |             d}~ww xY ww)z2Get information about the LiteLLM_SpendLogs table.LiteLLM_SpendLogsNz
            SELECT column_name, data_type, is_nullable
            FROM information_schema.columns
            WHERE table_name = 'LiteLLM_SpendLogs'
            ORDER BY ordinal_position;
            
spend_logs)columns	row_counttable_breakdownzError getting table info: )r   _get_table_row_countr   r   r   r!   )r   r"   spend_logs_countr'   columns_responser)   s         r   get_table_infozLiteLLMDatabase.get_table_infoH   s     ++-	C%)%>%>?R%SSE &,YY%8%8%?? ,- "2$   T  @  	C8QABB	CsJ   BA A$A AA BA A 	B'A>>BB
table_namec                    K   | j                         }	 d| d}|j                  j                  |       d{   }|r#t        |      dkD  r|d   j	                  dd      S y7 *# t
        $ r Y yw xY ww)z#Get row count from specified table.zSELECT COUNT(*) as count FROM ""Nr   count)r   r   r   lengetr   )r   r5   r"   r'   responses        r   r1   z$LiteLLMDatabase._get_table_row_countc   s|     ++-	5j\CE#YY0077HCMA-{w22	 8
  		s8   A4$A% A#(A% !A4#A% %	A1.A40A11A4c                 2  K   | j                         }	 d}|j                  j                  |       d{   }|D cg c]  }|d   	 }}i }|D ]  }d}|j                  j                  ||       d{   }	d}
|j                  j                  |
d| d       d{   }|r|D cg c]  }|d   	 c}ng }d}|j                  j                  ||       d{   }|r|ng }d	}|j                  j                  ||       d{   }|r|ng }	 | j                  |       d{   }|	||||d||<    |t        |      |dS 7 c c}w 7 7 c c}w 7 }7 S7 5# t        $ r d
}Y @w xY w# t        $ r}t	        dt        |             d}~ww xY ww)z>Discover all tables in the LiteLLM database and their schemas.z
            SELECT table_name 
            FROM information_schema.tables 
            WHERE table_schema = 'public' 
            AND table_name LIKE 'LiteLLM_%'
            ORDER BY table_name;
            Nr5   a  
                SELECT 
                    column_name,
                    data_type,
                    is_nullable,
                    column_default,
                    character_maximum_length,
                    numeric_precision,
                    numeric_scale,
                    ordinal_position
                FROM information_schema.columns 
                WHERE table_name = $1
                AND table_schema = 'public'
                ORDER BY ordinal_position;
                z
                SELECT a.attname
                FROM pg_index i
                JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
                WHERE i.indrelid = $1::regclass AND i.indisprimary;
                r7   attnamea  
                SELECT
                    tc.constraint_name,
                    kcu.column_name,
                    ccu.table_name AS foreign_table_name,
                    ccu.column_name AS foreign_column_name
                FROM information_schema.table_constraints AS tc
                JOIN information_schema.key_column_usage AS kcu
                    ON tc.constraint_name = kcu.constraint_name
                JOIN information_schema.constraint_column_usage AS ccu
                    ON ccu.constraint_name = tc.constraint_name
                WHERE tc.constraint_type = 'FOREIGN KEY'
                AND tc.table_name = $1;
                aZ  
                SELECT
                    i.relname AS index_name,
                    array_agg(a.attname ORDER BY a.attnum) AS column_names,
                    ix.indisunique AS is_unique
                FROM pg_class t
                JOIN pg_index ix ON t.oid = ix.indrelid
                JOIN pg_class i ON i.oid = ix.indexrelid
                JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey)
                WHERE t.relname = $1
                AND t.relkind = 'r'
                GROUP BY i.relname, ix.indisunique
                ORDER BY i.relname;
                r   )r.   primary_keysforeign_keysindexesr/   )tablestable_counttable_nameszError discovering tables: )r   r   r   r1   r   r9   r!   )r   r"   litellm_tables_querytables_responserowrC   tables_infor5   columns_queryr3   pk_querypk_responser>   fk_queryfk_responser?   indexes_queryindexes_responser@   r/   r)   s                        r   discover_all_tablesz#LiteLLMDatabase.discover_all_tablesq   s    ++-c	C$  %+II$7$78L$MMO8GH3|,HKH K)
! *0)<)<]J)W#W  %+II$7$7Aj\QRBS$TTJU+F3IF[] %+II$7$7*$MM.9{r! *0)<)<]J)W#W .>*B"&*&?&?
&K KI
  0$0$0&!*+J'O *` &";/* i NH* $X UF" N$ $X
 !L  " !I"   	C8QABB	Cs   F E/ EE/ E
	*E/ 3E4)E/ E
E/ (E4&E/ E+E/ E
E/ E&E'E+E/ FE/ 
E/ E/ E/ E/ EE,)E/ +E,,E/ /	F8FFFN)i  )__name__
__module____qualname____doc__r   r   r   intr   r    r*   r   r!   r   r4   r1   rO    r   r   r	   r	      sv    E] ](SV- ]cecoco ]@Cd38n C6S S gC4S> gCr   r	   )
rS   r   r   typingr   r   r   polarsr   r	   rU   r   r   <module>rX      s$   ( ; ( & & |C |Cr   