+
    Ni/              
          ^ RI t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
HtHt ^ RIHt ]'       d   ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ R	IHtHtHt ^ R
IHt ]P6                  ! R4      tRtRt ! R R4      t ^ RIH t  ^ RI!H"t"H#t#H$t$ ^ RI%H&t& Rt'Rt(Rt)Rt*Rt+],;QJ d;    . R ]! ]-! ]+P]                  4       ]+P_                  4       4      !   4       F  NK  	  5M4! R ]! ]-! ]+P]                  4       ]+P_                  4       4      !   4       4      t0 ! R R] 4      t1R R lt3R R lt4R#   ]2 d    Rt& Li ; i)    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                   P   a  ] tR t^%t o RtRtRtV 3R lR ltV 3R lR ltRt	V t
R	# )
SpotlightClienta=  
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@c                $   < V ^8  d   QhRS[ RR/# )   urlreturnN)str)format__classdict__s   ";/tmp/pip-target-e6j6ikcs/lib/python/sentry_sdk/spotlight.py__annotate__SpotlightClient.__annotate__4   s     + +C +D +    c                v    Wn         \        P                  ! 4       V n        V P                  V n        R V n        R# )        N)r   urllib3PoolManagerhttpINITIAL_RETRY_DELAY_retry_delay_last_error_time)selfr   s   &&r   __init__SpotlightClient.__init__4   s-    '')	 44'*r   c                "   < V ^8  d   QhRRRR/# )r   enveloper   r   N )r   r   s   "r   r   r   :   s     $ $ $ $r   c                   V P                   ^ 8  d9   \        P                  ! 4       V P                   ,
          pW P                  8  d   R# \        P                  ! 4       pVP                  V4        V P                  P                  V P                  VP                  4       RRR/R7      pVP                  4        V P                  V n        RV n         R#   \         d   p\        P                  ! 4       T n         \        T P                  ^,          T P                  4      T n        \        P                   ! RT P                  TT P                  4        Rp?R# Rp?ii ; i)r   N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es   &&    r   capture_envelope SpotlightClient.capture_envelope:   s     1$#yy{T-B-BB"3"33zz|%	))##HH]]_"$C	 $ C IIK $ 8 8D$'D! 	$(IIKD! !$D$5$5$94;O;O PD !!1!! 	s   1A!C EA3EE)r$   r#   r!   r   N)__name__
__module____qualname____firstlineno____doc__r"   r:   r&   r@   __static_attributes____classdictcell__)r   s   @r   r   r   %   s+      O+ +$ $r   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              #   b   "   T F%  pR P                  RP                  V4      4      x  K'  	  R# 5i)z</{}> N)r   join).0charss   & r   	<genexpr>rS   q   s+      )PE 	rwwu~&&Ps   -/c                      a a ] tR t^vt oRtRtV3R lV 3R llt]V3R lR l4       tV3R lR lt	V3R lR	 lt
V3R
 ltRtVtV ;t# )SpotlightMiddlewareNc                &   < V ^8  d   QhRRRRRR/# )r   r%   r
   get_responsezCallable[..., HttpResponse]r   Nr*   )r   r   s   "r   r    SpotlightMiddleware.__annotate__z   s)     	T 	T6 	T1N 	TSW 	Tr   c                .  < \         SV `  V4       ^ RIpVP                  V n        V P                  P                  4       P                  pVf   \        P                  ! R4       R# \        P                  P                  VP                  R4      V n        R# )r   NzPCannot find Spotlight client from SpotlightMiddleware, disabling the middleware.z../)superr&   sentry_sdk.apiapi
sentry_sdk
get_clientr   r;   r<   urllibparseurljoinr   _spotlight_url)r%   rW   r]   spotlight_client	__class__s   &&  r   r&   SpotlightMiddleware.__init__z   ss    G\*!(nnDO#99;EE'%%f "(,,"6"67G7K7KU"SDr   c                "   < V ^8  d   QhRRRR/# )r   r%   r
   r   Optional[str]r*   )r   r   s   "r   r   rX      s     	* 	*6 	*o 	*r   c                4   V P                   e   V P                  f    \        P                  P	                  V P                   \
        4      p\        P                  P                  VRR7      p\        P                  P                  V4       \        P                  V P                   VR7      V n        V P                  # V P                  #   \        P                  P                   d/   p\        P                  ! RXTR7        R p?T P                  # R p?ii ; i)NHEAD)r/   )spotlight_urlspotlight_js_urlzUCannot get Spotlight JS to inject at %s. SpotlightMiddleware will not be very useful.)exc_info)rb   _spotlight_scriptr_   r`   ra   SPOTLIGHT_JS_ENTRY_PATHr5   RequesturlopenSPOTLIGHT_JS_SNIPPET_PATTERNr   errorURLErrorr;   debug)r%   rk   r>   errs   &   r   spotlight_script$SpotlightMiddleware.spotlight_script   s    "".43I3I3Q'-||';';++-D($ !..00(% 1 C NN**3/-I-P-P&*&9&9)9 .Q .D* )))4))) ||,, !''o(!$  )))s   BC
 
D)DDc                *   < V ^8  d   QhRRRRRRRR/# )	r   r%   r
   _requestrL   responserK   r   zOptional[HttpResponse]r*   )r   r   s   "r   r   rX      s-     ,	 ,	,	$1,	=K,	%,	r   c                  aa \         ;QJ dK    . R  SP                  P                  RR4      P                  4       P	                  R4       4       F  NK  	  5MD! R  SP                  P                  RR4      P                  4       P	                  R4       4       4      pV^ ,          p\        V4      ^8  d=   V^,          P                  \        4      '       d   V^,          \        \        4      R oMRoV P                  e   SP                  '       g   VR8X  d   \        SP                  4      pV P                  P                  S4      p\        R VV3R l\         4        4       V4      pSP                  RV V,           SP                  VR ,           Sn
        SP                  R	4      '       d    V\        V4      ,           SP                  R	&   S# )
c              3   B   "   T F  pVP                  4       x  K  	  R # 5iN)strip)rQ   ps   & r   rS   7SpotlightMiddleware.process_response.<locals>.<genexpr>   s      (TA 		Ts   r-   rO   ;Nutf-8z	text/htmlc              3   8   "   T F  pVR8  g   K  Vx  K  	  R# 5i)   Nr*   )rQ   idxs   & r   rS   r      s&      $C 8 $s   	
c              3   x   <"   T F/  pSP                   P                  VP                  S4      4      x  K1  	  R # 5ir}   )contentrfindencode)rQ   body_variantencodingrz   s   & r   rS   r      s7      $0L %,,22<3F3Fx3PQQ0Ls   7:zContent-Length)tupler0   getlowersplitlen
startswithCHARSET_PREFIXrv   	streamingr   r   nextBODY_CLOSE_TAG_POSSIBILITIES
has_header)	r%   ry   rz   content_type_headercontent_typecontent_length	injectioninjection_siter   s	   &&f     @r   process_response$SpotlightMiddleware.process_response   s    #(% (!))--nbAGGIOOPST(%% (!))--nbAGGIOOPST( # /q1L&'!+0CA0F0Q0Q1 1 /q1#n2E2GH" %%1 *** K/!$X%5%5!6 1188B	!%$0L$ #
" $$_n5 &&~78   &&'7889G#i.9XH$$%56Or   c                ,   < V ^8  d   QhRRRRRS[ RR/# )r   r%   r
   ry   rL   	exceptionr   z!Optional[HttpResponseServerError])r8   )r   r   s   "r   r   rX      s-     	 		$1	>G	0	r   c           
        \         P                  '       d   V P                  '       g   R #  \        P                  P                  V P                  4      P                  4       P                  R4      pV P                  P                  V4      p\        VP                  R\        P                  V P                  VR7      4      4      #   \        P                  P                   d     R # i ; i)Nr   z<html>)rj   event_id)rM   DEBUGrb   r_   r5   rp   readdecoder]   capture_exceptionrJ   replaceSPOTLIGHT_ERROR_PAGE_SNIPPETr   rr   rs   )r%   ry   r   r   r   s   &&&  r   process_exception%SpotlightMiddleware.process_exception   s     >>>)<)<)<NN**4+>+>?DDFMMgV   ??<<YG.%% 4;;*.*=*= <  	 <<(( s   AC C*)C*c                .   < V ^8  d   Qh/ R;R&   R;R&   # )r   rg   rm   rb   r*   )r   r   s   "r   r   rX   v   s     *1 '. r   )rm   rb   r]   )rB   rC   rD   rE   rm   rb   r&   propertyrv   r   r   __annotate_func__rG   rH   __classcell__)rd   r   s   @@r   rU   rU   v   sM     -1*.	T 	T  
	* 
	*0,	 ,	\	 	w  r   rU   c                $    V ^8  d   QhRRRRRR/# )r   spotlight_configr   r;   r   rg   r*   )r   s   "r   r   r      s$     < <<,1<<r   c                   \         P                  P                  R4      pRpRpV'       d   \        VRR7      pVf   RpTpMTpV RJ d   V'       d   VP                  ! R4       R# V RJ d   V'       d   V# \
        # \        V \        4      '       d%   V'       d   W 8w  d   VP                  ! RV V4       V # V f   V'       d   V# V'       d   \
        # R# )z
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environr   r   r<   DEFAULT_SPOTLIGHT_URL
isinstancer   )r   r;   spotlight_env_valuespotlight_from_envspotlight_env_urlparseds   &&    r   _resolve_spotlight_urlr      s     **..);< ,0)-0>>!% 3!' 5 !!B 	T	! $$((	$c	*	*#6#J!!> #	  		!$$(( r   c                     V ^8  d   QhRRRR/# )r   optionszDict[str, Any]r   zOptional[SpotlightClient]r*   )r   s   "r   r   r   +  s        -  2M  r   c                    \        V P                  R 4      \        4      pVf   R# \        P                  ! \
        P                  4      pVP                  \        P                  ! R4      4       \        P                  V4       \        P                  \        P                  4       WR &   \        4       ;_uu_ 4        \        e   \        P                  '       d   \!        \"        P$                  P                  RR4      4      '       d   \!        \"        P$                  P                  RR4      4      '       dZ   \        P&                  p\(        V9  d?   \+        V4      ! \-        V\(        34      4      \        n        \        P/                  R4       RRR4       \1        V4      p\        P/                  RV4       V#   + '       g   i     L3; i)r   Nz' [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   r   r;   loggingStreamHandlersysstderrsetFormatter	Formatterr   
addHandlersetLevelINFOr   rM   r   r   r   r   
MIDDLEWARE DJANGO_SPOTLIGHT_MIDDLEWARE_PATHtyper   infor   )r   r   _handler
middlewareclients   &    r   setup_spotlightr   +  s5   
 [!9=
IC
{ $$SZZ0H'++,UVW
h
OOGLL! K	$	&	& BJJNN+FLMMBJJNN+H#NOO!,,J/zA&*:&6*'G&IJ'# FG 
' S!F
KK7=M# 
'	&s   =F>B7F>>G	)5r2   r   r   r1   urllib.parser_   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.deprecationrI   django.httprJ   rK   rL   django.confrM   rn   rq   r   r   BODY_TAG_NAMEr   zipupperr   r   rU   ImportErrorr   r   r*   r   r   <module>r      sD   	  	      
 $   
 ) 
		;	' 7 #M  9 9xH8NN$/	Q !
	{ !  NM#(5 )c-"5"5"79L9L9NOP)55 )c-"5"5"79L9L9NOP) $ 
po pl<~ G  Hs   
&D9 1A:D9 9	EE