o
    BDip                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlmZ d dl	m
Z
mZmZmZ d dlmZ d dlmZ d dlmZmZ d dlZd dlZd dlmZmZ d d	lmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z& d d
l'm(Z( e(rd dl'm)Z) d dl'm*Z* d dl'm+Z+ d dl'm,Z, d dl'm-Z- d dl.m/Z/ e0dZ1dZ2G dd deZ3dd Z4e j5		d;ddZ6dd Z7dd Z8dd  Z9d!d" Z:d#d$ Z;d%d& Z<G d'd( d(Z=G d)d* d*Z>d+d, Z?d-d. Z@d/d0 ZAd<d1d2ZBd3d4d5d6ZCd7d8 ZDd d9lEmFZFmGZGmHZH e(rd d:lEmIZI dS dS )=    N)Mapping)	timedelta)
ROUND_DOWNDecimalDefaultContextlocalcontext)wraps)Random)quoteunquote)OPSPANDATA)capture_internal_exceptionsfilename_for_moduleDsnloggermatch_regex_listqualname_from_function	to_stringtry_convertis_sentry_url_is_external_source_is_in_project_root_module_in_list)TYPE_CHECKING)Any)Dict)	Generator)Optional)Union)	FrameTypez5^[ 	]*([0-9a-f]{32})?-?([0-9a-f]{16})?-?([01])?[ 	]*$z(([a-zA-Z0-9+/]{4})*([a-zA-Z0-9+/]{2,3})?c                   @   s0   e Zd Z	dddZdd Zdd Zdd	 Zd
S )EnvironHeadersHTTP_c                 C   s   || _ || _d S N)environprefix)selfr$   r%    r'   Q/var/www/Datamplify/venv/lib/python3.10/site-packages/sentry_sdk/tracing_utils.py__init__A   s   
zEnvironHeaders.__init__c                 C   s   | j | j|dd   S N-_)r$   r%   replaceupper)r&   keyr'   r'   r(   __getitem__J      zEnvironHeaders.__getitem__c                 C   s   t dd t| D S )Nc                 s   s    | ]}d V  qdS )   Nr'   ).0r,   r'   r'   r(   	<genexpr>P   s    z)EnvironHeaders.__len__.<locals>.<genexpr>)sumiterr&   r'   r'   r(   __len__N   s   zEnvironHeaders.__len__c                 c   sP    | j D ]!}t|tsq|dd }|| jsq|t| jd  V  qd S r*   )r$   
isinstancestrr-   r.   
startswithr%   len)r&   kr'   r'   r(   __iter__R   s   

zEnvironHeaders.__iter__N)r"   )__name__
__module____qualname__r)   r0   r8   r>   r'   r'   r'   r(   r!   @   s    
	r!   c                 C   s:   | du rdS t | dduo| ddup| dduS )z}
    Returns True if either traces_sample_rate or traces_sampler is
    defined and enable_tracing is set and not false.
    NFenable_tracingtraces_sample_ratetraces_sampler)boolget)optionsr'   r'   r(   has_tracing_enabled_   s   rH   Fmanualc                 c   s    t  jd ddr|r|d gkrd }|dkrd}nd }d }t| |}i }|d ur/||d< |d ur7||d< |r=d|d	< |rG| d urG| |d
< t  t j|d|d W d    n1 s]w   Y  t jtj	||d}|
 D ]
\}	}
||	|
 qp|V  W d    d S 1 sw   Y  d S )N_experimentsrecord_sql_paramsFpyformatformatz	db.paramszdb.paramstyleTzdb.executemanyz	db.cursorquery)messagecategorydata)opnameorigin)
sentry_sdk
get_clientrG   rF   _format_sqlr   add_breadcrumb
start_spanr   DBitemsset_data)cursorrN   params_list
paramstyleexecutemanyrecord_cursor_reprspan_originrQ   spanr=   vr'   r'   r(   record_sql_queriesq   s@   
"re   c                 C   s   |j tjkr| j|jdd|jd d S |j tjkrZd }|jt	j
}|rAd|  kr.dkr3n nd}nd|  kr=dkrAn nd}|rO| jd	d
|j|d d S | jd	d
|jd d S |j dkrl| jdd|j|jd d S d S )Nredis)rO   typerP   rQ   i  iW  errori  i  warninghttphttplib)rg   rP   rQ   level)rg   rP   rQ   
subprocess)rg   rP   rO   rQ   )rR   r   DB_REDISrX   description_tagsHTTP_CLIENT_datarF   r   HTTP_STATUS_CODE)scoperc   rl   status_coder'   r'   r(   "maybe_create_breadcrumbs_from_span   s2   




rv   c                 C   s    z| j jW S  ty   Y d S w r#   )f_codeco_filename	Exception)framer'   r'   r(   _get_frame_module_abs_path   s
   
r{   c                 C   s6   t ||}t|pt ||}|  o|pt||o| S r#   )r   r   r   )is_sentry_sdk_frame	namespacein_app_includein_app_excludeabs_pathproject_rootshould_be_includedshould_be_excludedr'   r'   r(   _should_be_included   s   


r   c                 C   sD  t  }| s
dS | jdu s| jdu rdS |jdd}|s!dS | j| j }|jdd}|tdd |k}|s;dS |jd }|jd	}|jd
}t	 }	|	durt
|	}
z|	jd}W n tyk   d}Y nw |duot|d}t|||||
|d}|rn	|	j}	|	dusTd}	|	durz|	j}W n ty   d}Y nw |dur| tj|	j z|	jd}W n ty   d}Y nw |dur| tj| t
|	}|dur|durt||}n|dur||r||dtj}n|}| tj| z|	jj}W n ty   d}Y nw |dur | tj|	jj dS dS dS )zB
    Adds OTel compatible source code information to the span
    Nenable_db_query_sourceTdb_query_source_threshold_msr   r2   )millisecondsr   r~   r   r?   zsentry_sdk.)r|   r}   r~   r   r   r    )rU   rV   	is_active	timestampstart_timestamprG   rF   r   sys	_getframer{   	f_globalsry   r;   r   f_backf_linenor\   r   CODE_LINENOCODE_NAMESPACEr   r-   lstripossepCODE_FILEPATHrw   co_nameCODE_FUNCTION)rc   clientshould_add_query_sourceduration	threshold
slow_queryr   r~   r   rz   r   r}   r|   r   linenofilepathin_app_pathcode_functionr'   r'   r(   add_query_source   s   



r   c                 C   s   | sdS |  dr| dr| dd } t| }|sdS | \}}}d}|r0dt|d}|r:dt|d}|r@|d	k}|||d
S )zL
    Given a `sentry-trace` header string, return a dictionary of data.
    Nz00-z-00   z{:032x}   z{:016x}0)trace_idparent_span_idparent_sampled)r;   endswithSENTRY_TRACE_REGEXmatchgroupsrM   int)headerr   r   r   sampled_strr   r'   r'   r(   extract_sentrytrace_data8  s&   
r   c                 C   sX   d }zt | dr| |}t|tr|| jj}W n ty%   d }Y nw |p+t|S )Nmogrify)	hasattrr   r9   bytesdecode
connectionencodingry   r   )r]   sqlreal_sqlr'   r'   r(   rW   X  s   


rW   c                   @   s   e Zd ZdZdZ					dddZedd Zedd	 Z	e	j
d
d	 Z	edd Zej
dd Zdd Zdd Zdd Zdd ZdS )PropagationContextzJ
    The PropagationContext represents the data of a trace in Sentry.
    	_trace_id_span_idr   r   dynamic_sampling_contextNc                 C   s*   || _ 	 || _	 || _	 || _	 || _d S r#   r   )r&   r   span_idr   r   r   r'   r'   r(   r)   y  s   	zPropagationContext.__init__c                 C   sz   d }t |}|t}|rt }t| |_|t}|r3t|}|d ur3|d u r.t }|	| |d ur;|
  |S r#   )normalize_incoming_datarF   BAGGAGE_HEADER_NAMEr   Baggagefrom_incoming_headerr   SENTRY_TRACE_HEADER_NAMEr   update_fill_sample_rand)clsincoming_datapropagation_contextnormalized_databaggage_headersentry_trace_headersentrytrace_datar'   r'   r(   from_incoming_data  s(   


z%PropagationContext.from_incoming_datac                 C   s   | j s	t j| _ | j S )z!The trace id of the Sentry trace.)r   uuiduuid4hexr7   r'   r'   r(   r     s   zPropagationContext.trace_idc                 C   
   || _ d S r#   )r   r&   valuer'   r'   r(   r        
c                 C   s    | j st jdd | _ | j S )z+The span id of the currently executed span.r   N)r   r   r   r   r7   r'   r'   r(   r     s   zPropagationContext.span_idc                 C   r   r#   )r   r   r'   r'   r(   r     r   c              	   C   s8   |  D ]\}}zt| || W q ty   Y qw dS )zU
        Updates the PropagationContext with data from the given dictionary.
        N)r[   setattrAttributeError)r&   
other_dictr/   r   r'   r'   r(   r     s   zPropagationContext.updatec                 C   s   d | j| j| j| j| jS )Nzm<PropagationContext _trace_id={} _span_id={} parent_span_id={} parent_sampled={} dynamic_sampling_context={}>)rM   r   r   r   r   r   r7   r'   r'   r(   __repr__  s   zPropagationContext.__repr__c              
   C   s   | j du rdS tt| j d}|dur d|  krdk r dS  tt| j d}t| j|\}}zt| j||fd}W n t	yS   t
d| j d| d	 Y dS w |d
| j d< dS )aJ  
        Ensure that there is a valid sample_rand value in the dynamic_sampling_context.

        If there is a valid sample_rand value in the dynamic_sampling_context, we keep it.
        Otherwise, we generate a sample_rand value according to the following:

          - If we have a parent_sampled value and a sample_rate in the DSC, we compute
            a sample_rand value randomly in the range:
                - [0, sample_rate) if parent_sampled is True,
                - or, in the range [sample_rate, 1) if parent_sampled is False.

          - If either parent_sampled or sample_rate is missing, we generate a random
            value in the range [0, 1).

        The sample_rand is deterministically generated from the trace_id, if present.

        This function does nothing if there is no dynamic_sampling_context.
        Nsample_randr   r2   sample_rateintervalz5Could not backfill sample_rand, since parent_sampled=z and sample_rate=.z.6f)r   r   r   rF   float_sample_rand_ranger   _generate_sample_randr   
ValueErrorr   debug)r&   r   r   lowerr.   r'   r'   r(   r     s0   

z$PropagationContext._fill_sample_randc                 C   s   | j du rdS | j dS )zRConvenience method to get the sample_rand value from the dynamic_sampling_context.Nr   )r   rF   r7   r'   r'   r(   _sample_rand  s   
zPropagationContext._sample_rand)NNNNN)r?   r@   rA   __doc__	__slots__r)   classmethodr   propertyr   setterr   r   r   r   r   r'   r'   r'   r(   r   l  s.    



	



6r   c                   @   s   e Zd ZdZdZdZedZ		dddZ	e
d	d
ddZe
dd Ze
dd Zdd Zdd ZdddZedd Zdd Zdd Zd	S ) r   aF  
    The W3C Baggage header information (see https://www.w3.org/TR/baggage/).

    Before mutating a `Baggage` object, calling code must check that `mutable` is `True`.
    Mutating a `Baggage` object that has `mutable` set to `False` is not allowed, but
    it is the caller's responsibility to enforce this restriction.
    sentry_itemsthird_party_itemsmutablezsentry-z^sentry-r   Tc                 C   s   || _ || _|| _d S r#   r   )r&   r   r   r   r'   r'   r(   r)   -  s   
zBaggage.__init__N)r   c          
   	   C   s   i }d}d}|rU| dD ]G}d|vrqt 5 | }| d\}}tj|r;t| dd }	t|||	< d}n
||r@dnd| 7 }W d   n1 sOw   Y  q|durat||d	< d}t|||S )
zF
        freeze if incoming header already has sentry baggage
        r   T,=r+   r2   FNr   )splitr   stripr   SENTRY_PREFIX_REGEXr   r   r:   )
r   r   r   r   r   r   itemr/   valbaggage_keyr'   r'   r(   r   7  s,   
zBaggage.from_incoming_headerc                 C   s   i }d}d}t  }| r|jd u rt|S |j}|j}|d ur&|j|d< |dr1|d |d< |dr<|d |d< |drJt|d j	|d< |drWt
|d |d	< t|||S )
Nr   Fr   environmentreleasedsn
public_keyrC   r   )rU   rV   r   _propagation_contextr   rG   r   rF   r   r   r:   )r   rt   r   r   r   r   rG   r   r'   r'   r(   from_options[  s&   




zBaggage.from_optionsc                 C   s   t  }i }| st|S |jpi }|j|d< t|j|d< |dr*|d |d< |dr5|d |d< |drCt	|d j
|d< |jrP|jtvrP|j|d< |jdur\t|j|d	< |jdurj|jrfd
nd|d< |jrx|jjrx||jj t|ddS )z
        Populate fresh baggage entry with sentry_items and make it immutable
        if this is the head SDK which originates traces.
        r   r   r   r   r   r   transactionNr   truefalsesampledFr   )rU   rV   r   r   rG   r   r:   r   rF   r   r   rS   sourceLOW_QUALITY_TRANSACTION_SOURCESr   r   _baggager   r   )r   r   r   r   rG   r'   r'   r(   populate_from_transaction|  s0   








z!Baggage.populate_from_transactionc                 C   s
   d| _ d S )NFr  r7   r'   r'   r(   freeze  s   
zBaggage.freezec                 C   s$   i }| j  D ]\}}|||< q|S r#   )r   r[   )r&   r   r/   r   r'   r'   r(   r     s   
z Baggage.dynamic_sampling_contextFc              	   C   s   g }| j  D ]+\}}t  tjt| d tt| }|| W d    n1 s-w   Y  q|r;|| j d	|S )Nr   r   )
r   r[   r   r   SENTRY_PREFIXr
   r:   appendr   join)r&   include_third_partyr[   r/   r   r   r'   r'   r(   	serialize  s   
zBaggage.serializec                 C   s   d dd | dD S )zRemove Sentry baggage from the given header.

        Given a Baggage header, return a new Baggage header with all Sentry baggage items removed.
        r   c                 s   s$    | ]}t j| s|V  qd S r#   )r   r   r   r   )r3   r   r'   r'   r(   r4     s    
z/Baggage.strip_sentry_baggage.<locals>.<genexpr>)r	  r   )r   r'   r'   r(   strip_sentry_baggage  s
   zBaggage.strip_sentry_baggagec                 C   sB   t t| jd}|durtd|  krtdk r|S  dS dS )zConvenience method to get the sample_rand value from the sentry_items.

        We validate the value and parse it as a Decimal before returning it. The value is considered
        valid if it is a Decimal in the range [0, 1).
        r   Nr   r2   )r   r   r   rF   )r&   r   r'   r'   r(   r     s
   "zBaggage._sample_randc                 C   s   d| j dd d| j dS )Nz
<Baggage "T)r
  z", mutable=>)r  r   r7   r'   r'   r(   r     r1   zBaggage.__repr__)r   T)F)r?   r@   rA   r   r   r  recompiler   r)   r   r   r   r  r  r   r  staticmethodr  r   r   r'   r'   r'   r(   r     s,    


#
 
.
	
r   c                 C   s&   | j d }t| |rdS t||ddS )zy
    Returns True if url matches trace_propagation_targets configured in the given client. Otherwise, returns False.
    trace_propagation_targetsFT)substring_matching)rG   r   r   )r   urlr  r'   r'   r(   should_propagate_trace  s   

r  c                 C   sH   i }|   D ]\}}|dr|dd }|dd }|||< q|S )z
    Normalizes incoming data so the keys are all lowercase with dashes instead of underscores and stripped from known prefixes.
    r"      Nr,   r+   )r[   r;   r-   r   )r   rQ   r/   r   r'   r'   r(   r     s   

r   c                    s   t  r#t  fdd}z	t  |_W |S  ty"   Y |S w t  fdd}z	t  |_W |S  ty@   Y |S w )zc
    Decorator to add child spans for functions.

    See also ``sentry_sdk.tracing.trace()``.
    c                     s   t  }|d u rtdt   | i |I d H S |jtjt d  | i |I d H W  d    S 1 s9w   Y  d S NzbCannot create a child span for %s. Please start a Sentry transaction before calling this function.)rR   rS   get_current_spanr   r   r   start_childr   FUNCTIONargskwargsrc   funcr'   r(   func_with_tracing  s   $z5start_child_span_decorator.<locals>.func_with_tracingc                     sr   t  }|d u rtdt   | i |S |jtjt d  | i |W  d    S 1 s2w   Y  d S r  r  r  r  r'   r(   r   +  s   $)inspectiscoroutinefunctionr   	signature__signature__ry   )r  r   r'   r  r(   start_child_span_decorator  s&   
 r%  c                 C   s   | pt  } | j}|S )zU
    Returns the currently active span if there is one running, otherwise `None`
    )rU   get_current_scoperc   )rt   current_spanr'   r'   r(   r  G  s   r                ?r   c                C   s   |\}}||k st dt| }|}||kr |||}||kstt}d|_t|jtdtdW  d   S 1 s=w   Y  dS )a  Generate a sample_rand value from a trace ID.

    The generated value will be pseudorandomly chosen from the provided
    interval. Specifically, given (lower, upper) = interval, the generated
    value will be in the range [lower, upper). The value has 6-digit precision,
    so when printing with .6f, the value will never be rounded up.

    The pseudorandom number generator is seeded with the trace ID.
    z/Invalid interval: lower must be less than upper   z0.000001)roundingN)	r   r	   uniformr   r   precr   quantizer   )r   r   r   r.   rngr   ctxr'   r'   r(   r   Q  s   
$r   c                 C   s,   | du s|du r
dS | du rd|fS |dfS )z
    Compute the lower (inclusive) and upper (exclusive) bounds of the range of values
    that a generated sample_rand value must fall into, given the parent_sampled and
    sample_rate values.
    Nr(  Tr)  r*  r'   )r   r   r'   r'   r(   r   t  s
   r   )r   r  r   )Span)FrI   r#   )J
contextlibr!  r   r  r   collections.abcr   datetimer   decimalr   r   r   r   	functoolsr   randomr	   urllib.parser
   r   r   rU   sentry_sdk.constsr   r   sentry_sdk.utilsr   r   r   r   r   r   r   r   r   r   r   r   typingr   r   r   r   r   r   typesr    r  r   base64_strippedr!   rH   contextmanagerre   rv   r{   r   r   r   rW   r   r   r  r   r%  r  r   r   sentry_sdk.tracingr   r  r   r2  r'   r'   r'   r(   <module>   sn    8
/ [  4 J
B#