
    UhQ'                     <   U 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 d dl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mZ d d	lmZmZ  ej>                  e       Z! e jD                  d
d      Z#e jD                  eejH                        e%d<    G d de&      Z' G d d      Z(	 d dl)m*Z* e*jV                  e(_,        e(jV                  e*_+        ee/e0e1eef   Z2e
e2   Z3ee2   Z4ee4e3f   Z5 G d de      Z6y# e-$ r e!j]                  d       Y ?w xY w)    N)datetimetimezone)	AnyAsyncIterable	AwaitableCallable	CoroutineIteratorMappingOptionalUnion)BackgroundTask)iterate_in_threadpool)MutableHeaders)Response)ReceiveScopeSendMessage)ServerSentEventensure_bytes
exit_event)default_exit_event_contextc                       e Zd Zy)SendTimeoutErrorN)__name__
__module____qualname__     R/var/www/html/hubwallet-dev/venv/lib/python3.12/site-packages/sse_starlette/sse.pyr   r   "   s    r!   r   c                   d    e Zd ZU dZdZdZee   ed<   e	d        Z
e	dej                  fd       Zy)	AppStatusz\Helper to capture a shutdown signal from Uvicorn so we can gracefully terminate SSE streams.FNoriginal_handlerc                      dt         _        t        j                  d       }||j	                          t         j
                  t        j
                  | i | y y )NT)r$   should_exitr   getsetr%   )argskwargscurrent_events      r"   handle_exitzAppStatus.handle_exit,   sT     !%	 ,//5$%%1&&77 2r!   returnc                      t         j                  d      } | )t        j                         } t         j	                  |        | S )z4Get or create an exit event for the current context.N)r   r(   anyioEventr)   )events    r"   get_or_create_exit_eventz"AppStatus.get_or_create_exit_event9   s7     $''-=KKME##E*r!   )r   r   r   __doc__r'   r%   r   r   __annotations__staticmethodr-   r0   r1   r3   r    r!   r"   r$   r$   &   sK    fK+/hx(/
8 
8 ekk  r!   r$   )ServerzHUvicorn not installed. Graceful shutdown on server termination disabled.c                      e Zd ZdZdZdZ	 	 	 	 	 	 	 	 	 	 d dededee	e
e
f      de
d	ee   d
ee   dee
   deeg ef      deeg ed   f      dee   deeeged   f      ddfdZedeeef   fd       Zej,                  deeef   ddfd       Zd!deddfdZdeddfdZdeddfdZed"d       ZdeddfdZde dededdfdZ!y)#EventSourceResponsezf
    Streaming response that sends data conforming to the SSE (Server-Sent Events) specification.
       
Ncontentstatus_codeheaders
media_type
backgroundpingsepping_message_factorydata_sender_callable)NNNsend_timeoutclient_close_handler_callabler.   c                    |dvrt        d|       |xs | j                  | _        t        |t              r|| _        nt        |      | _        || _        || j                  n|| _        || _	        |	| _
        |
| _        t               }||j                  |       |j                  dd       d|d<   d|d<   | j                  |       || j                   n|| _        || _        || _        d	| _        t+        j,                         | _        y )
N)Nr;   
z'sep must be one of: \r\n, \r, \n, got: zCache-Controlzno-storez
keep-alive
ConnectionnozX-Accel-BufferingT)
ValueErrorDEFAULT_SEPARATORrB   
isinstancer   body_iteratorr   r=   r?   r@   rD   rE   r   update
setdefaultinit_headersDEFAULT_PING_INTERVALping_intervalrC   rF   activer0   Lock
_send_lock)selfr<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   _headerss                r"   __init__zEventSourceResponse.__init__[   s   & 00J3%PQQ0$00 g}-!(D!6w!?D&-7-?$//Z$$8!( "#OOG$ 	OZ8!-(,$%(#;?<T77T$8!-J***,r!   c                     | j                   S N)_ping_interval)rX   s    r"   rT   z!EventSourceResponse.ping_interval   s    """r!   valuec                 t    t        |t        t        f      st        d      |dk  rt	        d      || _        y )Nzping interval must be intr   z$ping interval must be greater than 0)rN   intfloat	TypeErrorrL   r]   )rX   r^   s     r"   rT   z!EventSourceResponse.ping_interval   s7    %#u.78819CDD#r!   forcec                     t        d      )Nz-Compression is not supported for SSE streams.)NotImplementedError)rX   rc   s     r"   enable_compressionz&EventSourceResponse.enable_compression   s    !"QRRr!   sendc                   K    |d| j                   | j                  d       d{    | j                  2 3 d{   }t        || j                        }t
        j                  d|       t        j                  | j                        5 } |d|dd       d{    ddd       st|j                  st        | j                  d      r"| j                  j                          d{    t               7 7 7 b# 1 sw Y   axY w7  6 | j                  4 d{  7   d	| _         |dd
d	d       d{  7   ddd      d{  7   y# 1 d{  7  sw Y   yxY ww)zHSend out SSE data to the client as it becomes available in the iterator.zhttp.response.start)typestatusr>   Nz	chunk: %shttp.response.bodyTri   body	more_bodyacloseFr!   )r=   raw_headersrO   r   rB   loggerdebugr0   move_on_afterrE   cancel_calledhasattrro   r   rW   rU   )rX   rg   datachunkcancel_scopes        r"   _stream_responsez$EventSourceResponse._stream_response   sZ    -**++
 	
 	
 ,, 	) 	)$ txx0ELLe,$$T%6%67 <15tT  
  : :4--x8,,33555&(('	
	)  6 - ?? 	X 	XDK 4cPUVWWW	X 	X 	X 	X 	Xs   $E(C:E(DC<DAE(D C>D  
E(+E(83E(+D,E(<D>D  D		E(E(D" E($E;D><EE(EE(E%EE%!E(receivec                    K   | j                   rg |        d{   }|d   dk(  rBd| _         t        j                  d       | j                  r| j                  |       d{    y| j                   rfyy7 ]7 w)z/Watch for a disconnect message from the client.Nri   zhttp.disconnectFz+Got event: http.disconnect. Stop streaming.)rU   rq   rr   rF   )rX   rz   messages      r"   _listen_for_disconnectz*EventSourceResponse._listen_for_disconnect   sj     kk#IoGv"33#JK55<<WEEE kk%
 Fs(   A;A7AA;"A9#A;5A;9A;c                     K   t         j                  ryt         j                         } t         j                  ry| j                          d{    y7 w)zQWatch for shutdown signals (e.g. SIGINT, SIGTERM) so we can break the event loop.N)r$   r'   r3   wait)r   s    r"   _listen_for_exit_signalz+EventSourceResponse._listen_for_exit_signal   sB         779
   oos   A
AAAc                 X  K   | j                   rt        j                  | j                         d{    | j                  r| j	                         n:t        dt        j                  t        j                         | j                        }t        || j                        }t        j                  d|       | j                  4 d{    | j                   r |d|dd       d{    ddd      d{    | j                   ryy7 7 E7 '7 # 1 d{  7  sw Y   )xY ww)zPeriodically send ping messages to keep the connection alive on proxies.
        - frequenccy ca every 15 seconds.
        - Alternatively one can send periodically a comment line (one starting with a ':' character)
        Nzping - )commentrB   zping: %srk   Trl   )rU   r0   sleepr]   rC   r   r   nowr   utcrB   r   rq   rr   rW   )rX   rg   sse_ping
ping_bytess       r"   _pingzEventSourceResponse._ping   s     
 kk++d11222 ,, ))+$%hll8<<&@%AB  &h9JLLZ0  ;;$8$.)-    kk2   sp   /D*DBD*	D
D*D)D*D.D*9D:D*D*D*DD*D'DD'#D*scopec                 (   K   t        j                         4 d{   dt        g t        d   f   ffd}j	                  | fd       j	                  | fd       j	                  | j
                          j                  rj	                   j                         j	                  | fd       ddd      d{     j                   j                          d{    yy7 7 ,# 1 d{  7  sw Y   <xY w7 w)a  Entrypoint for Starlette's ASGI contract. We spin up tasks:
        - _stream_response to push events
        - _ping to keep the connection alive
        - _listen_for_exit_signal to respond to server shutdown
        - _listen_for_disconnect to respond to client disconnect
        Ncoroc                 d   K    |         d {    j                   j                          y 7 wr\   )rx   cancel)r   
task_groups    r"   cancel_on_finishz6EventSourceResponse.__call__.<locals>.cancel_on_finish  s'     f''..0 s   0. 0c                  &     j                        S r\   )ry   rX   rg   s   r"   <lambda>z.EventSourceResponse.__call__.<locals>.<lambda>  s    D<Q<QRV<W r!   c                  &     j                        S r\   )r   r   s   r"   r   z.EventSourceResponse.__call__.<locals>.<lambda>  s    DJJt<L r!   c                  &    j                         S r\   )r}   )rz   rX   s   r"   r   z.EventSourceResponse.__call__.<locals>.<lambda>  s    $*E*Eg*N r!   )r0   create_task_groupr   r   
start_soonr   rD   r@   )rX   r   rz   rg   r   r   s   ` `` @r"   __call__zEventSourceResponse.__call__   s      **, 	 	
1Xb)D/6I-J 1 !!"24WX!!"24LM!!"2D4P4PQ((%%d&?&?@ !! "N	 	$ ??&//### '%	 	 	 	 	& $sQ   DC7DBC;DC9#D0D1D9D;DDD	D)
   Nztext/event-streamNNNNNNN)F)r.   N)"r   r   r   r4   rS   rM   ContentStreamr`   r   r   strr   r   r   r	   ra   r   r   rZ   propertyr   rT   setterboolrf   r   ry   r   r}   r6   r   r   r   r   r    r!   r"   r9   r9   S   s    
 /3-/3"!HL (, !;';' ;' '#s(+,	;'
 ;' ^,;' sm;' c];' 'xO0C'DE;' 'R#3445
;' uo;' (0gY	$/0(
;'" 
#;'z #uS%Z0 # # $5e#4 $ $ $S S SX4 XD X6	G 	 	      6$E $G $4 $D $r!   r9   )7contextvarsloggingr   r   typingr   r   r   r   r	   r
   r   r   r   r0   starlette.backgroundr   starlette.concurrencyr   starlette.datastructuresr   starlette.responsesr   starlette.typesr   r   r   r   sse_starlette.eventr   r   	getLoggerr   rq   
ContextVarr   r1   r5   TimeoutErrorr   r$   uvicorn.mainr7   r-   r%   ImportErrorrr   r   bytesdictContentSyncContentStreamAsyncContentStreamr   r9   r    r!   r"   <module>r      s%     '
 
 
  / 7 3 ( 9 9 = 
		8	$ K<6 [++HU[[,AB 
	| 	 :#!'!3!3I"..F UD/36
7W% "7+ (*;;<$( $  
LLRs   3(D DD