o
    e~#g                     @  s  d dl m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
Z
d dlZd dlZd dlmZ d dlmZmZ d dlmZmZmZ d dlmZ d dlmZ d dlmZ d d	lmZmZ d d
lm Z m!Z!m"Z"m#Z#m$Z$ d dl%m&Z& d dl'Z'd dl(Z(d dl)m*Z+ d dl,Z,d dl-Z-d dl.m/Z/ d dl0m1Z1 d dl2m3Z3m4Z4m5Z5m6Z6 d dl7m8Z8m9Z9 d dl:m;Z;m<Z< d dl=m>Z>m?Z?m@Z@mAZAmBZB d dlCmDZDm*Z* d dlEmFZFmGZGmHZHmIZI d dlJmKZK d dlLmMZM e rd dlNmOZOmPZP d dlQmRZR d dlSmTZT eU ZVdZWG dd dZXe/ G dd dZYG dd deZZ[dd(d)Z\dd0d1Z]dd4d5Z^dd7d8Z_dd=d>Z`ddAdBZaddFdGZbG dHdI dIe6ZcedJdKG dLdM dMZdeG dNdO dOZeG dPdQ dQeZZfG dRdS dSeZZgG dTdU dUZhG dVdW dWZidd\d]ZjddadbZkddedfZlddjdkZmddmdnZnddpdqZoG drds dsZpddvdwZqddzd{Zre	|ddd~dZsdddZtedddZu	|	|ddddZvG dd dZwdS )    )annotationsN)deque)AsyncGeneratorCallable)AbstractAsyncContextManagerAsyncExitStackasynccontextmanager)	dataclass)datetime)Path)NamedTemporaryFile_TemporaryFileWrapper)TYPE_CHECKINGAnyBinaryIOOptionalUnion)urlparse)document)parse_options_header)FormDataHeadersMutableHeaders
UploadFile)MultiPartExceptionMultipartPart)PlainTextResponseResponse)ASGIAppMessageReceiveScopeSend)processing_utilsutils)BlocksConfigDictMediaStreamChunkPredictBodyPredictBodyInternal)Error)SessionState)BlockFunctionBlocks	EventData)Appz/gradio_apic                   @  sz   e Zd ZdZdd Zdd Zdd Zdd	 ZdddZdddZ	dd Z
dd Zdd Zd ddZd ddZdddZdS )!Objz
    Using a class to convert dictionaries into objects. Used by the `Request` class.
    Credit: https://www.geeksforgeeks.org/convert-nested-python-dictionary-to-object/
    c                 C  sD   | j | | D ]\}}t|ttfrt|}t| || q
d S N)__dict__updateitems
isinstancedictlistr0   setattr)selfdict_keyvalue r=   w/var/www/static.ux5.de/https/Moving-Object-Detection-with-OpenCV/env/lib/python3.10/site-packages/gradio/route_utils.py__init__D   s   zObj.__init__c                 C  s
   | j | S r1   r2   )r9   itemr=   r=   r>   __getitem__K      
zObj.__getitem__c                 C  s   || j |< d S r1   r@   r9   rA   r<   r=   r=   r>   __setitem__N   s   zObj.__setitem__c                 c  s>    | j  D ]\}}t|tr|t|fV  q||fV  qd S r1   )r2   r4   r5   r0   r6   )r9   r;   r<   r=   r=   r>   __iter__Q   s   
zObj.__iter__returnboolc                 C  s:   || j v rdS | j  D ]}t|tr||v r dS qdS )NTF)r2   valuesr5   r0   rD   r=   r=   r>   __contains__X   s   
zObj.__contains__Nc                 C  s   || v r	| j | S |S r1   r@   r9   rA   defaultr=   r=   r>   get`   s   
zObj.getc                 C  
   | j  S r1   )r2   keysr9   r=   r=   r>   rO   e   rC   zObj.keysc                 C  rN   r1   )r2   rI   rP   r=   r=   r>   rI   h   rC   z
Obj.valuesc                 C  rN   r1   )r2   r4   rP   r=   r=   r>   r4   k   rC   z	Obj.itemsstrc                 C  
   t | jS r1   rQ   r2   rP   r=   r=   r>   __str__n   rC   zObj.__str__c                 C  rR   r1   rS   rP   r=   r=   r>   __repr__q   rC   zObj.__repr__c                 C  s   || v r
| j |S |S r1   )r2   poprK   r=   r=   r>   rV   t   s   zObj.pop)rG   rH   r1   )rG   rQ   )__name__
__module____qualname____doc__r?   rB   rE   rF   rJ   rM   rO   rI   r4   rT   rU   rV   r=   r=   r=   r>   r0   >   s    



r0   c                   @  sH   e Zd ZdZ			dddd	Zd
d ZdddZdddZdddZdS )Requesta  
    A Gradio request object that can be used to access the request headers, cookies,
    query parameters and other information about the request from within the prediction
    function. The class is a thin wrapper around the fastapi.Request class. Attributes
    of this class include: `headers`, `client`, `query_params`, `session_hash`, and `path_params`. If
    auth is enabled, the `username` attribute can be used to get the logged in user. In some environments,
    the dict-like attributes (e.g. `requests.headers`, `requests.query_params`) of this class are automatically
    converted to to dictionaries, so we recommend converting them to dictionaries before accessing
    attributes for consistent behavior in different environments.
    Example:
        import gradio as gr
        def echo(text, request: gr.Request):
            if request:
                print("Request headers dictionary:", dict(request.headers))
                print("Query parameters:", dict(request.query_params))
                print("IP address:", request.client.host)
                print("Gradio session hash:", request.session_hash)
            return text
        io = gr.Interface(echo, "textbox", "textbox").launch()
    Demos: request_ip_headers
    Nrequestfastapi.Request | Noneusername
str | Nonesession_hashc                 K  s   || _ || _|| _|| _dS )at  
        Can be instantiated with either a fastapi.Request or by manually passing in
        attributes (needed for queueing).
        Parameters:
            request: A fastapi.Request
            username: The username of the logged in user (if auth is enabled)
            session_hash: The session hash of the current session. It is unique for each page load.
        N)r\   r^   r`   kwargs)r9   r\   r^   r`   ra   r=   r=   r>   r?      s   
zRequest.__init__c                 C  s"   t |trtjt|tdS |S )N)object_hook)r5   r6   jsonloadsdumpsr0   )r9   dr=   r=   r>   dict_to_obj   s   
zRequest.dict_to_objnamerQ   c              
   C  s\   | j r| t| j |S z| j| }W n ty( } z	td| d|d }~ww | |S )Nz#'Request' object has no attribute '')r\   rg   getattrra   KeyErrorAttributeError)r9   rh   objker=   r=   r>   __getattr__   s   

zRequest.__getattr__rG   dict[str, Any]c                 C  s   | j tt| di tt| di tt| di tt| di t| di o(| jjt| di o1| jjdt| ddd	 t| d
 }rZzt	| || j d< W n
 tj
yY   Y nw d | _| jS )Nheadersquery_paramscookiespath_paramsclient)hostporturl )rq   rr   rs   rt   ru   rx   staterequest_state)ra   r3   r6   rj   ru   rv   rw   hasattrpicklere   PicklingErrorr\   r2   )r9   r{   r=   r=   r>   __getstate__   s(   

zRequest.__getstate__rz   c                 C  s    | dd  }r|| _|| _d S )Nr{   )rV   rz   r2   )r9   rz   r{   r=   r=   r>   __setstate__   s   
zRequest.__setstate__)NNN)r\   r]   r^   r_   r`   r_   )rh   rQ   )rG   rp   )rz   rp   )	rW   rX   rY   rZ   r?   rg   ro   r   r   r=   r=   r=   r>   r[   z   s    

r[   c                   @     e Zd ZdS )FnIndexInferErrorNrW   rX   rY   r=   r=   r=   r>   r          r   blocksr,   api_namer_   bodyr'   rG   r+   c                 C  sl   |j r| j|j  }|jj}n| j}|jd u r1|d ur*| D ]}|j|kr)|  S qtd| ||j S )Nz-Could not infer function index for API name: )r`   state_holderblocks_configfnsfn_indexrI   r   r   )r   r   r   session_stater   fnr=   r=   r>   get_fn   s   



r   r(   r   r^   Optional[str]r\   Optional[fastapi.Request]c                 C  sh   |j r| jg| _| jr"| jrt||dg}|S t|| j| jd}|S |d u r*tdt||| jd}|S )N)r^   r\   )r^   r\   r`   z0request must be provided if body.request is None)cancelsr`   datar\   batchedr[   
ValueError)r   r   r^   r\   
gr_requestr=   r=   r>   compile_gr_request   s    


r   appr/   c                 C  s   |j }t|dd }|d ur7| j| }|d u rd }||fS || jv r-d }| j| ||fS | j|}||fS t|  }d }||fS )Nr`   )	event_idrj   r   iterators_to_resetremove	iteratorsrM   r*   
get_blocks)r   r   r   r`   r   iteratorr=   r=   r>   restore_session_state  s    


r   r.   c                 C  s2   ddl m} |j}||r| j|nd |j}|S )Nr   r-   )gradio.helpersr.   
trigger_idr   rM   
event_data)r   r   r.   targetr   r=   r=   r>   prepare_event_data   s   r   r   Union[Request, list[Request]]	root_pathrQ   c                   sR  t | |d\}}t|  |}|j}t|dd }	|j}
|j o"|j}|r(|
g}
zBt	  |  j
||
||||	||d|j|dI d H }W d    n1 sNw   Y  |dd }|d urb|| j|< t|tri|W n2 ty   |d ur{| j|nd }|d urt|}|  j|	 |i }| D ]}|  q w |r|d d |d< |S )N)r   r   r`   T)block_fninputsr\   rz   r   r`   r   r   in_event_listenersimple_formatr   r   r   r   )r   r   r   r   rj   r   r   batchr$   MatplotlibBackendManangerprocess_apir   rV   r   r5   r)   BaseExceptionrM   idpending_streamsrI   
end_stream)r   r   r   r   r   r   r   r   r   r`   r   batch_in_single_outoutputrun_idr   streamr=   r=   r>   call_process_api.  sX   



r   fastapi.Request
route_pathc                   s   d fdd}|rt |r|dS |d}|rd| nt j}t|}|jdd	}t|d}|d
dkrA|dd}|d}t	|dkrW|sW|dt	|  }|d}t|}|rn|j
|krn|j|d}t|dS )a  
    Gets the root url of the Gradio app (i.e. the public url of the app) without a trailing slash.

    This is how the root_url is resolved:
    1. If a user provides a `root_path` manually that is a full URL, it is returned directly.
    2. If the request has an x-forwarded-host header (e.g. because it is behind a proxy), the root url is
    constructed from the x-forwarded-host header. In this case, `route_path` is not used to construct the root url.
    3. Otherwise, the root url is constructed from the request url. The query parameters and `route_path` are stripped off.
    And if a relative `root_path` is provided, and it is not already the subpath of the URL, it is appended to the root url.

    In cases (2) and (3), We also check to see if the x-forwarded-proto header is present, and if so, convert the root url to https.
    And if there are multiple hosts in the x-forwarded-host or multiple protocols in the x-forwarded-proto, the first one is used.
    header_namerQ   c                   s&    j | }|r|dd  S d S )N,r   )rq   rM   splitstrip)r   header_valuer\   r=   r>   get_first_header_valuev  s   z,get_root_url.<locals>.get_first_header_value/zx-forwarded-hosthttp://N)queryzx-forwarded-protohttpszhttps://r   )path)r   rQ   )client_utilsis_http_url_likerstriprQ   rx   httpxURL	copy_withreplacelenr   )r\   r   r   r   x_forwarded_hostroot_urlr=   r   r>   get_root_urle  s$   




r   srcbytescodecc              	   C  s.   z|  |W S  ttfy   |  d Y S w )Nlatin-1)decodeUnicodeDecodeErrorLookupError)r   r   r=   r=   r>   _user_safe_decode  s
   r   c                      s,   e Zd ZdZddddd fddZ  ZS )GradioUploadFilez UploadFile with a sha attribute.Nsizefilenamerq   filer   r   
int | Noner   r_   rq   Headers | NonerG   Nonec                  s0   t  j||||d t | _| jtj d S )Nr   )superr?   hashlibsha256shar3   r#   	hash_seed)r9   r   r   r   rq   	__class__r=   r>   r?     s   
zGradioUploadFile.__init__)
r   r   r   r   r   r_   rq   r   rG   r   )rW   rX   rY   rZ   r?   __classcell__r=   r=   r   r>   r     s    r   T)frozenc                   @     e Zd ZU ded< ded< dS )FileUploadProgressUnitrQ   r   int
chunk_sizeNrW   rX   rY   __annotations__r=   r=   r=   r>   r        
 r   c                   @  r   )FileUploadProgressTrackerzdeque[FileUploadProgressUnit]r   rH   is_doneNr   r=   r=   r=   r>   r     r   r   c                   @  r   )!FileUploadProgressNotTrackedErrorNr   r=   r=   r=   r>   r     r   r   c                   @  r   ) FileUploadProgressNotQueuedErrorNr   r=   r=   r=   r>   r     r   r   c                   @  sR   e Zd ZdddZdddZdddZdddZdddZdddZdddZ	dS )FileUploadProgressrG   r   c                 C  s
   i | _ d S r1   	_statusesrP   r=   r=   r>   r?     rC   zFileUploadProgress.__init__	upload_idrQ   c                 C  s$   || j vrtt d| j |< d S d S )NF)r   r   r   r9   r   r=   r=   r>   track  s   
zFileUploadProgress.trackr   message_bytesr   c                 C  s   || j vr
| | | j | j}t|dkr"|t|t| d S | }|j|kr7|t|t| d S |t||jt|  d S )Nr   )	r   r   r   r   appendr   popleftr   r   )r9   r   r   r   queue	last_unitr=   r=   r>   r     s   


zFileUploadProgress.appendc                 C  s$   || j vr
| | d| j | _d S NT)r   r   r   r   r=   r=   r>   set_done  s   

zFileUploadProgress.set_donec                 C  s   || j vrt | j | jS r1   )r   r   r   r   r=   r=   r>   r     s   
zFileUploadProgress.is_donec                 C  s   || j v r| j |= d S d S r1   r   r   r=   r=   r>   stop_tracking  s   
z FileUploadProgress.stop_trackingr   c              
   C  sD   || j vrt z	| j | j W S  ty! } zt |d }~ww r1   )r   r   r   rV   
IndexErrorr   )r9   r   er=   r=   r>   rV     s   
zFileUploadProgress.popNrG   r   )r   rQ   )r   rQ   r   rQ   r   r   )r   rQ   rG   r   )
rW   rX   rY   r?   r   r   r   r   r   rV   r=   r=   r=   r>   r     s    





r   c                   @  s   e Zd ZdZdZdddddd/ddZd0ddZd1ddZd0d d!Zd1d"d#Z	d1d$d%Z
d0d&d'Zd0d(d)Zd0d*d+Zd2d-d.ZdS )3GradioMultiPartParsera  Vendored from starlette.MultipartParser.

    Thanks starlette!

    Made the following modifications
        - Use GradioUploadFile instead of UploadFile
        - Use NamedTemporaryFile instead of SpooledTemporaryFile
        - Compute hash of data as the request is streamed

    i   i  N)	max_files
max_fieldsr   upload_progressrq   r   r   AsyncGenerator[bytes, None]r  Union[int, float]r  r   r_   r  FileUploadProgress | Nonemax_file_sizeint | floatrG   r   c                C  sl   || _ || _|| _|| _g | _|| _|| _d| _d| _|| _	d| _
d| _t | _d| _g | _g | _g | _d S )Nr       ry   )rq   r   r  r  r4   r   r  _current_files_current_fieldsr  _current_partial_header_name_current_partial_header_valuer   _current_part_charset_file_parts_to_write_file_parts_to_finish_files_to_close_on_error)r9   rq   r   r  r  r   r  r  r=   r=   r>   r?     s"   
zGradioMultiPartParser.__init__c                 C  s   t  | _d S r1   )r   r  rP   r=   r=   r>   on_part_begin  s   z#GradioMultiPartParser.on_part_beginr   r   startr   endc                 C  sd   ||| }| j d ur| j | j| jjj| | jjd u r'| j j|7  _d S | j| j|f d S r1   )r  r   r   r  r   r   r   r  )r9   r   r  r  r   r=   r=   r>   on_part_data  s   
z"GradioMultiPartParser.on_part_datac                 C  s^   | j jd u r| j| j jt| j jt| jf d S | j	| j  | j| j j| j jf d S r1   )
r  r   r4   r   
field_namer   r   rQ   r  r  rP   r=   r=   r>   on_part_end+  s   z!GradioMultiPartParser.on_part_endc                 C     |  j ||| 7  _ d S r1   )r  r9   r   r  r  r=   r=   r>   on_header_field:     z%GradioMultiPartParser.on_header_fieldc                 C  r  r1   )r  r  r=   r=   r>   on_header_value=  r   z%GradioMultiPartParser.on_header_valuec                 C  s@   | j  }|dkr| j| j_| jj|| jf d| _ d| _d S )Ns   content-dispositionr  )r  lowerr  r  content_dispositionitem_headersr   )r9   fieldr=   r=   r>   on_header_end@  s   


z#GradioMultiPartParser.on_header_endc              
   C  s  t | jjpd\}}zt|d t| j| j_W n ty) } ztd|d }~ww d|v rj|  j	d7  _	| j	| j
krDtd| j
 dt|d t| j}tdd	}| j| t|d
|t| jjdd| j_d S |  jd7  _| j| jkrtd| j dd | j_d S )Nr  s   namez=The Content-Disposition header field "name" must be provided.s   filename   z+Too many files. Maximum number of files is .F)deleter   )raw)r   r   r   rq   z-Too many fields. Maximum number of fields is )r   r  r#  r   rQ   r  r  rk   r   r  r  r   r  r   r   r   r$  r   r  r  )r9   _optionsr  r   tempfiler=   r=   r>   on_headers_finishedJ  sD   
z)GradioMultiPartParser.on_headers_finishedc                 C  s   d S r1   r=   rP   r=   r=   r>   on_endk  s   zGradioMultiPartParser.on_endr   c              
     s  t | jd \}}|dd}t|tr|d}|| _z|d }W n ty4 } ztd|d }~ww | j	| j
| j| j| j| j| j| jd}t||}zn| j2 zg3 d H W }|| | jD ]:\}	}
|	jsiJ |	j|
I d H  |	jj|
 t|	jjjj| jkr| jd ur| j| j  td| j d	q`| j!D ]}	|	jsJ |	j"d
I d H  q| j#  | j!#  qR6 W n ty } z| j$D ]}|%  t&|j'  q|d }~ww |(  | jd ur| j| j  t)| j*S )NzContent-Types   charsetzutf-8r   s   boundaryzMissing boundary in multipart.)r  r  r  r  r!  r&  r.  r/  z+File size exceeded maximum allowed size of z bytes.r   )+r   rq   rM   r5   r   r   r  rk   r   r  r  r  r  r!  r&  r.  r/  	multipartMultipartParserr   writer  r   r   r3   osstatrh   st_sizer  r  r   r   r  seekclearr  closer   unlinkfinalizer   r4   )r9   r+  paramscharsetboundaryr  	callbacksparserchunkpartr   excr   r=   r=   r>   parsen  sj   











zGradioMultiPartParser.parse)rq   r   r   r  r  r	  r  r	  r   r_   r  r
  r  r  rG   r   r  )r   r   r  r   r  r   rG   r   )rG   r   )rW   rX   rY   rZ   r  r?   r  r  r  r  r!  r&  r.  r/  rC  r=   r=   r=   r>   r    s"    








!r  files	list[str]destinationsr   c                 C  s(   t | |ddD ]
\}}t|| qd S )NF)strict)zipshutilmove)rD  rF  r   destr=   r=   r>   move_uploaded_files_to_cache  s   rL  configr%   rootc                 C  s4   |  d}|du s||kr|| d< t| ||} | S )z
    Updates the root "key" in the config dictionary to the new root url. If the
    root url has changed, all of the urls in the config that correspond to component
    file urls are updated to use the new root url.
    rN  N)rM   r#   add_root_url)rM  rN  previous_rootr=   r=   r>   update_root_in_config  s
   
rQ  api_inforp   c                 C  s   ddd}t | |dd S )	zS
    Updates the example values in the api_info dictionary to use a public url
    	file_dictr6   c                 S  sB   |  d}|d urt|rt|d r| S | d d |d< | S )Nparameter_defaultrx   example_input)rM   r   is_file_obj_with_urlr   )rS  default_valuer=   r=   r>   _add_root_url  s   
z>update_example_values_to_use_public_url.<locals>._add_root_urlc                 S  s   t | tod| v S )NrT  )r5   r6   )rf   r=   r=   r>   <lambda>  s    z9update_example_values_to_use_public_url.<locals>.<lambda>N)rS  r6   )r   traverse)rR  rX  r=   r=   r>   'update_example_values_to_use_public_url  s   
r[  input_passwordcorrect_passwordrH   c                 C  s   t |  | S r1   )hmaccompare_digestencode)r\  r]  r=   r=   r>   compare_passwords_securely  s   ra  stringc                 C  s   d}t || duS )zThis regex matches strings that start with a scheme (one or more characters not including colon, slash, or space)
    followed by ://, or start with just //, \/, /\, or \ as they are interpreted as SMB paths on Windows.
    z0^(?:[a-zA-Z][a-zA-Z0-9+\-.]*://|//|\\\\|\\/|/\\)N)rematch)rb  patternr=   r=   r>   starts_with_protocol  s   rf  rx   c                 C  s>   | sdS d| vrd|  } zt | jpdW S  ty   Y dS w )a  
    Returns the hostname of a given url, or an empty string if the url cannot be parsed.
    Examples:
        get_hostname("https://www.gradio.app") -> "www.gradio.app"
        get_hostname("localhost:7860") -> "localhost"
        get_hostname("127.0.0.1") -> "127.0.0.1"
    ry   z://r   )r   hostname	Exception)rx   r=   r=   r>   get_hostname  s   ri  c                   @  sZ   e Zd Z	d&d'dd	Zd(ddZd)ddZd*ddZd+ddZd,ddZe	d-d#d$Z
d%S ).CustomCORSMiddlewareTr   r   strict_corsrH   rG   r   c                 C  s`   || _ d| _d| jtddd| _ddi| _g d| _|r&tdd ur.| j	d	 d S d S )
N)DELETEGETHEADOPTIONSPATCHPOSTPUTz, iX  true)zAccess-Control-Allow-MethodszAccess-Control-Max-Age Access-Control-Allow-Credentialsrt  )	localhostz	127.0.0.1z0.0.0.0GRADIO_LOCAL_DEV_MODEnull)
r   all_methodsjoinrQ   preflight_headerssimple_headerslocalhost_aliasesr3  getenvr   )r9   r   rk  r=   r=   r>   r?     s   


zCustomCORSMiddleware.__init__scoper!   receiver    sendr"   c                   s   |d dkr|  |||I d H  d S t|d}|d}|d u r-|  |||I d H  d S |d dkrHd|v rH| j|d}||||I d H  d S | j||||dI d H  d S )	Ntypehttpr~  originmethodro  zaccess-control-request-method)request_headers)r   r   rM   preflight_responsesimple_response)r9   r~  r  r  rq   r  responser=   r=   r>   __call__  s   

zCustomCORSMiddleware.__call__r  r   r   c                 C  sL   t | j}|d }| |r||d< |d}|d ur||d< tdd|dS )NOriginAccess-Control-Allow-Originzaccess-control-request-headerszAccess-Control-Allow-HeadersOK   )status_coderq   )r6   rz  is_valid_originrM   r   )r9   r  rq   r  requested_headersr=   r=   r>   r    s   


z'CustomCORSMiddleware.preflight_responsec                   s,   t j| j||d}| |||I d H  d S )N)r  r  )	functoolspartial_sendr   )r9   r~  r  r  r  r=   r=   r>   r  (  s   z$CustomCORSMiddleware.simple_responsemessager   c                   sr   |d dkr||I d H  d S | dg  t|d}|| j |d }| |r0| || ||I d H  d S )Nr  zhttp.response.startrq   r  r  )
setdefaultr   r3   r{  r  allow_explicit_origin)r9   r  r  r  rq   r  r=   r=   r>   r  .  s   

zCustomCORSMiddleware._sendc                 C  s4   |d }|d }t |}t |}|| jvp|| jv S )Nr  Host)ri  r|  )r9   r  r  rv   	host_nameorigin_namer=   r=   r>   r  <  s   
z$CustomCORSMiddleware.is_valid_originrq   r   r  rQ   c                 C  s   || d< |  d d S )Nr  r  )add_vary_header)rq   r  r=   r=   r>   r  G  s   z*CustomCORSMiddleware.allow_explicit_originN)T)r   r   rk  rH   rG   r   )r~  r!   r  r    r  r"   rG   r   )r  r   rG   r   )
r~  r!   r  r    r  r"   r  r   rG   r   )r  r   r  r"   r  r   rG   r   )r  r   rG   rH   )rq   r   r  rQ   rG   r   )rW   rX   rY   r?   r  r  r  r  r  staticmethodr  r=   r=   r=   r>   rj    s    





rj  ager   c           	   
   C  s   t  }| j D ]}|t|dt   q| jD ]A}t  }|D ]5}||v r&qz%t|}t|	 j
}|du s@t | j|krJt| || W q tyT   Y qw ||8 }qdS )zGDelete files that are older than age. If age is None, delete all files.keep_in_cacheN)setr   rI   r3   rj   temp_file_setsr   r
   fromtimestamplstatst_ctimenowsecondsr3  r   addFileNotFoundError)	r   r  dont_delete	componenttemp_set	to_remover   	file_pathmodified_timer=   r=   r>   delete_files_created_by_appM  s(   



r  	frequencyr   c                   s0   	 t |I dH  tjt|  |I dH  q)zVStartup task to delete files created by the app based on time since last modification.TN)asynciosleepanyio	to_threadrun_syncr  r   r   r  r  r=   r=   r>   delete_files_on_scheduled  s   

r  r'  r   c                 C s.   t t| || dV  t|  dd dS )zKA context manager that triggers the startup and shutdown events of the app.N)r  )r  create_taskr  r  r   r  r=   r=   r>   _lifespan_handlerm  s   r  c                   s    	 | j   tdI dH  q)z&Delete all expired state every second.Tr'  N)r   delete_all_expired_stater  r  r   r=   r=   r>   _delete_statew  s
   
r  c                 C s   t t|  dV  dS )z9When the server launches, regularly delete expired state.N)r  r  r  r  r=   r=   r>   _delete_state_handler~  s   
r  user_lifespan3Callable[[App], AbstractAsyncContextManager] | None,Callable[[App], AbstractAsyncContextManager]c                   s   t d fdd}|S )zWReturn a context manager that applies _lifespan_handler and user_lifespan if it exists.r   r/   c              	    s   t  4 I d H 7}|t| I d H  r# r#|t|  I d H  d ur1|| I d H  d V  W d   I d H  d S 1 I d H sEw   Y  d S r1   )r   enter_async_contextr  r  )r   stackr  r  r  r=   r>   _handler  s   .z)create_lifespan_handler.<locals>._handlerNr   r/   )r   )r  r  r  r  r=   r  r>   create_lifespan_handler  s   	r  c                   @  s*   e Zd ZddddZddd	Zd
d ZdS )MediaStreamNdesired_output_formatr_   c                 C  s.   g | _ d | _d| _d| _d| _d| _|| _d S )NFr   ze#EXTM3U
#EXT-X-PLAYLIST-TYPE:EVENT
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:4
#EXT-X-MEDIA-SEQUENCE:0
   )segmentscombined_fileendedsegment_indexplaylistmax_durationr  )r9   r  r=   r=   r>   r?     s   
zMediaStream.__init__r   MediaStreamChunk | Nonec                   sD   |sd S t t }| jd|i| t| j|d d | _d S )Nr   durationr'  )rQ   uuiduuid4r  r   maxr  )r9   r   
segment_idr=   r=   r>   add_segment  s   zMediaStream.add_segmentc                 C  s
   d| _ d S r   )r  rP   r=   r=   r>   r     rC   zMediaStream.end_streamr1   )r  r_   )r   r  )rW   rX   rY   r?   r  r   r=   r=   r=   r>   r    s    
	r  )r   r,   r   r_   r   r'   rG   r+   )r   r(   r   r+   r^   r   r\   r   )r   r/   r   r(   )r   r,   r   r(   rG   r.   )
r   r/   r   r(   r   r   r   r+   r   rQ   )r\   r   r   rQ   r   r_   rG   rQ   )r   r   r   rQ   rG   rQ   )rD  rE  rF  rE  rG   r   )rM  r%   rN  rQ   rG   r%   )rR  rp   rG   rp   )r\  rQ   r]  rQ   rG   rH   )rb  rQ   rG   rH   )rx   rQ   rG   rQ   )r   r,   r  r   rG   r   )r   r/   r  r   r  r   rG   r   )r'  r'  )r   r/   r  r   r  r   rG   r   r  )r  r  r  r   r  r   rG   r  )x
__future__r   r  r  r   r^  rc   r3  r}   rc  rI  	threadingr  collectionsr   collections.abcr   r   
contextlibr   r   r   dataclassesr	   python_dataclassr
   pathlibr   r-  r   r   typingr   r   r   r   r   urllib.parser   r  fastapigradio_client.utilsr$   r   r   r0  gradio_client.documentationr   multipart.multipartr   starlette.datastructuresr   r   r   r   starlette.formparsersr   r   starlette.responsesr   r   starlette.typesr   r   r    r!   r"   gradior#   gradio.data_classesr%   r&   r'   r(   gradio.exceptionsr)   gradio.state_holderr*   gradio.blocksr+   r,   r   r.   gradio.routesr/   Lockconfig_lock
API_PREFIXr0   r[   rh  r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  rL  rQ  r[  ra  rf  ri  rj  r  r  r  r  r  r  r  r=   r=   r=   r>   <module>   s    <[





7
.2 
>





W
	
	