o
    ej                     @  s  d Z ddlmZ ddlZddlZejdkrddlmZ n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mZ ddlmZ ddlmZ dd	lmZmZmZmZmZ ddlZddlZddl Z ddl!Z!dd
lm"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z( ddl)m*Z* ddl+m,Z,m-Z-m.Z.m/Z/ ddl0m1Z1 ddl2m3Z3 ddl4m5Z5m6Z6 ddl7m8Z8 ddl9m:Z: ddl;m<Z<m=Z= ddl>m?Z? ddl@Z@ddlAmBZB ddl@mCZCmDZDmEZE ddlFmGZG ddlHmIZImJZJ ddlKmLZL ddlMmNZN ddlOmPZP ddlQmRZRmSZS ddlTmUZU ddlVmWZWmXZXmYZY e
Z  ed[d\ Z]ed[ddd \ Z^ed[ddd!\ Z_ed[d"` ZaG d#d$ d$e.Zbd%d& Zce3e]d'Zdecedjejfd&< eg ZhG d(d) d)e#Zid?d.d/Zjd@d2d3Zke6d4 e5 		dAdBd=d>ZldS )CzImplements a FastAPI server to run the gradio interface. Note that some types in this
module use the Optional/Union notation so that they work correctly with pydantic.    )annotationsN)   	   )files)TimeoutError)defaultdict)Path)AnyDictListOptionalType)DependsFastAPIFileHTTPException
UploadFile	WebSocketstatus)CORSMiddleware)FileResponseHTMLResponseJSONResponsePlainTextResponse)OAuth2PasswordRequestForm)Jinja2Templates)documentset_documentation_group)TemplateNotFound)BackgroundTask)RedirectResponseStreamingResponse)WebSocketState)route_utilsutils
wasm_utils)Context)PredictBody	ResetBody)warn_deprecation)Error)attach_oauth)
EstimationEvent)Request)cancel_tasksrun_coro_in_backgroundset_task_namegradio	templatesZfrontendZstaticZassetszversion.txtc                   @  s6   e Zd ZdZedddZddd	ZedddZdS )ORJSONResponsezapplication/jsoncontentr	   returnbytesc                 C  s   t j| t jt jB tdS )N)optiondefault)orjsondumpsZOPT_SERIALIZE_NUMPYZOPT_PASSTHROUGH_DATETIMEstrr5    r>   =D:\Projects\ConvertPro\env\Lib\site-packages\gradio/routes.py_renderF   s
   
zORJSONResponse._renderc                 C  s
   t |S N)r4   r@   )selfr5   r>   r>   r?   renderN   s   
zORJSONResponse.renderr<   c                 C  s   t | dS )Nzutf-8)r4   r@   decoder=   r>   r>   r?   _render_strQ   s   zORJSONResponse._render_strN)r5   r	   r6   r7   )r5   r	   r6   r<   )__name__
__module____qualname__
media_typestaticmethodr@   rC   rE   r>   r>   r>   r?   r4   C   s    
r4   c                 C  s0   t t| ddddddddS )	N<z\u003c>z\u003e&z\u0026'z\u0027)
markupsafeZMarkupr4   rE   replace)valuer>   r>   r?   toorjsonV   s   rR   )	directoryc                      sN   e Zd ZdZ fddZddd	Zdd
dZdd Ze	ddddZ	  Z
S )Appz
    FastAPI App Wrapper
    c                   s   i | _ d | _d | _i | _tt| _tt| _t	
 | _td| _d| _tjdp3ttt d | _d | _|dd  |dd  t jdi | d S )N    FZGRADIO_TEMP_DIRr2   Zdocs_urlZ	redoc_urlr>   )tokensauthblocksZstate_holderr   dict	iteratorssetiterators_to_resetr$   Zsafe_get_locklocksecretstoken_urlsafeZqueue_tokenstartup_events_triggeredosenvirongetr<   r   tempfile
gettempdiruploaded_file_dirchange_event
setdefaultsuper__init__)rB   kwargs	__class__r>   r?   rj   k   s    


zApp.__init__rX   gradio.Blocksr6   Nonec                 C  s`   |j }|d urt|sdd |D | _ n|| _ nd | _ || _t | _|j| _i | _|j| _d S )Nc                 S  s   i | ]	}|d  |d qS )r      r>   ).0accountr>   r>   r?   
<dictcomp>   s    z%App.configure_app.<locals>.<dictcomp>)	rW   callablerX   ra   getcwdcwdfavicon_pathrV   	root_path)rB   rX   rW   r>   r>   r?   configure_app   s   
zApp.configure_appc                 C  s   | j d u r	td| j S )Nz+No Blocks has been configured for this app.)rX   
ValueError)rB   r>   r>   r?   
get_blocks   s   
zApp.get_blocksc                   s|   t | | js
J t fdd| jjD }|std jd}i }tj	d ur4|r4dtj	 |d< t
jd |d}|S )	Nc                 3  s"    | ]} j t|j kV  qd S rA   )hosthttpxURL)rq   rooturlr>   r?   	<genexpr>   s    
z*App.build_proxy_request.<locals>.<genexpr>zThis URL cannot be proxied.z	.hf.spacezBearer AuthorizationGETheaders)r}   r~   rX   anyZ	root_urlsPermissionErrorr|   endswithr&   Zhf_tokenclientZbuild_request)rB   url_pathZis_safe_urlZ	is_hf_urlr   rp_reqr>   r   r?   build_proxy_request   s   

zApp.build_proxy_requestN
app_kwargsDict[str, Any] | Nonec              	     s:  |pi }t js|dt tdi |  |  t js( jtdgdgdgd  d dd fd
d} d dt	|fd fdd}ddd} d dd fdd} d dd fdd}ddd d fd!d" 
d#dfd$d%} d& d't	 fd fd*d+} jd ur jjrt   jd,td- jd,td-t	|fd fd.d/}	 jd0t	|gd1 jd2t	|gd1dd fd6d7}
 jd8t	|gd1 jd9t	|gd1d fd:d;} d<dd>d? d@ddAdB} dC fdDdE} jdFt	|gd1 jdFt	|gd1d fdHdI} jdJt	|gd1 jdJt	|gd1d fdLdM jdNt	|gd1d fdSdT} jdUt	|gd1dfdVdW} dX dYd fd\d]} jd^t	|gd1 jd_t	|gd1 jd`t	|gd1 jdat	|gd1t	|fd fdedf} 
dgt	|fd fdidj} jdkt	|gtdl fdmdn} jdot	|gd1tdpfd fdsdt} du dv fdwdx} jdytd- fdzd{} jd|td- fd}d~} S )NZdefault_response_class*)Zallow_originsZallow_methodsZallow_headersz/userz/user/requestfastapi.Requestr6   Optional[str]c                   s$   | j dp| j d} j|S Naccess-tokenaccess-token-unsecurecookiesrc   rV   r   tokenappr>   r?   get_current_user   s   z(App.create_app.<locals>.get_current_userz/login_checkz/login_check/userr<   c                   s$    j d u s	| d urd S ttjdd)NzNot authenticatedstatus_codedetail)rW   r   r   ZHTTP_401_UNAUTHORIZED)r   r   r>   r?   login_check   s
   z#App.create_app.<locals>.login_check	websocketr   c                   s   | j dp| j d}|S r   )r   rc   )r   r   r>   r>   r?   ws_login_check   s
   z&App.create_app.<locals>.ws_login_checkz/tokenz/token/rY   c                   s   | j d}| j|dS )Nr   )r   r   r   r   r   r>   r?   	get_token   s   z!App.create_app.<locals>.get_tokenz/app_idz/app_id/c                   s   d   jiS )Napp_id)r{   r   )r   r   r>   r?   r      s   zApp.create_app.<locals>.app_idc                   s&   	 |  dI d H  tdI d H  q)NTZPINGrp   )	send_textasynciosleepr   r>   r>   r?   send_ping_periodically   s
   z.App.create_app.<locals>.send_ping_periodicallyc                   sD    j sJ 	  j  r| dI d H   j   tdI d H  q)NTZCHANGEg?)rg   is_setr   clearr   r   r   r   r>   r?   listen_for_changes   s   


z*App.create_app.<locals>.listen_for_changesz/dev/reloadc                   s   |   I d H  t| }t | }||h}||j ||j tj||gtjdI d H \}}|D ]}|  q7tdd |D rP| 	 I d H  d S d S )N)return_whenc                 s  s    | ]
}t | tV  qd S rA   )
isinstance	exception	Exception)rq   taskr>   r>   r?   r      s    z9App.create_app.<locals>.notify_changes.<locals>.<genexpr>)
acceptr   create_taskadd_done_callbackremovewaitFIRST_COMPLETEDcancelr   close)r   Zpingnotifytasksdonependingr   )r   r   r>   r?   notify_changes   s    
z&App.create_app.<locals>.notify_changesz/loginz/login/	form_datar   c                   s   | j  | j}} jd u rtdtjdS t js&| jv r& j| |ks2t jrW j||rWt	
d}| j|< tddid}|jd|dddd	 |jd
|dd |S tddd)N/r   r      successTr=   r   none)keyrQ   httponlysamesitesecurer   )r   rQ   r     zIncorrect credentials.r   )usernamestrippasswordrW   r    r   HTTP_302_FOUNDrt   __call__r^   r_   rV   r   
set_cookier   )r   r   r   r   responser   r>   r?   login   s4   



zApp.create_app.<locals>.loginr   )response_classc              
     s   t dd   }| jdd} jd u s|d ur$  j}||d< nd|j  j|d}z|j	r5dnd	}t
|| |d
W S  tyY } z|j	rPtd|td|d }~ww )Nzapplication/javascriptz.jsrx    r   T)Zauth_requiredauth_messagespace_idr   zfrontend/share.htmlzfrontend/index.html)r   configzqDid you install Gradio from source files? Share mode only works when Gradio is installed through the pip package.znDid you install Gradio from source files? You need to build the frontend by running /scripts/build_frontend.sh)	mimetypesadd_typer{   scoperc   rW   r   r   r   sharer3   ZTemplateResponser   rz   )r   r   rX   rx   r   templateerrr   r>   r?   main#  s@   

zApp.create_app.<locals>.mainz/info/)dependenciesz/infoT	serializeboolc                   s      j}tj|| S rA   )r{   r   r2   rX   Zget_api_info)r   r   r   r>   r?   api_infoI  s   
z App.create_app.<locals>.api_infoz/config/z/configc                   s$   | j dd}  j}||d< |S )Nrx   r   r   )r   rc   r{   r   )r   rx   r   r   r>   r?   
get_configO  s   
z"App.create_app.<locals>.get_configz/static/{path:path}pathc                 S     t t| }t|S rA   )	safe_joinSTATIC_PATH_LIBr   )r   Zstatic_filer>   r>   r?   static_resourceW     
z'App.create_app.<locals>.static_resourcez/assets/{path:path}c                 S  r   rA   )r   BUILD_PATH_LIBr   )r   Z
build_filer>   r>   r?   build_resource\  r   z&App.create_app.<locals>.build_resourcez/favicon.icoc                    s&      } | jd u rdS t| jS )Nzimg/logo.svg)r{   rw   r   )rX   )r   r   r>   r?   favicona  s
   

zApp.create_app.<locals>.faviconz/proxy={url_path:path}r   c              
     sn   z  | }W n ty } z	tdt|d|d }~ww tj|ddI d H }t| |j|j	t
|jdS )Nr   r   Tstream)r   r   
background)r   r   r   r<   r   sendr!   Z	aiter_rawr   r   r   aclose)r   r   r   Zrp_respr   r>   r?   reverse_proxyi  s   z%App.create_app.<locals>.reverse_proxyz/file={path_or_url:path}path_or_urlc                   s    }t| rt| tjdS t|  t fdd|jD }tdd  j	D } 
 }|s6|s6|r?tdd|  dt j}t t j|j v }t fdd|jD }t j}	|su|su|su|	sutdd|  d  std	d
|  d|jdd }
|
drd|
v r|
dd  }
|
d\}}| r| rt|}t|}tj t||t|jt ! d}|S t" ddidS )Nr   c                 3      | ]	}t  |V  qd S rA   r$   is_in_or_equal)rq   Zblocked_pathabs_pathr>   r?   r     
    

z/App.create_app.<locals>.file.<locals>.<genexpr>c                 s  s    | ]}| d V  qdS ).N)
startswith)rq   partr>   r>   r?   r     s      zFile not allowed: r   c                 3  r   rA   r   )rq   Zallowed_pathr   r>   r?   r     r     zFile not found: Ranger   zbytes=-   )stat_resultzAccept-Rangesr7   r   )#r{   r$   Zvalidate_urlr    r   r   abspathr   Zblocked_pathspartsis_dirr   r   rv   r<   r[   unionZtemp_file_setsZallowed_pathsrf   existsr   rc   r   r   split	isnumericintranged_responseZRangedFileResponseZ	OpenRangerY   ra   statr   )r   r   rX   Zin_blocklistZ
is_dotfiler  Z
in_app_dirZcreated_by_appZin_allowlistZwas_uploadedZ	range_valstartendr   r   r   r?   filey  sN   


zApp.create_app.<locals>.filez+/stream/{session_hash}/{run}/{component_id}session_hashrunr  component_idc                   sH     j|  |i |d   d u rtdd fdd}t| S )Nr   zStream not found.c                  3  s^    d} d}d}	 t  dkr||krd S || 7 }t|  qd} d}|d u r+d S |V  q)Ng{Gz?x   r   )lentimer   pop)Zcheck_stream_rateZmax_wait_timeZ	wait_timeZnext_streamr   r>   r?   stream_wrapper  s"   

z6App.create_app.<locals>.stream.<locals>.stream_wrapper)r{   Zpending_streamsrc   r   r!   )r  r  r  r   r  r   r   r?   r     s   

zApp.create_app.<locals>.streamz/file/{path:path}c                   s    | |I d H S rA   r>   )r   r   )r  r>   r?   file_deprecated  s   z'App.create_app.<locals>.file_deprecatedz/reset/z/resetbodyr(   c              	     s   | j  jvrddiS  j4 I d H ! d  j| j  | j<  j| j  | j W d   I d H  ddiS 1 I d H s9w   Y  ddiS )Nr   FT)r  rZ   r]   fn_indexr\   add)r  r   r>   r?   reset_iterator  s   z&App.create_app.<locals>.reset_iteratorz/run/{api_name}z/run/{api_name}/z/api/{api_name}z/api/{api_name}/api_namer'   r   c           	   
     s   t j | |d}  js  |rttjdt j ||||d}zt j	 |||dI d H }W |S  t
yb } z"  jpEt|t}t  td|rRt|nd iddW  Y d }~S d }~ww )N)r   r  r  )r   )fn_index_inferredr   r   )r   r  
gr_requestr  errori  )r5   r   )r#   Zinfer_fn_indexr{   Zapi_openZqueue_enabled_for_fnr   r   ZHTTP_404_NOT_FOUNDZcompile_gr_requestZcall_process_apiBaseException
show_errorr   r*   	traceback	print_excr   r<   )	r  r  r   r   r  r   outputr!  r#  r   r>   r?   predict  sD   
zApp.create_app.<locals>.predictz/queue/joinr   c                   s     } jd ur|d u r| jtjdI d H  d S |jjd u r&|j  |  I d H  zt	j
| ddiddI d H  W n
 tyH   Y d S w zt	j
|  ddI d H }W n
 tya   Y d S w t| |d |d } j||_|d |_|j|j dd	rt|j d
|j hI d H  |j|j|jI d H  |jj| t|jj|gd}t||j|jdd n/|j|}|d u r|j|ddiI d H  | I d H  d S |j }|j |||I d H  	 t	!dI d H  | j"t#j$krd S q)N)codemsgZ	send_hash   )timeoutr  r  Zeveryr   _F)batchZ
queue_fullTrp   )%r{   rW   r   r   ZWS_1008_POLICY_VIOLATION_queueZ
server_appZset_server_appr   r   wait_forZ	send_jsonAsyncTimeOutErrorZreceive_jsonr-   rV   rc   r   r  r   r  r/   Zreset_iteratorsZcontinuous_tasksappendr0   Zprocess_eventsr1   pushsend_messageZ
disconnectget_estimationZsend_estimationr   Zapplication_stater"   ZDISCONNECTED)r   r   rX   Zsession_infoeventr   ZrankZ
estimationr   r>   r?   
join_queue  s^   

z"App.create_app.<locals>.join_queuez/queue/status)r   Zresponse_modelc                     s      j S rA   )r{   r.  r4  r>   r   r>   r?   get_queue_statusF  s   z(App.create_app.<locals>.get_queue_statusz/upload.r   List[UploadFile]c                   s6   g }t  }| D ]}||| jI d H  q	|S rA   )r2   r   r1  Zsave_uploaded_filerf   )r   Zoutput_filesZfile_managerZ
input_filer   r>   r?   upload_fileN  s   z#App.create_app.<locals>.upload_filestartupz/startup-eventsc                     s"    j s    d _ dS dS )NTF)r`   r{   startup_eventsr>   r   r>   r?   r;  \  s   z&App.create_app.<locals>.startup_eventsz
/theme.cssc                     s   t   jddS )Nztext/css)rI   )r   r{   	theme_cssr>   r   r>   r?   r<  e  s   z!App.create_app.<locals>.theme_cssz/robots.txtc                     s      jrdS dS )NzUser-agent: *
Disallow: /zUser-agent: *
Disallow: )r{   r   r>   r   r>   r?   
robots_txti  s   
z"App.create_app.<locals>.robots_txtr>   )r   r   r6   r   )r   r<   )r   r   r6   r   )r   r   r6   rY   )r   r   )r   r   )r   r   r   r<   )T)r   r   )r   r   )r   r<   )r   r<   )r   r<   r   r   )r  r<   r  r  r  r  r   r   )r   r<   r   r   )r  r(   )r  r<   r  r'   r   r   r   r<   )r   r   r   r   )r   r8  )r%   ZIS_WASMrh   r4   rT   ry   Zadd_middlewarer   rc   r   r   postrX   Zexpects_oauthr+   headr   r,   r   on_eventr   )rX   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r'  r6  r7  r9  r;  r<  r=  r>   )r   r  r   r   r   r?   
create_app   s   


 $1	):zApp.create_app)rX   rn   r6   ro   )r6   rn   rA   )rX   rn   r   r   r6   rT   )rF   rG   rH   __doc__rj   ry   r{   r   rJ   rA  __classcell__r>   r>   rl   r?   rT   f   s    

rT   rS   r<   r   r6   c                   s   dd t jjt jjfD }|dkrtdt| t j|  }t fdd|D sAt j	 sA dksA 
dsAt j|rEtd	t j|sPtd
d|S )ztSafely path to a base directory to avoid escaping the base directory.
    Borrowed from: werkzeug.security.safe_joinc                 S  s    g | ]}|d ur|dkr|qS )Nr   r>   rq   sepr>   r>   r?   
<listcomp>{  s    zsafe_join.<locals>.<listcomp>r   r   c                 3  s    | ]}| v V  qd S rA   r>   rD  filenamer>   r?   r     s    zsafe_join.<locals>.<genexpr>z..z../r   r   zFile not found)ra   r   rE  altsepr   	posixpathnormpathjoinr   isabsr   isdirr  )rS   r   Z_os_alt_sepsfullpathr>   rG  r?   r   x  s(   



r   cls_set
List[Type]c                 C  sz   g }g }| D ]2}t |pd}|d}|D ]}d|v r+||dd dd  q||d dd  q||fS )	Nr   
zvalue (rp   )r   :)inspectgetdocr	  r1  )rP  ZdocsettypesclsdocZ	doc_linesliner>   r>   r?   	get_types  s   
r\  Zroutesr   fastapi.FastAPIrX   rn   gradio_api_url
str | Noner   dict[str, Any] | Nonec                   s\   d|_ | |_|  tj||d |durtd | d fdd}| |  | S )a  Mount a gradio.Blocks to an existing FastAPI application.

    Parameters:
        app: The parent FastAPI application.
        blocks: The blocks object we want to mount to the parent app.
        path: The path at which the gradio application will be mounted.
        gradio_api_url: Deprecated and has no effect.
        app_kwargs: Additional keyword arguments to pass to the underlying FastAPI app as a dictionary of parameter keys and argument values. For example, `{"docs_url": "/docs"}`
    Example:
        from fastapi import FastAPI
        import gradio as gr
        app = FastAPI()
        @app.get("/")
        def read_main():
            return {"message": "This is your main app"}
        io = gr.Interface(lambda x: "Hello, " + x + "!", "textbox", "textbox")
        app = gr.mount_gradio_app(app, io, path="/gradio")
        # Then run `uvicorn run:app` from the terminal and navigate to http://localhost:8000/gradio.
    F)r   Nz0gradio_api_url is deprecated and has not effect.r:  c                     s       jr     d S d S rA   )r{   Zenable_queuer;  r>   Z
gradio_appr>   r?   start_queue  s   
z%mount_gradio_app.<locals>.start_queue)	dev_modeZget_config_filer   Zvalidate_queue_settingsrT   rA  r)   r@  mount)r   rX   r   r^  r   rb  r>   ra  r?   mount_gradio_app  s   
re  )rS   r<   r   r<   r6   r<   )rP  rQ  )NN)r   r]  rX   rn   r   r<   r^  r_  r   r`  r6   r]  )mrB  
__future__r   r   sysversion_infoimportlib.resourcesr   Zimportlib_resourcesrV  r   ra   rJ  r^   rd   	threadingr  r$  r   r0  collectionsr   pathlibr   typingr	   r
   r   r   r   Zfastapir}   rO   r:   r   r   r   r   r   r   r   Zfastapi.middleware.corsr   Zfastapi.responsesr   r   r   r   Zfastapi.securityr   Zfastapi.templatingr   Zgradio_client.documentationr   r   Zjinja2.exceptionsr   Zstarlette.backgroundr   Zstarlette.responsesr    r!   Zstarlette.websocketsr"   r2   Zgradio.ranged_responser  r#   r$   r%   Zgradio.contextr&   Zgradio.data_classesr'   r(   Zgradio.deprecationr)   Zgradio.exceptionsr*   Zgradio.oauthr+   Zgradio.queueingr,   r-   Zgradio.route_utilsr.   Zgradio.utilsr/   r0   r1   initjoinpathas_posixZSTATIC_TEMPLATE_LIBr   r   	read_textVERSIONr4   rR   r3   envfiltersZAsyncClientr   rT   r   r\  re  r>   r>   r>   r?   <module>   s    
$

    

