a
    xdR+                     @   s  d 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
 ddlmZ ddlmZ ddlmZmZ dd	l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 m!Z! edZ"dZ#dZ$dddZ%dd Z&G dd dZ'dS )zf
An ASGI middleware.

Based on Tom Christie's `sentry-asgi <https://github.com/encode/sentry-asgi>`_.
    N)partial)MYPY)Hub_should_send_default_pii)_filter_headers)auto_session_tracking)SOURCE_FOR_STYLETRANSACTION_SOURCE_ROUTE)
ContextVarevent_from_exceptionHAS_REAL_CONTEXTVARSCONTEXTVARS_ERROR_MESSAGEtransaction_from_function)Transaction)Dict)Any)Optional)Callable)Literal)EventHintZsentry_asgi_middleware_appliedzgeneric ASGI request)endpointurlasgic                 C   s8   | j d ur4t|| j j|ddd\}}| j||d d S )NF)typeZhandled)Zclient_optionsZ	mechanism)hint)clientr   optionsZcapture_event)hubexcmechanism_typeeventr    r"   T/var/www/html/Ranjet/env/lib/python3.9/site-packages/sentry_sdk/integrations/asgi.py_capture_exception/   s    

r$   c                 C   sB   t | rt| dS t | r(t| S t| dd}t|S dS )z
    Try to figure out if an application object supports ASGI3.

    This is how uvicorn figures out the application version as well.
    	__await____call__N)inspectisclasshasattr
isfunctionasyncioiscoroutinefunctiongetattr)appcallr"   r"   r#   _looks_like_asgi3<   s    



r0   c                   @   sb   e Zd ZdZdddZdd Zd	d
 Zdd Zdd Zdd Z	dd Z
dd Zdd Zdd ZdS )SentryAsgiMiddleware)r.   r&   transaction_styler    Fr   r   c                 C   s\   |st stdt |tvr,td|tf || _|| _|| _t|rP| j	| _
n| j| _
dS )ab  
        Instrument an ASGI application with Sentry. Provides HTTP/websocket
        data to sent events and basic handling for exceptions bubbling up
        through the middleware.

        :param unsafe_context_data: Disable errors when a proper contextvars installation could not be found. We do not recommend changing this from the default.
        zRThe ASGI middleware for Sentry requires Python 3.7+ or the aiocontextvars package.z7Invalid value for transaction_style: %s (must be in %s)N)r   RuntimeErrorr   TRANSACTION_STYLE_VALUES
ValueErrorr2   r    r.   r0   
_run_asgi3r&   
_run_asgi2)selfr.   Zunsafe_context_datar2   r    r"   r"   r#   __init__O   s$    
zSentryAsgiMiddleware.__init__c                    s    fdd}|S )Nc                    s      fddI d H S )Nc                      s     S Nr.   r"   receivescoper8   sendr"   r#   <lambda>x       z@SentryAsgiMiddleware._run_asgi2.<locals>.inner.<locals>.<lambda>_run_appr=   r?   r>   r8   rD   r#   innerv   s    z.SentryAsgiMiddleware._run_asgi2.<locals>.innerr"   )r8   r>   rF   r"   rE   r#   r7   t   s    zSentryAsgiMiddleware._run_asgi2c                    s      fddI d H S )Nc                      s     S r:   r;   r"   r<   r"   r#   r@   ~   rA   z1SentryAsgiMiddleware._run_asgi3.<locals>.<lambda>rB   )r8   r>   r=   r?   r"   r<   r#   r6   |   s    zSentryAsgiMiddleware._run_asgi3c           
         s<  t d}|rZz| I d H W S  tyX } z$ttj|| jd |d W Y d }~n
d }~0 0 t d zttj}t|dd |d |	 6}|
  d|_t| j|d}|| W d    n1 s0    Y  |d }|d	v rtj| |d
|d}	n
tdd}	t|	_t|	_|	d| |j|	d|id zD| I d H W W  d    W  d    W  d    W t d S  ty } z"t||| jd |d W Y d }~n
d }~0 0 W d    n1 s0    Y  W d    n1 s0    Y  W d    n1 s0    Y  W t d nt d 0 d S )NF)r    Trequest)Zsession_moder   )
asgi_scoper   httpZ	websocketz	{}.server)opzasgi.serverz	asgi.typerH   )Zcustom_sampling_context)_asgi_middleware_appliedget	Exceptionr$   r   currentr    setr   Zconfigure_scopeZclear_breadcrumbs_namer   event_processorZadd_event_processorr   Zcontinue_from_headers_get_headersformat_DEFAULT_TRANSACTION_NAMEnamer	   sourceZset_tagZstart_transaction)
r8   r>   callbackZis_recursive_asgi_middlewarer   r   Zsentry_scope	processortytransactionr"   r"   r#   rC      sP    



(

8
~zSentryAsgiMiddleware._run_appc                 C   s   | di }|d }|dv rr| d|d< t| | |d< }| ||d< | ||dkr`dnd| d	|d
< | d}|rt rd| |i|d< | || j| ||d< |S )NrG   r   rI   methodheadersquery_stringrJ   wshostr   r   ZREMOTE_ADDRenv)	rM   r   rS   
_get_query_get_urlr   _get_ip _set_transaction_name_and_sourcer2   )r8   r!   r   rH   Zrequest_inforZ   r]   r   r"   r"   r#   rR      s"    

z$SentryAsgiMiddleware.event_processorc           	      C   s   | dttk}|rd S d}|dkr@| d}|rnt|p<d}n.|dkrn| d}|rnt|dd }|d urn|}|st|d< dti|d< d S ||d< dt| i|d< d S )	Nr[    r   r   routepathrW   Ztransaction_info)rM   rU   r   r-   r	   r   )	r8   r!   r2   rH   Ztransaction_name_already_setrV   r   rg   rh   r"   r"   r#   re      s.    


z5SentryAsgiMiddleware._set_transaction_name_and_sourcec           	      C   s   | d|}| dd}| dd| dd }|rBd|||f S |dur|\}}dd	dd	d
| }||kr|d||||f S d|||f S |S )zZ
        Extract URL from the ASGI scope, without also including the querystring.
        schemeserverN	root_pathrf   rh   z	%s://%s%sP   i  )rJ   httpsr_   wssz%s://%s:%s%s)rM   )	r8   r>   Zdefault_schemer`   ri   rj   rh   portdefault_portr"   r"   r#   rc      s    zSentryAsgiMiddleware._get_urlc                 C   s$   | d}|sdS tj|dS )zj
        Extract querystring from the ASGI scope, in the format that the Sentry protocol expects.
        r^   Nlatin-1)rM   urllibparseunquotedecode)r8   r>   qsr"   r"   r#   rb     s    
zSentryAsgiMiddleware._get_queryc              	   C   sf   |  |}z|d dd  W S  ttfy8   Y n0 z
|d W S  tyV   Y n0 |dd S )zp
        Extract IP Address from the ASGI scope based on request headers with fallback to scope client.
        zx-forwarded-for,r   z	x-real-ipr   )rS   splitstripKeyError
IndexErrorrM   )r8   r>   r]   r"   r"   r#   rd     s    

zSentryAsgiMiddleware._get_ipc                 C   sT   i }|d D ]B\}}| d}| d}||v rF|| d | ||< q|||< q|S )zf
        Extract headers from the ASGI scope, in the format that the Sentry protocol expects.
        r]   rq   z, )ru   )r8   r>   r]   Zraw_keyZ	raw_valuekeyvaluer"   r"   r#   rS   )  s    


z!SentryAsgiMiddleware._get_headersN)Fr   r   )__name__
__module____qualname__	__slots__r9   r7   r6   rC   rR   re   rc   rb   rd   rS   r"   r"   r"   r#   r1   L   s      
%4 $
r1   )r   )(__doc__r+   r'   rr   Zsentry_sdk._functoolsr   Zsentry_sdk._typesr   Zsentry_sdk.hubr   r   Z$sentry_sdk.integrations._wsgi_commonr   Zsentry_sdk.sessionsr   Zsentry_sdk.tracingr   r	   Zsentry_sdk.utilsr
   r   r   r   r   r   typingr   r   r   r   Ztyping_extensionsr   r   r   rL   rU   r4   r$   r0   r1   r"   r"   r"   r#   <module>   s0   
