o
    ٰi/                     @   s  d dl Z d dlZd dlZd dlZ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mZ d dlmZ erRd 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mZ d d
lmZ edZdZdZG dd dZz<d dlm Z  d dl!m"Z"m#Z#m$Z$ d dl%m&Z& dZ'dZ(dZ)dZ*dZ+e,dd ee-e+. e+/  D Z0G dd de Z1W n e2y   dZ&Y nw 						 d(d!d"Z3d)d&d'Z4dS )*    N)chainproduct)TYPE_CHECKING)Any)Callable)Dict)Optional)Self)loggerenv_to_boolcapture_internal_exceptions)Envelope	spotlightzhttp://localhost:8969/streamz(sentry_sdk.spotlight.SpotlightMiddlewarec                   @   s4   e Zd ZdZdZdZdeddfddZdddZdS )SpotlightClientaY  
    A client for sending envelopes to Sentry Spotlight.

    Implements exponential backoff retry logic per the SDK spec:
    - Logs error at least once when server is unreachable
    - Does not log for every failed envelope
    - Uses exponential backoff to avoid hammering an unavailable server
    - Never blocks normal Sentry operation
    g      ?g      N@urlreturnNc                 C   s"   || _ t | _| j| _d| _d S )N        )r   urllib3PoolManagerhttpINITIAL_RETRY_DELAY_retry_delay_last_error_time)selfr    r   H/home/ubuntu/.local/lib/python3.10/site-packages/sentry_sdk/spotlight.py__init__4   s   

zSpotlightClient.__init__enveloper   c              
   C   s   | j dkrt | j  }|| jk rd S t }|| z| jj| j|	 dddid}|
  | j| _d| _ W d S  tye } z t | _ t| jd | j| _td| j|| j W Y d }~d S d }~ww )	Nr   POSTContent-Typezapplication/x-sentry-envelope)r   bodymethodheadersr      zNFailed to send envelope to Spotlight at %s: %s. Will retry after %.1f seconds.)r   timer   ioBytesIOserialize_intor   requestr   getvaluecloser   	ExceptionminMAX_RETRY_DELAYsentry_loggerwarning)r   r   time_since_errorr    reqer   r   r   capture_envelope:   s8   



z SpotlightClient.capture_envelope)r   r   r   N)	__name__
__module____qualname____doc__r   r-   strr   r3   r   r   r   r   r   %   s    r   )MiddlewareMixin)HttpResponseServerErrorHttpResponseHttpRequest)settingsz/assets/main.jsz<script>window.__spotlight = {{ initOptions: {{ sidecarUrl: '{spotlight_url}', fullPage: false }} }};</script>
<script type="module" crossorigin src="{spotlight_js_url}"></script>
z<html><base href="{spotlight_url}">
<script>window.__spotlight = {{ initOptions: {{ fullPage: true, startFrom: "/errors/{event_id}" }}}};</script>
zcharset=r    c                 c   s     | ]}d  d|V  qdS )z</{}> N)formatjoin).0charsr   r   r   	<genexpr>q   s
    
rC   c                       sz   e Zd ZU dZded< dZded< d fd
dZedddZ									dddZ	ddddde
d	dfddZ  ZS )SpotlightMiddlewareNOptional[str]_spotlight_script_spotlight_urlr   r	   get_responseCallable[..., HttpResponse]r   c                    sT   t  | dd l}|j| _| j j}|d u rtd d S t	j
|jd| _d S )Nr   zPCannot find Spotlight client from SpotlightMiddleware, disabling the middleware.z../)superr   sentry_sdk.apiapi
sentry_sdk
get_clientr   r.   r/   urllibparseurljoinr   rG   )r   rH   rM   spotlight_client	__class__r   r   r   z   s   zSpotlightMiddleware.__init__c              
   C   s   | j d urL| jd u rLz#tj| j t}tjj|dd}tj| t	j
| j |d| _W | jS  tjjyK } ztjd||d W Y d }~| jS d }~ww | jS )NHEAD)r!   )spotlight_urlspotlight_js_urlzUCannot get Spotlight JS to inject at %s. SpotlightMiddleware will not be very useful.)exc_info)rG   rF   rO   rP   rQ   SPOTLIGHT_JS_ENTRY_PATHr(   RequesturlopenSPOTLIGHT_JS_SNIPPET_PATTERNr?   errorURLErrorr.   debug)r   rW   r1   errr   r   r   spotlight_script   s2   
z$SpotlightMiddleware.spotlight_script_requestr<   responser;   Optional[HttpResponse]c                    s   t dd jdd dD }|d }t|dkr/|d tr/|d ttd   nd | jd uryj	sy|d	krytj
}| j }td
d  fddtD D |}j
d | | j
|d   _
dry|t| jd< S )Nc                 s   s    | ]}|  V  qd S N)strip)rA   pr   r   r   rC      s
    
z7SpotlightMiddleware.process_response.<locals>.<genexpr>r   r>   ;r      utf-8z	text/htmlc                 s   s    | ]	}|d kr|V  qdS )Nr   )rA   idxr   r   r   rC      s    c                 3   s"    | ]}j | V  qd S re   )contentrfindencode)rA   body_variantencodingrc   r   r   rC      s
    
zContent-Length)tupler"   getlowersplitlen
startswithCHARSET_PREFIXra   	streamingrm   ro   nextBODY_CLOSE_TAG_POSSIBILITIES
has_header)r   rb   rc   content_type_headercontent_typecontent_length	injectioninjection_siter   rq   r   process_response   s@   


z$SpotlightMiddleware.process_response	exceptionz!Optional[HttpResponseServerError]c                 C   sn   t jr| jsd S ztj| j d}W n tjj	y"   Y d S w | j
|}t|dtj| j|dS )Nrj   z<html>)rV   event_id)r=   DEBUGrG   rO   r(   r[   readdecoder]   r^   rM   capture_exceptionr:   replaceSPOTLIGHT_ERROR_PAGE_SNIPPETr?   )r   rb   r   r   r   r   r   r   process_exception   s"   z%SpotlightMiddleware.process_exception)r   r	   rH   rI   r   N)r   r	   r   rE   )r   r	   rb   r<   rc   r;   r   rd   )r4   r5   r6   rF   __annotations__rG   r   propertyra   r   r+   r   __classcell__r   r   rS   r   rD   v   s0   
 
.rD   spotlight_configr   r.   r   rE   c                 C   s   t jd}d}d}|rt|dd}|du rd}|}n|}| du r*|r(|d dS | du r4|r2|S tS t| trH|rF|| krF|d| | | S | du rT|rP|S |rTtS dS )a  
    Resolve the Spotlight URL based on config and environment variable.

    Implements precedence rules per the SDK spec:
    https://develop.sentry.dev/sdk/expected-features/spotlight/

    Returns the resolved URL string, or None if Spotlight should be disabled.
    SENTRY_SPOTLIGHTNT)strictFzhSpotlight is disabled via spotlight=False config option, ignoring SENTRY_SPOTLIGHT environment variable.z`Spotlight URL from config (%s) takes precedence over SENTRY_SPOTLIGHT environment variable (%s).)osenvironrt   r   r/   DEFAULT_SPOTLIGHT_URL
isinstancer8   )r   r.   spotlight_env_valuespotlight_from_envspotlight_env_urlparsedr   r   r   _resolve_spotlight_url   sB   
r   optionsDict[str, Any]Optional[SpotlightClient]c                 C   s   t | dt}|d u rd S ttj}|td t	
| t	tj || d< t 8 td ur_tjr_ttjddr_ttjddr_tj}t|vr_t|t|tft_t	d W d    n1 siw   Y  t|}t	d| |S )Nr   z' [spotlight] %(levelname)s: %(message)sSENTRY_SPOTLIGHT_ON_ERROR1SENTRY_SPOTLIGHT_MIDDLEWAREz(Enabled Spotlight integration for Djangoz%Enabled Spotlight using sidecar at %s)r   rt   r.   loggingStreamHandlersysstderrsetFormatter	Formatterr
   
addHandlersetLevelINFOr   r=   r   r   r   r   
MIDDLEWARE DJANGO_SPOTLIGHT_MIDDLEWARE_PATHtyper   infor   )r   r   _handler
middlewareclientr   r   r   setup_spotlight+  s6   


r   )r   r   r.   r   r   rE   )r   r   r   r   )5r%   r   r   r$   urllib.parserO   urllib.requesturllib.errorr   r   	itertoolsr   r   typingr   r   r   r   r   r	   sentry_sdk.utilsr
   r.   r   r   sentry_sdk.enveloper   	getLoggerr   r   r   django.utils.deprecationr9   django.httpr:   r;   r<   django.confr=   rY   r\   r   ry   BODY_TAG_NAMErs   zipupperru   r|   rD   ImportErrorr   r   r   r   r   r   <module>   sb    
<r
?