ó
    Ð]jç:  ã                  óH  • % S SK Jr  S SKrS SKrS SKrS SKJrJr  S SKJ	r	J
r
  S SKJr  S SKJrJrJrJr  S SKrS SKJr  S SKJr  S S	KJr  S S
KJr  SSKJrJrJrJrJ r J!r!J"r"J#r#J$r$J%r%J&r&J'r'J(r(  SSK)J*r+  SSK,J-r-  SSK.J/r/J0r0  SSSSSSSSSSSSS/S V s/ s H	  n SU  S3PM     sn Qr1Sr2S \3S!'   \ " S" S#5      5       r4\\4/\4   r5 " S$ S%\5      r6\ " S& S'5      5       r7 " S( S)\5      r8 " S* S+\85      r9\9" 5       r: " S, S-\85      r; " S. S/5      r< " S0 S15      r=gs  sn f )2é    )ÚannotationsN)ÚABCÚabstractmethod)ÚMappingÚSequence)Ú	dataclass)ÚAnyÚCallableÚ	TypedDictÚcast)Ú	LogRecord)ÚBoundedAttributes)ÚEvent)ÚLinké   )ÚATTRIBUTES_JSON_SCHEMA_KEYÚATTRIBUTES_LOG_LEVEL_NAME_KEYÚATTRIBUTES_LOG_LEVEL_NUM_KEYÚATTRIBUTES_LOGGING_NAMEÚATTRIBUTES_MESSAGE_KEYÚATTRIBUTES_MESSAGE_TEMPLATE_KEYÚ'ATTRIBUTES_PENDING_SPAN_REAL_PARENT_KEYÚATTRIBUTES_SAMPLE_RATE_KEYÚATTRIBUTES_SCRUBBED_KEYÚATTRIBUTES_SPAN_TYPE_KEYÚATTRIBUTES_TAGS_KEYÚ$MESSAGE_FORMATTED_VALUE_LENGTH_LIMITÚ$RESOURCE_ATTRIBUTES_PACKAGE_VERSIONS)Úsemconv)ÚSTACK_INFO_KEYS)ÚReadableSpanDictÚtruncate_stringÚpasswordÚpasswdÚ	mysql_pwdÚsecretzauth(?!ors?\b)Ú
credentialzprivate[._ -]?keyzapi[._ -]?keyÚsessionÚcookiezsocial[._ -]?securityzcredit[._ -]?cardzlogfire[._ -]?token)ÚcsrfÚxsrfÚjwtÚssnz(?:\b|_)ztuple[str | int, ...]ztyping_extensions.TypeAliasÚJsonPathc                  ó<   • \ rS rSr% SrS\S'    S\S'    S\S'   S	rg
)Ú
ScrubMatchéB   z`An object passed to a [`ScrubbingOptions.callback`][logfire.ScrubbingOptions.callback] function.r.   Úpathr	   Úvaluezre.Match[str]Úpattern_match© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__Ú__static_attributes__r5   ó    ÚX/home/mande/repo/quber/.venv/lib/python3.13/site-packages/logfire/_internal/scrubbing.pyr0   r0   B   s    ‡ ájà
ƒNØnàƒJØUà Ó òr=   r0   c                  ó*   • \ rS rSr% S\S'   S\S'   Srg)ÚScrubbedNoteéV   r.   r2   ÚstrÚmatched_substringr5   N)r6   r7   r8   r9   r;   r<   r5   r=   r>   r@   r@   V   s   ‡ Ø
ƒNØÖr=   r@   c                  ó8   • \ rS rSr% SrSrS\S'    SrS\S'   Srg)	ÚScrubbingOptionsé[   z%Options for redacting sensitive data.NúScrubCallback | NoneÚcallbackúSequence[str] | NoneÚextra_patternsr5   )	r6   r7   r8   r9   r:   rH   r;   rJ   r<   r5   r=   r>   rE   rE   [   s'   ‡ á/à%)€HÐ"Ó)ðð ,0€NÐ(Ó/òr=   rE   c                  óp  • \ rS rSr1 \i\i\i\i\i\	i\
i\i\i\i\i\i\kSiSiSiSiSiSiSiS	iS
iSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSi\R$                  i\R&                  i\R(                  i\R*                  i\R,                  i\R.                  i\R0                  i\R2                  i\R4                  i\R6                  i\R8                  i\R:                  i\R<                  i\R>                  i\R@                  i\RB                  ir"\#S!S j5       r$\#S"S j5       r%\#S#S j5       r&Sr'g )$ÚBaseScrubberéo   zexception.stacktracezexception.typezexception.messagez
error.typezhttp.methodzhttp.status_codezhttp.schemezhttp.urlzhttp.targetz
http.routezdb.statementzdb.planzfastapi.route.namezfastapi.route.operation_idzurl.fullzurl.pathz	url.queryz
event.nameÚagent_session_idÚdo_not_scrubÚbinary_contentzpydantic_ai.all_messagesz
rpc.methodÚmodel_request_parameterszlangsmith.metadata.session_idzlangsmith.trace.session_namec                ó   • g ©Nr5   ©ÚselfÚspans     r>   Ú
scrub_spanÚBaseScrubber.scrub_span¬   s   € Ø25r=   c                ó   • g rS   r5   ©rU   Úlogs     r>   Ú	scrub_logÚBaseScrubber.scrub_log¯   s   € Ø69r=   c                ó   • g rS   r5   ©rU   r2   r3   s      r>   Úscrub_valueÚBaseScrubber.scrub_value²   s   € ØY\r=   r5   N©rV   r!   ©r[   r   Úreturnr   ©r2   r.   r3   r	   rd   ztuple[Any, list[ScrubbedNote]])(r6   r7   r8   r9   r   r   r   r   r   r   r   r   r   r   r   r   r    Úgen_ai_semconvÚINPUT_MESSAGESÚOUTPUT_MESSAGESÚSYSTEM_INSTRUCTIONSÚTOOL_DEFINITIONSÚ	TOOL_NAMEÚTOOL_CALL_IDÚINPUT_TOKENSÚOUTPUT_TOKENSÚCACHE_READ_INPUT_TOKENSÚCACHE_CREATION_INPUT_TOKENSÚ	USAGE_RAWÚCONVERSATION_IDÚSYSTEMÚPROVIDER_NAMEÚREQUEST_MODELÚRESPONSE_MODELÚ	SAFE_KEYSr   rW   r\   r`   r<   r5   r=   r>   rL   rL   o   sè  † ð8Øð8à'ð8ð 	#ð8ð 	ð	8ð
 	&ð8ð 	%ð8ð 	!ð8ð 	0ð8ð 	#ð8ð 	 ð8ð 	 ð8ð 	-ð8ð 
ð8ð 	ð8ð 	ð8ð  	ð!8ð" 	ð#8ð$ 	ð%8ð& 	ð'8ð( 	ð)8ð* 	ð+8ð, 	ð-8ð. 	ð/8ð0 	ð18ð2 	ð38ð4 	ð58ð6 	%ð78ð8 	ð98ð: 	ð;8ð< 	ð=8ð> 	ð?8ð@ 	ðA8ðB 	ðC8ðD 	ðE8ðF 	#ðG8ðH 	ðI8ðJ 	#ðK8ðL 	(ðM8ðN 	'ðO8ðP 	×%Ñ%ðQ8ðR 	×&Ñ&ðS8ðT 	×*Ñ*ðU8ðV 	×'Ñ'ðW8ðX 	× Ñ ðY8ðZ 	×#Ñ#ð[8ð\ 	×#Ñ#ð]8ð^ 	×$Ñ$ð_8ð` 	×.Ñ.ða8ðb 	×2Ñ2ðc8ðd 	× Ñ ðe8ðf 	×&Ñ&ðg8ðh 	×Ñði8ðj 	×$Ñ$ðk8ðl 	×$Ñ$ðm8ðn 	×%Ñ%ðo8€Iðt Û5ó Ø5àÛ9ó Ø9àÛ\ó Û\r=   rL   c                  ó2   • \ rS rSrSS jrSS jrS	S jrSrg)
ÚNoopScrubberé¶   c                ó   • g rS   r5   rT   s     r>   rW   ÚNoopScrubber.scrub_span·   s   € Ør=   c                ó   • U$ rS   r5   rZ   s     r>   r\   ÚNoopScrubber.scrub_logº   s   € Øˆ
r=   c                ó
   • U/ 4$ rS   r5   r_   s      r>   r`   ÚNoopScrubber.scrub_value½   s   € Ø�bˆyÐr=   r5   Nrb   rc   re   )r6   r7   r8   r9   rW   r\   r`   r<   r5   r=   r>   ry   ry   ¶   s   † ôô÷r=   ry   c                  óD   • \ rS rSrSrS	S
S jjrSS jrSS jrSS jrSr	g)ÚScrubberéÄ   z#Redacts potentially sensitive data.Nc                óÊ   • / [         QU=(       d    / Qn[        R                  " SR                  U5      [        R                  [        R
                  -  5      U l        X l        g )NÚ|)ÚDEFAULT_PATTERNSÚreÚcompileÚjoinÚ
IGNORECASEÚDOTALLÚ_patternÚ	_callback)rU   ÚpatternsrH   s      r>   Ú__init__ÚScrubber.__init__Ç   sC   € à9Ô%Ð9¨¯°RÐ9ˆÜŸ
š
 3§8¡8¨HÓ#5´r·}±}ÄrÇyÁyÑ7PÓQˆŒØ!�r=   c                ó:   • [        U 5      nUR                  U5      $ rS   )ÚSpanScrubberr\   )rU   r[   Úspan_scrubbers      r>   r\   ÚScrubber.scrub_logÍ   s   € Ü$ TÓ*ˆØ×&Ñ& sÓ+Ð+r=   c                ó¼  • US   nU(       a  UR                   S;   a  g [        U 5      nUR                  U5        UR                  (       av  US   n[	        SUR                  [        S5      5      n [	        S[        R                  " U5      5      n0 UE[        [        R                  " XSR                  -   5      0EUS'   g g ! [        R                   a    / n NIf = f)NÚinstrumentation_scope)zlogfire.openaizlogfire.anthropicÚ
attributesrB   z[]zlist[ScrubbedNote])Únamer’   rW   Úscrubbedr   Úgetr   ÚjsonÚloadsÚJSONDecodeErrorÚdumps)rU   rV   Úscoper“   r—   Úalready_scrubbeds         r>   rW   ÚScrubber.scrub_spanÑ   sÔ   € ØÐ,Ñ-ˆÞ�U—Z‘ZÐ#JÓJØä$ TÓ*ˆØ× Ñ  Ô&Ø×!×!Ø˜lÑ+ˆJÜ# E¨:¯>©>Ô:QÐSWÓ+XÓYÐð&Ü#'Ð(<¼d¿jºjÐIYÓ>ZÓ#[Ð ð"Øð"ä'¬¯ªÐ4D×G]ÑG]Ñ4]Ó)^ñ"ˆD�Òð "øô
 ×'Ñ'ó &Ø#%Ò ð&ús   Á1 C ÃCÃCc                óT   • [        U 5      nUR                  X5      nXCR                  4$ rS   )r’   Úscrubr™   )rU   r2   r3   r“   Úresults        r>   r`   ÚScrubber.scrub_valueä   s+   € Ü$ TÓ*ˆØ×$Ñ$ TÓ1ˆØ×-Ñ-Ð-Ð-r=   )r�   rŒ   rS   )rŽ   rI   rH   rG   rc   rb   re   )
r6   r7   r8   r9   r:   r�   r\   rW   r`   r<   r5   r=   r>   r‚   r‚   Ä   s   † Ù-ö"ô,ô÷&.r=   r‚   c                  óT   • \ rS rSrSrSS jrSS jrSS jrSS jrSS jr	SS jr
S	rg
)r’   éê   zÎDoes the actual scrubbing work.

This class is separate from Scrubber so that it can be instantiated more regularly
and hold and mutate state about the span being scrubbed, specifically the scrubbed notes.
c                ód   • UR                   U l         UR                  U l        / U l        SU l        g )NF)rŒ   r�   r™   Ú	did_scrub)rU   Úparents     r>   r�   ÚSpanScrubber.__init__ñ   s(   € ØŸ™ˆŒØ×)Ñ)ˆŒØ,.ˆŒØˆ�r=   c                óê  • U R                  SUS   5      nU R                  (       a  [        US9US'   [        US   5       VVs/ s H:  u  p4[	        UR
                  [        U R                  XC5      S9UR                  S9PM<     snnUS'   [        US   5       VVs/ s H=  u  p5[        UR                  [        U R                  SUS4UR                  5      S9S9PM?     snnUS'   g s  snnf s  snnf )N©r—   r—   Úevents)r˜   r—   Ú	timestampÚlinks)Úcontextr—   )r£   r©   r   Ú	enumerater   r˜   Úscrub_event_attributesr¯   r   r±   r—   )rU   rV   Únew_attributesÚiÚeventÚlinks         r>   rW   ÚSpanScrubber.scrub_span÷   sô   € ð Ÿ™ O°T¸,Ñ5GÓHˆØ�>�>Ü!2¸nÑ!MˆD�Ñô & d¨8¡nÔ5ô	
ò 6‘�ô ð —Z‘ZÜ,¸×8SÑ8SÐTYÓ8]Ñ^ØŸ/™/ôñ 6ò	
ˆˆX‰ô % T¨'¡]Ô3ô
ò
 4‘�ô	 ØŸ™Ü,¸¿
¹
ÀGÈQÐP\ÐC]Ð_c×_nÑ_nÓ8oÑpôñ 4ò
ˆˆWŠùó	
ùó
s   ÁAC)ÂAC/c                óv  • U R                  SUR                  5      nU R                  SUR                  5      nU R                  (       d  U$ U R                  (       a2  U=(       d    0 n[
        R                  " U R                  5      U[        '   [        R                  " U5      n[        US9Ul        X4l        U$ )Nr­   )Úlog_body)
r£   r—   Úbodyr©   r™   r›   rž   r   Úcopyr   )rU   r[   r´   Únew_bodyr¤   s        r>   r\   ÚSpanScrubber.scrub_log  sƒ   € Ø04·
±
¸?ÈCÏNÉNÓ0[ˆØ—:‘:˜m¨S¯X©XÓ6ˆà�~�~ØˆJà�=�=Ø+×1¨rˆNÜ6:·j²jÀÇÁÓ6OˆNÔ2Ñ3ä—’˜3“ˆÜ-¸ÑHˆÔØŒØˆr=   c                ó\   • UR                   =(       d    0 nSUS4nU R                  XC5      nU$ )NÚotel_eventsr—   )r—   r£   )rU   r¶   Úindexr—   r2   r´   s         r>   r³   Ú#SpanScrubber.scrub_event_attributes$  s2   € Ø×%Ñ%×+¨ˆ
Ø˜u lÐ3ˆØŸ™ DÓ5ˆàÐr=   c                ó8  • [        U[        5      (       a‚  U R                  R                  U5      =n(       a]  UR	                  5       S[        U5      4:X  a  U$  [        R                  " U5      n[        R                  " U R                  X5      5      $  U$ [        U[        5      (       a=  [        [        SU5      5       VVs/ s H  u  pEU R                  X4-   U5      PM     snn$ [        U[         5      (       aà  0 n[        SU5      R#                  5        H¾  u  pxU[$        R&                  ;   a  X†U'   M  U R                  R                  U5      =n(       af  U R                  [        X4-   Xƒ5      5      n	[        U	[        5      (       a-  [        U[        5      (       a  [        U[        5      (       d  U	/n	X–U'   M§  U R                  X4-   U5      Xg'   MÀ     U$ U$ ! [        R                   a    U R                  [        XU5      5      s $ f = fs  snnf )züRedacts sensitive data from `value`, recursing into nested sequences and mappings.

`path` is a list of keys and indices leading to `value` in the span.
Similar to the truncation code, it should use the field names in the frontend, e.g. `otel_events`.
r   zSequence[Any]zMapping[str, Any])Ú
isinstancerB   rŒ   ÚsearchrV   Úlenr›   rœ   rž   r£   r�   Ú_redactr0   r   r²   r   r   ÚitemsrL   rw   )
rU   r2   r3   Úmatchrµ   Úxr¤   ÚkÚvÚredacteds
             r>   r£   ÚSpanScrubber.scrub+  sÉ  € ô �eœS×!Ñ!ØŸ™×,Ñ,¨UÓ3Ð3ˆuÕ3Ø—:‘:“< A¤s¨5£z ?Ó2ð !�Lð?Ü ŸJšJ uÓ-�Eô  Ÿ:š: d§j¡j°Ó&=Ó>Ð>ð 4ð4 ˆô ˜œx×(Ñ(Ü;DÄTÈ/Ð[`ÓEaÔ;bÔcÒ;b±4°1�D—J‘J˜t d™{¨AÖ.Ñ;bÒcÐcÜ˜œw×'Ñ'Ø%'ˆFÜÐ0°%Ó8×>Ñ>Ö@‘�Øœ×.Ñ.Ó.Ø !˜1“IØ"Ÿm™m×2Ñ2°1Ó5Ð5�UÕ5Ø#Ÿ|™|¬J°t¸d±{ÀAÓ,MÓN�HÜ! (¬C×0Ñ0´ZÀÄ8×5LÑ5LÔU_Ð`aÔcf×UgÑUgØ$, :˜Ø (˜1“Ià $§
¡
¨4°$©;¸Ó :�F“Iñ Að ˆMØˆøô' ×+Ñ+ó HØŸ<™<¬
°4ÀÓ(FÓGÒGðHüó
 ds   ÁG! Ã!HÇ!/HÈHc                óF  • U R                   (       a;  U R                  U5      =nb'  U R                  =(       d    X!R                  LU l        U$ SU l        UR                  R	                  S5      nU R
                  R                  [        UR                  US95        SU< S3$ )NTr   )r2   rC   z[Scrubbed due to Ú])	r�   r©   r3   r4   Úgroupr™   Úappendr@   r2   )rU   rÉ   r¤   rC   s       r>   rÇ   ÚSpanScrubber._redactN  s…   € Ø�>�>¨¯©¸Ó)>Ð>˜vÑKØ!Ÿ^™^×H¨v¿[¹[Ð/HˆDŒNØˆMØˆŒØ!×/Ñ/×5Ñ5°aÓ8ÐØ�‰×Ñœ\¨u¯z©zÐM^Ñ_Ô`Ø"Ð#4Ñ"7°qÐ9Ð9r=   )r�   rŒ   r©   r™   N)rª   r‚   rb   rc   )r¶   r   rÁ   Úint)r2   r.   r3   r	   rd   r	   )rÉ   r0   rd   r	   )r6   r7   r8   r9   r:   r�   rW   r\   r³   r£   rÇ   r<   r5   r=   r>   r’   r’   ê   s&   † ñôô
ô:ô ô!÷F:r=   r’   c                  ó@   • \ rS rSrSrS	S jrS
S jrSS jrSS jrSr	g)ÚMessageValueCleaneriX  aR  Scrubs and truncates formatted field values to be included in the message attribute.

Use to construct the message for a single span, e.g:

    cleaner = MessageValueCleaner(scrubber, check_keys=...)
    message_parts = [cleaner.clean_value(field_name, str(value)) for field_name, value in fields]
    message = <construct from message parts>
    attributes = {**other_attributes, **cleaner.extra_attrs(), ATTRIBUTES_MESSAGE_KEY: message}

check_keys determines whether the key should be accounted for in scrubbing.
Set to False if the user explicitly provided the key, e.g. `logfire.info(f'... {password} ...')`
means that the password is clearly expected to be logged.
The password will therefore not be scrubbed here and will appear in the message.
However it may still be scrubbed out of the attributes, just because that process is independent.
c               ó*   • Xl         / U l        X l        g rS   )Úscrubberr™   Ú
check_keys)rU   rØ   rÙ   s      r>   r�   ÚMessageValueCleaner.__init__i  s   € Ø ŒØ,.ˆŒØ$�r=   c                ó6  • XR                   R                  ;  ap  U R                  (       a$  U R                   R                  SX05      u  p4X1   nO U R                   R                  SU4U5      u  p$U R                  R                  U5        U R                  U5      $ )N)ÚmessagerÜ   )rØ   rw   rÙ   r`   r™   ÚextendÚtruncate)rU   Ú
field_namer3   Úscrubbed_valueÚscrubbed_notess        r>   Úclean_valueÚMessageValueCleaner.clean_valuen  s‚   € ð Ÿ]™]×4Ñ4Ó4Ø��à15·±×1JÑ1JÈ<ÐZdÐYlÓ1mÑ.�Ø&Ñ2‘ð )-¯©×(AÑ(AÀ9ÈjÐBYÐ[`Ó(aÑ%�Ø�M‰M× Ñ  Ô0Ø�}‰}˜UÓ#Ð#r=   c                ó   • [        U[        S9$ )N)Ú
max_length)r"   r   )rU   r3   s     r>   rÞ   ÚMessageValueCleaner.truncate~  s   € Ü˜uÔ1UÑVÐVr=   c                ót   • U R                   (       a&  [        [        R                  " U R                   5      0$ 0 $ rS   )r™   r   r›   rž   )rU   s    r>   Úextra_attrsÚMessageValueCleaner.extra_attrs�  s&   € Ø�=�=Ü+¬T¯ZªZ¸¿¹Ó-FÐGÐGØˆ	r=   )rÙ   r™   rØ   N)rØ   rL   rÙ   Úbool)rß   rB   r3   rB   rd   rB   )r3   rB   rd   rB   )rd   zdict[str, Any])
r6   r7   r8   r9   r:   r�   râ   rÞ   rè   r<   r5   r=   r>   rÖ   rÖ   X  s   † ñô %ô
$ô W÷r=   rÖ   )>Ú
__future__r   r¼   r›   r‡   Úabcr   r   Úcollections.abcr   r   Údataclassesr   Útypingr	   r
   r   r   Útyping_extensionsÚopentelemetry._logsr   Úopentelemetry.attributesr   Úopentelemetry.sdk.tracer   Úopentelemetry.tracer   Ú	constantsr   r   r   r   r   r   r   r   r   r   r   r   r   Úintegrations.llm_providersr   rf   Ú
stack_infor    Úutilsr!   r"   r†   r.   r;   r0   ÚScrubCallbackr@   rE   rL   ry   ÚNOOP_SCRUBBERr‚   r’   rÖ   )Úacronyms   0r>   Ú<module>rü      s^  ðÞ "ã Û Û 	ß #ß -Ý !ß 1Ó 1ã Ý )Ý 6Ý )Ý $÷÷ ÷ õ õ BÝ 'ß 4ð ØØØØØØØØØØØØðñ$
ó	
ò
ˆGð �G�9˜HÓ%ñ
ñ	
ðÐ ð6 )@€Ð
%Ó ?ð ÷ð ó ðð  ˜*˜ sÐ*Ñ+€ô�9ô ð
 ÷ð ó ðô&D]�3ô D]ôN�<ô ñ “€ô#.ˆ|ô #.÷Lk:ñ k:÷\,ò ,ùòM	
s   ÂD