
    h*                     X    d Z ddlmZ ddlmZmZ ddlZddlmZ ddl	m
Z
  G d	 d
      Zy)z7Transform LiteLLM data to CloudZero AnyCost CBF format.    )datetime)AnyOptionalN   )	CBFRecord   )CZRNGeneratorc                       e Zd ZdZd Zdej                  dej                  fdZdej                  dej                  fdZde	e
ef   defdZdee   fd	Zy
)CBFTransformerz?Transform LiteLLM usage data to CloudZero Billing Format (CBF).c                 "    t               | _        y)z+Initialize transformer with CZRN generator.N)r	   czrn_generator)selfs    d/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/integrations/cloudzero/transform.py__init__zCBFTransformer.__init__!   s    +o    datareturnc                    |j                         rt        j                         S t        |      }|j	                  t        j
                  d      dkD  t        j
                  d      j                         z  t        j
                  d      dk7  z        }t        |      }||z
  }|j                         r7ddlm}  |       }|j                  d|dd       t        j                         S | j                  |      }g }	d}
|j                  d	
      D ]%  }	 | j                  |      }|	j                  |       ' ddlm}  |       }|dkD  r|j                  d|dd|dd       |
dkD  r#|j                  d|
ddt        |      dd       t        |	      dkD  r|j                  dt        |	      dd       t        j                  |	      S # t        $ r |
dz  }
Y w xY w)zATransform LiteLLM SpendLogs data to hourly aggregated CBF format.spendr   team_id )Consoleu   [yellow]⚠️  Dropped all ,z6 records due to zero spend or missing team_id[/yellow]T)namedr   u   [yellow]⚠️  Dropped z of z4 records with zero spend or missing team_id[/yellow]z1 aggregated records due to invalid CZRNs[/yellow]u$   [green]✓ Successfully transformed z" hourly aggregated records[/green])is_emptypl	DataFramelenfiltercolis_not_nullrich.consoler   print_aggregate_to_hourly	iter_rows_create_cbf_recordappend	Exception)r   r   original_countfiltered_datafiltered_countzero_spend_droppedr   consolehourly_aggregatedcbf_dataczrn_dropped_countrow
cbf_records                r   	transformzCBFTransformer.transform%   s   ==?<<>! TVVG_q VVI**,.VVI"$&

 ]++n<!!#,iGMM88J  KA  B  C<<>! !55mD $..T.:C!44S9

+ ; 	))!MM45G4J$~^_N`  aU  V  W!MM45G4J$sSdOefgNh  iZ  [  \x=1MM@Xq@QQstu||H%%%  "a'"s   "GG! G!c                 ,   |j                  t        j                  d      j                  j	                         j
                  j                  d      j                  d      t        j                  g       j                  t        j                  t        j                              j                  d      t        j                  d      j                  d      g      }|j                  t        j                  dt        j                        j                  d	      g      }|j                  g d
      j                  t        j                  d      j                         j                  d      t        j                  d      j                         j                  d      t        j                  d      j                         j                  d      t        j                  d      j                         j                  d      t        j                  d      j                         j                  d      t        j                  d      j!                         j                  d      t        j                  d      j#                  t        j                  d      dk(        j                         j                  d      t        j                  d      j#                  t        j                  d      dk7        j                         j                  d      g      }|S )zKAggregate spend logs to hourly level by team_id, key_name, model, and tags.	startTime1h
usage_hourparsed_tagsr   key_nameN)dtypetag)r7   r   r9   modelmodel_groupcustom_llm_providerr;   r   total_spendtotal_tokensprompt_tokenstotal_prompt_tokenscompletion_tokenstotal_completion_tokens
request_idrequest_countapi_keyapi_key_samplestatussuccesssuccessful_requestsfailed_requests)with_columnsr   r    strto_datetimedttruncatealiaslitcastListStringgroup_byaggsumcountfirstr   )r   r   data_with_hourall_data
aggregateds        r   r$   z#CBFTransformer._aggregate_to_hourlyY   s0    **FF;##//144==dCII,WFF2JOOBGGBII./55mDFF2JZ(,
  "..FF4ryy)//60
 
 && (
  3FF7O!''6FF>"&&(..~>FF?#'')//0EFFF&'++-334MNFF< &&(..?FF9##%++,<=FF8##BFF8$4	$ABHHJPPQfgFF8##BFF8$4	$ABHHJPPQbc	
 	 	$ r   r1   c                    d }| j                   ||j                  d                  }t         ||j                  dd                  }t         ||j                  dd                  }t         ||j                  dd                  }t         ||j                  dd                  }t         ||j                  dd                  } ||j                  d	            }	t         ||j                  d
d            xs d      }
t	         ||j                  dd            xs d      }t	         ||j                  dd            xs d      }t	         ||j                  dd            xs d      }t	         ||j                  dd            xs d      }t	         ||j                  dd            xs d      }t	         ||j                  dd            xs d      }|d||t         ||j                  dd                  d}| j
                  j                  |      }d|||||t        |      t        |      t        |      d	}|	t        |	      dvrt        |	      |d	<   | j
                  j                  |      }|\  }}}}}}|r|j                         nd|
||d||||dd
}||d<   ||d<   |j                         D ]W  \  }}t        |d      r$t        |t              s||j                         nd}|9t        |      dvsGt        |      |d | <   Y |dkD  rt        |      |d!<   |dkD  rt        |      |d"<   |dkD  rt        |      |d#<   t        |      S )$z=Create a single CBF record from aggregated hourly spend data.c                     t        | d      r4t        | t        t        t        t
        f      s| | j                         S d S | S )Nitem)hasattr
isinstancerN   intfloatboolra   )values    r   extract_scalarz9CBFTransformer._create_cbf_record.<locals>.extract_scalar   s:    uf%jc5RV@W.X','8uzz|BdBLr   r7   r   r   r9   r<   r=   r>   r;   r?   g        r@   r   rB   rD   rF   rK   rL   teamrH   )	entity_identity_typer<   r>   rG   )	rk   rj   r9   r<   r=   providerrF   rK   rL   N)r   nullNonetokensUsage)
ztime/usage_startz	cost/costzresource/idzusage/amountzusage/unitszresource/servicezresource/accountzresource/regionzresource/usage_familyzlineitem/typezresource/tag:providerzresource/tag:modelra   )r   zN/Arn   rm   zresource/tag:zresource/tag:prompt_tokenszresource/tag:completion_tokenszresource/tag:total_tokens)_parse_datetimegetrN   re   rd   r   create_from_litellm_dataextract_components	isoformatitemsrb   rc   ra   r   )r   r1   rh   
usage_timerj   r9   r<   r=   rl   r;   r?   r@   rB   rD   rF   rK   rL   czrn_rowresource_id
dimensionsczrn_componentsservice_typeprovider_czrnregionowner_account_idresource_typecloud_local_idr2   keyrg   s                                 r   r&   z!CBFTransformer._create_cbf_record~   s{   	 )).9N*OP
 swwy"'=>?	~cggj"&=>?N3777B#789.)CDE~cgg.CR&HIJSWWU^, N377=#+FGN3O>#''.!*DEJK!.9NPQ1R"S"XWXY"%nSWW=VXY5Z&[&`_`"aN377?A+FGL1M!.9NPQ1R"S"XWXYnSWW5F-JKPqQ
 #!#+>#''2BB*GHI
 ))BB8L "" &  /#&':#;"?3


 ?s3x/CC #CJu --@@M_n\mV-=}n
 ;E
 4 4 6$$& )# !- 0%%2 %#

* /<
*++9
'( %**,JCuf%j.D(-(9

t SZ7R%R47J
]3%01 - "7:;N7OJ34"Q&;>?V;WJ78!69,6GJ23$$r   c                     |yt        |t              r|S t        |t              r=	 t        j                  |g      j                  j                         j                         S y# t        $ r Y yw xY w)z.Parse datetime object to ensure proper format.N)rc   r   rN   r   SeriesrO   ra   r(   )r   datetime_objs     r   rq   zCBFTransformer._parse_datetime   sl    lH-lC(yy,044@@BGGII   s   ;A$ $	A0/A0N)__name__
__module____qualname____doc__r   r   r   r3   r$   dictrN   r   r   r&   r   r   rq    r   r   r   r      sr    I.2&bll 2&r|| 2&h" "",, "Jf%d38n f% f%Px/A r   r   )r   r   typingr   r   polarsr   types.integrations.cloudzeror   cz_resource_namesr	   r   r   r   r   <module>r      s%   & >     5 ,W Wr   