o
    BDi4                     @   sL  d Z ddlZddlZddlmZ ddlmZ ddlZddlm	Z	 ddl
mZ ddlmZmZmZ ddlmZ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mZmZ ddl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Z0dS )ze
An ASGI middleware.

Based on Tom Christie's `sentry-asgi <https://github.com/encode/sentry-asgi>`.
    N)deepcopy)partial)continue_trace)OP)_get_headers_get_request_data_get_url)DEFAULT_HTTP_METHODS_TO_CAPTUREnullcontext)track_session)SOURCE_FOR_STYLETransactionSource)
ContextVarevent_from_exceptionHAS_REAL_CONTEXTVARSCONTEXTVARS_ERROR_MESSAGEloggertransaction_from_function_get_installed_modules)Transaction)TYPE_CHECKING)Any)Callable)Dict)Optional)Tuple)EventHintsentry_asgi_middleware_appliedzgeneric ASGI request)endpointurlasgic                 C   s0   t | t j|ddd\}}tj||d d S )NF)typehandled)client_options	mechanism)hint)r   
sentry_sdk
get_clientoptionscapture_event)excmechanism_typeeventr&    r.   U/var/www/Datamplify/venv/lib/python3.10/site-packages/sentry_sdk/integrations/asgi.py_capture_exception<   s   
r0   c                 C   s>   t | r
t| dS t | rt| S t| dd}t|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_asgi3G   s   




r<   c                   @   s\   e Zd ZdZddddef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:   r2   transaction_styler,   span_originhttp_methods_to_captureFr   r!   manualc                 C   s   |s
t s
tdt |tvrtd|tf |dkodt v }|r&td || _|| _	|| _
|| _|| _t|r?| j| _dS | 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)r!   	starlettezThe Sentry Python SDK can now automatically support ASGI frameworks like Starlette and FastAPI. Please remove 'SentryAsgiMiddleware' from your project. See https://docs.sentry.io/platforms/python/guides/asgi/ for more information.N)r   RuntimeErrorr   TRANSACTION_STYLE_VALUES
ValueErrorr   r   warningr>   r,   r?   r:   r@   r<   
_run_asgi3r2   
_run_asgi2)selfr:   unsafe_context_datar>   r,   r?   r@   0asgi_middleware_while_using_starlette_or_fastapir.   r.   r/   __init__a   s4   zSentryAsgiMiddleware.__init__c                 C      t || jdS )zCapture exceptions raise in application lifespan handlers.

        The separate function is needed to support overriding in derived integrations that use different catching mechanisms.
        r+   r,   r0   r,   rI   r+   r.   r.   r/   _capture_lifespan_exception      z0SentryAsgiMiddleware._capture_lifespan_exceptionc                 C   rM   )zCapture exceptions raised in incoming request handlers.

        The separate function is needed to support overriding in derived integrations that use different catching mechanisms.
        rN   rO   rP   r.   r.   r/   _capture_request_exception   rR   z/SentryAsgiMiddleware._capture_request_exceptionc                    s    fdd}|S )Nc                    s   j  | |ddI d H S )N   asgi_version_run_app)receivesendscoperI   r.   r/   inner      z.SentryAsgiMiddleware._run_asgi2.<locals>.innerr.   )rI   r\   r]   r.   r[   r/   rH      s   zSentryAsgiMiddleware._run_asgi2c                    s   | j |||ddI d H S )N   rU   rW   )rI   r\   rY   rZ   r.   r.   r/   rG      r^   zSentryAsgiMiddleware._run_asgi3c                    s  t d}|d dk}|s|r@z|dkr!| || I d H W S | || I d H W S  ty? } z| | |d d }~ww t d z;t }t|dd |	  d|_
t| j|d	}	||	 |d }
| | j|\}}|d
d }d |
dv r|
dks|| jv rtt|d|
||| jdtd nttj||| jdtd rÈd|
 tdjj d urtjd|idnt v td zY fdd}|dkr| |||I d H W W  d    W  d    W  d    W t d S | |||I d H W W  d    W  d    W  d    W t d S  tyH } z|  | |d d }~ww 1 sMw   Y  W d    n	1 s]w   Y  W d    n1 smw   Y  W t d d S W t d d S t d w )NFr"   lifespanrT   Trequest)session_moder!   )
asgi_scopemethod )http	websocketrg   z	{}.server)opnamesourceoriginz1[ASGI] Created transaction (continuing trace): %sz$[ASGI] Created transaction (new): %sz	asgi.typezB[ASGI] Set transaction name and source on transaction: '%s' / '%s'rc   )custom_sampling_contextz[ASGI] Started transaction: %sc                    s@   d ur|  ddkod| v }|r| d   | I d H S )Nr"   zhttp.response.startstatus)getset_http_status)r-   is_http_responserZ   transactionr.   r/   _sentry_wrapped_send   s   z;SentryAsgiMiddleware._run_app.<locals>._sentry_wrapped_send)!_asgi_middleware_appliedrn   r:   	ExceptionrQ   setr'   isolation_scoper   clear_breadcrumbs_namer   event_processoradd_event_processor _get_transaction_name_and_sourcer>   upperr@   r   r   formatr?   r   debugr   r   HTTP_SERVERset_tagri   rj   start_transactionr
   rS   )rI   r\   rY   rZ   rV   is_recursive_asgi_middlewareis_lifespanr+   sentry_scope	processortytransaction_nametransaction_sourcerd   rs   r.   rq   r/   rX      s   





U
U
 UUzSentryAsgiMiddleware._run_appc           
      C   s   | di }|t| t||d< | d}| dpi  d}|d uo3|tko3|tjtjtjfv }|sV| 	| j
|\}}	||d< d|	i|d< td|d |d d  |S )Nra   rr   transaction_inforj   zF[ASGI] Set transaction name and source in event_processor: '%s' / '%s')rn   updater   r   _DEFAULT_TRANSACTION_NAMEr   	COMPONENTROUTECUSTOMr|   r>   r   r   )
rI   r-   r&   rc   request_datarr   r   already_setri   rj   r.   r.   r/   rz     s6   


z$SentryAsgiMiddleware.event_processorc           	      C   s   d }t | }|d}|dkr.|d}|rt|pd}n9t||dkr%dndd d}tj}n(|dkrV|d}|rFt|d	d }|d urE|}nt||dkrNdndd d}tj}|d u rct}tj}||fS ||fS )
Nr"   r   re   rf   ws)hostr    routepath)	r   rn   r   r   r   URLr9   r   r   )	rI   r>   rc   ri   rj   r   r   r   r   r.   r.   r/   r|   @  s.   


z5SentryAsgiMiddleware._get_transaction_name_and_sourceN)__name__
__module____qualname__	__slots__r	   rL   rQ   rS   rH   rG   rX   rz   r|   r.   r.   r.   r/   r=   W   s    
3h(r=   )r!   )1__doc__r7   r3   copyr   	functoolsr   r'   sentry_sdk.apir   sentry_sdk.constsr   $sentry_sdk.integrations._asgi_commonr   r   r   $sentry_sdk.integrations._wsgi_commonr	   r
   sentry_sdk.sessionsr   sentry_sdk.tracingr   r   sentry_sdk.utilsr   r   r   r   r   r   r   r   typingr   r   r   r   r   r   sentry_sdk._typesr   r   rt   r   rD   r0   r<   r=   r.   r.   r.   r/   <module>   s8    $	
