
    kh"%                        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  G d
 de!      Z" G d d      Z#	 d dl$m%Z% e%jL                  e#_'        e#jL                  e%_&        ee*e+e,eef   Z-e	e-   Z.ee-   Z/ee/e.f   Z0 G d de      Z1y# e($ r e jS                  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_bytesc                       e Zd Zy)SendTimeoutErrorN)__name__
__module____qualname__     M/opt/mcp/mcp-sentiment/venv/lib/python3.12/site-packages/sse_starlette/sse.pyr   r      s    r   r   c                   V    e Zd ZU dZdZdZeej                  df   e	d<   dZ
ed        Zy)	AppStatusz\Helper to capture a shutdown signal from Uvicorn so we can gracefully terminate SSE streams.FNshould_exit_eventc                      dt         _        t         j                  t         j                  j                          t         j                  t        j                  | i | y y )NT)r!   should_exitr"   setoriginal_handler)argskwargss     r   handle_exitzAppStatus.handle_exit'   sN     !%	&&2''++-%%1&&77 2r   )r   r   r   __doc__r$   r"   r   anyioEvent__annotations__r&   staticmethodr)   r   r   r   r!   r!       s;    fK26uU[[$./68 8r   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_callablereturnc                    |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)Nr3   
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_SEPARATORr:   
isinstancer   body_iteratorr   r5   r7   r8   r<   r=   r   update
setdefaultinit_headersDEFAULT_PING_INTERVALping_intervalr;   r>   activer+   Lock
_send_lock)selfr4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   _headerss                r   __init__zEventSourceResponse.__init__I   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)rQ   s    r   rM   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)rG   intfloat	TypeErrorrE   rV   )rQ   rW   s     r   rM   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)rQ   r\   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statusr6   Nz	chunk: %shttp.response.bodyTrb   body	more_bodyacloseFr   )r5   raw_headersrH   r   r:   loggerdebugr+   move_on_afterr=   cancel_calledhasattrrh   r   rP   rN   )rQ   r`   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.Nrb   zhttp.disconnectFz+Got event: http.disconnect. Stop streaming.)rN   rj   rk   r>   )rQ   rs   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                         t         _        t         j                  ryt         j                  j                          d{    y7 w)zQWatch for shutdown signals (e.g. SIGINT, SIGTERM) so we can break the event loop.N)r!   r$   r"   r+   r,   waitr   r   r   _listen_for_exit_signalz+EventSourceResponse._listen_for_exit_signal   sT        &&.*/++-I'   ))..000s   A1A;3A94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 - )commentr:   zping: %srd   Tre   )rN   r+   sleeprV   r;   r   r   nowr   utcr:   r   rj   rk   rP   )rQ   r`   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rU   )rq   cancel)r   
task_groups    r   cancel_on_finishz6EventSourceResponse.__call__.<locals>.cancel_on_finish   s'     f''..0 s   0. 0c                  &     j                        S rU   )rr   rQ   r`   s   r   <lambda>z.EventSourceResponse.__call__.<locals>.<lambda>   s    D<Q<QRV<W r   c                  &     j                        S rU   )r   r   s   r   r   z.EventSourceResponse.__call__.<locals>.<lambda>   s    DJJt<L r   c                  &    j                         S rU   )rv   )rs   rQ   s   r   r   z.EventSourceResponse.__call__.<locals>.<lambda>   s    $*E*Eg*N r   )r+   create_task_groupr   r   
start_soonry   r<   r8   )rQ   r   rs   r`   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   r*   rL   rF   ContentStreamrY   r   r   strr   r   r   r	   rZ   r   r   rS   propertyr   rM   setterboolr_   r   rr   r   rv   r.   ry   r   r   r   r   r   r   r1   r1   A   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 	 	 1 1  6$E $G $4 $D $r   r1   )2loggingr   r   typingr   r   r   r   r	   r
   r   r   r   r+   starlette.backgroundr   starlette.concurrencyr   starlette.datastructuresr   starlette.responsesr   starlette.typesr   r   r   r   sse_starlette.eventr   r   	getLoggerr   rj   TimeoutErrorr   r!   uvicorn.mainr/   r)   r&   ImportErrorrk   r   bytesdictContentSyncContentStreamAsyncContentStreamr   r1   r   r   r   <module>r      s     '
 
 
  / 7 3 ( 9 9 = 
		8	$	| 	8 8"#!'!3!3I"..F UD/36
7W% "7+ (*;;<$( $  
LLRs   ;(C
 
C#"C#