
    .h$                        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%j&        e#_'        e#j&        e%_&        n # e($ r e )                    d           Y nw xY wee*e+e,eef         Z-e	e-         Z.ee-         Z/ee/e.f         Z0 G d de          Z1dS )    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dS )SendTimeoutErrorN)__name__
__module____qualname__     N/var/www/FlaskApp/flask-venv/lib/python3.11/site-packages/sse_starlette/sse.pyr   r      s        Dr   r   c                   Z    e Zd ZU dZdZdZeej        df         e	d<   dZ
ed             ZdS )	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                                         t           j        t          j        | i | d S d S )NT)r!   should_exitr"   setoriginal_handler)argskwargss     r   handle_exitzAppStatus.handle_exit'   sW     !%	&2'++---%1&777777 21r   )r   r   r   __doc__r$   r"   r   anyioEvent__annotations__r&   staticmethodr)   r   r   r   r!   r!       s]         ffK26uU[$./6668 8 \8 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!dS )&EventSourceResponsezf
    Streaming response that sends data conforming to the SSE (Server-Sent Events) specification.
       
   Ntext/event-streamcontentstatus_codeheaders
media_type
backgroundpingsepping_message_factorydata_sender_callable)NNNsend_timeoutclient_close_handler_callablereturnc                 6   |dvrt          d|           |p| j        | _        t          |t                    r|| _        nt          |          | _        || _        || j        n|| _        || _	        |	| _
        |
| _        t                      }||                    |           |                    dd           d|d<   d|d<   |                     |           || j        n|| _        || _        || _        d	| _        t+          j                    | _        d S )
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   r7   r9   r:   r>   r?   r   update
setdefaultinit_headersDEFAULT_PING_INTERVALping_intervalr=   r@   activer+   Lock
_send_lock)selfr6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   _headerss                r   __init__zEventSourceResponse.__init__I   s9   & 000P3PPQQQ0$0 g}-- 	@!(D!6w!?!?D&-7-?$//Z$$8!( "##OOG$$$ 	OZ888!-(,$%(###;?<T77T$8!-J**,,r   c                     | j         S N)_ping_interval)rS   s    r   rO   z!EventSourceResponse.ping_interval   s    ""r   valuec                     t          |t          t          f          st          d          |dk     rt	          d          || _        d S )Nzping interval must be intr   z$ping interval must be greater than 0)rI   intfloat	TypeErrorrG   rX   )rS   rY   s     r   rO   z!EventSourceResponse.ping_interval   sM    %#u.. 	97888199CDDD#r   Fforcec                      t          d          )Nz-Compression is not supported for SSE streams.)NotImplementedError)rS   r^   s     r   enable_compressionz&EventSourceResponse.enable_compression   s    !"QRRRr   sendc                   K    |d| j         | j        d           d{V  | j        2 3 d{V }t          || j                  }t
                              d|           t          j        | j	                  5 } |d|dd           d{V  ddd           n# 1 swxY w Y   |rI|j
        rBt          | j        d          r| j                                         d{V  t                      6 | j        4 d{V  d	| _         |dd
d	d           d{V  ddd          d{V  dS # 1 d{V swxY w Y   dS )zHSend out SSE data to the client as it becomes available in the iterator.zhttp.response.start)typestatusr8   Nz	chunk: %shttp.response.bodyTrd   body	more_bodyacloseFr   )r7   raw_headersrJ   r   r<   loggerdebugr+   move_on_afterr?   cancel_calledhasattrrj   r   rR   rP   )rS   rb   datachunkcancel_scopes        r   _stream_responsez$EventSourceResponse._stream_response   s     d-*+ 
 
 	
 	
 	
 	
 	
 	
 	
 , 	) 	) 	) 	) 	) 	) 	)$ tx00ELLe,,,$T%677 <d15tTT                      
  ) : )4-x88 6,33555555555&((( - ? 	X 	X 	X 	X 	X 	X 	X 	XDK$ 4cPUVVWWWWWWWWW	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	Xs)   C29BB	"B	 D00
D:=D:receivec                    K   | j         rj |             d{V }|d         dk    rEd| _         t                              d           | j        r|                     |           d{V  dS | j         hdS dS )z/Watch for a disconnect message from the client.Nrd   zhttp.disconnectFz+Got event: http.disconnect. Stop streaming.)rP   rl   rm   r@   )rS   ru   messages      r   _listen_for_disconnectz*EventSourceResponse._listen_for_disconnect   s      k 	#GIIooooooGv"333#JKKK5 F<<WEEEEEEEEE k 	 	 	 	 	r   c                     K   t           j        rdS t           j        t          j                    t           _        t           j        rdS t           j                                         d{V  dS )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   sn         	F&.*/+--I'   	F)..00000000000r   c                   K   | j         rt          j        | j                   d{V  | j        r|                                 n4t          dt          j        t          j	                   | j
                  }t          || j
                  }t                              d|           | j        4 d{V  | j         r |d|dd           d{V  ddd          d{V  n# 1 d{V swxY w Y   | j         dS dS )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: %srf   Trg   )rP   r+   sleeprX   r=   r   r   nowr   utcr<   r   rl   rm   rR   )rS   rb   sse_ping
ping_bytess       r   _pingzEventSourceResponse._ping   s     
 k 	+d1222222222 ,))+++$Bhl8<&@&@BB    &h99JLLZ000        ; $$8$.)-                                    k 	 	 	 	 	s   6C%%
C/2C/scopec                    K   t          j                    4 d{V dt          g t          d         f         ffd}                    | fd                               | fd                               | j                    j        r                     j                    | fd           d{V  ddd          d{V  n# 1 d{V swxY w Y    j                                          d{V  dS dS )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                 ^   K    |              d {V  j                                          d S rW   )rs   cancel)r   
task_groups    r   cancel_on_finishz6EventSourceResponse.__call__.<locals>.cancel_on_finish   s9      dff'..00000r   c                  .                                    S rW   )rt   rS   rb   s   r   <lambda>z.EventSourceResponse.__call__.<locals>.<lambda>   s    D<Q<QRV<W<W r   c                  .                                    S rW   )r   r   s   r   r   z.EventSourceResponse.__call__.<locals>.<lambda>   s    DJJt<L<L r   c                  .                                    S rW   )rx   )ru   rS   s   r   r   z.EventSourceResponse.__call__.<locals>.<lambda>   s    4+F+Fw+O+O r   )r+   create_task_groupr   r   
start_soonr{   r>   r:   )rS   r   ru   rb   r   r   s   ` `` @r   __call__zEventSourceResponse.__call__   s      *,, 	Q 	Q 	Q 	Q 	Q 	Q 	Q
1Xb)D/6I-J 1 1 1 1 1 1 !!"24W4W4W4W4WXXX!!"24L4L4L4L4LMMM!!"2D4PQQQ( A%%d&?@@@ #"#O#O#O#O#OPPPPPPPPP	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q 	Q  ?&//########### '&s   B&C
C"%C")
r4   Nr5   NNNNNNN)F)rA   N)"r   r   r   r*   rN   rH   ContentStreamr[   r   r   strr   r   r   r	   r\   r   r   rU   propertyr   rO   setterboolra   r   rt   r   rx   r.   r{   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 # # # X# $5e#4 $ $ $ $ $S S S S S S SX4 XD X X X X6	G 	 	 	 	 	 1 1 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   rl   TimeoutErrorr   r!   uvicorn.mainr/   r)   r&   ImportErrorrm   r   bytesdictContentSyncContentStreamAsyncContentStreamr   r1   r   r   r   <module>r      ss    ' ' ' ' ' ' ' '
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  / / / / / / 7 7 7 7 7 7 3 3 3 3 3 3 ( ( ( ( ( ( 9 9 9 9 9 9 9 9 9 9 9 9 = = = = = = = = 
	8	$	$	 	 	 	 	| 	 	 	8 8 8 8 8 8 8 8"######!'!3I".F   
LLR    
 UD/36
7W% "7+ (*;;<}$ }$ }$ }$ }$( }$ }$ }$ }$ }$s   ?B B;:B;