o
    dG                     @   s$  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Zd dlZd dlZd dlZd dlmZmZmZmZ d dlmZ eeZdddZG dd dZG d	d
 d
ejZG dd deZG dd deZG dd deZG dd deZ G dd deZ!dS )    N)NoAppFoundErrorTestingTimeoutErrorServerCloseErrorDashAppLoadingError)waitappc              
   C   sL   zt | }|| }W |S  ty% } ztd td|  |d}~ww )a
  Import a dash application from a module. The import path is in dot
    notation to the module. The variable named app will be returned.

    :Example:

        >>> app = import_app("my_app.app")

    Will import the application in module `app` of the package `my_app`.

    :param app_file: Path to the app (dot-separated).
    :type app_file: str
    :param application_name: The name of the dash application instance.
    :raise: dash_tests.errors.NoAppFoundError
    :return: App from module.
    :rtype: dash.Dash
    zthe app name cannot be foundz$No dash `app` instance was found in N)runpy
run_moduleKeyErrorlogger	exceptionr   )app_fileapplication_name
app_moduler   app_name_missing r   e/var/www/html/visualizacion-main/env/lib/python3.10/site-packages/dash/testing/application_runners.py
import_app   s   


r   c                   @   st   e Zd ZdZdZdd Zdd Zdd Zed	d
 Z	dd Z
dd Zdd Zedd Zedd Zedd ZdS )BaseDashRunnerz4Base context manager class for running applications.i  c                 C   s"   d| _ d | _|| _|| _d | _d S )Nr  )portstarted	keep_openstop_timeout_tmp_app_pathselfr   r   r   r   r   __init__@   s
   
zBaseDashRunner.__init__c                 O      t NNotImplementedErrorr   argskwargsr   r   r   startG      zBaseDashRunner.startc                 C   r   r   r    r   r   r   r   stopJ   r&   zBaseDashRunner.stopc                 C   s*   zt |  W dS  t jjy   Y dS w )NFT)requestsget
exceptionsRequestException)urlr   r   r   
accessibleM   s   zBaseDashRunner.accessiblec                 O   s   | j |i |S r   )r%   r"   r   r   r   __call__U   s   zBaseDashRunner.__call__c                 C   s   | S r   r   r'   r   r   r   	__enter__X   r&   zBaseDashRunner.__enter__c              
   C   s^   | j r(| js(ztd |   W n ty' } z
td| j d|d }~ww td d S )Nzkilling the app runnerzCannot stop server within z	s timeoutz__exit__ complete)r   r   r   infor(   r   r   r   )r   exc_typeexc_val	tracebackcannot_stop_serverr   r   r   __exit__[   s   
zBaseDashRunner.__exit__c                 C   s   d| j  S )zThe default server url.zhttp://localhost:)r   r'   r   r   r   r-   f   s   zBaseDashRunner.urlc                 C   s
   t jdkS )Nwin32)sysplatformr'   r   r   r   
is_windowsk   s   
zBaseDashRunner.is_windowsc                 C   s   | j S r   )r   r'   r   r   r   tmp_app_patho   s   zBaseDashRunner.tmp_app_pathN)__name__
__module____qualname____doc__
_next_portr   r%   r(   staticmethodr.   r/   r0   r6   propertyr-   r:   r;   r   r   r   r   r   ;   s"    


r   c                       s$   e Zd Z fddZdd Z  ZS )KillerThreadc                    s&   t  jdi | ttj | _d S )Nr   )superr   list	threading_activekeys_old_threads)r   r$   	__class__r   r   r   u   s   zKillerThread.__init__c                 C   st   t tjD ]2}|| jv rqtjt|tt	}|dkr%t
d| |dkr7tjt|d  t	dqd S )Nr   zInvalid thread id:    zStopping thread failure)rE   rF   rG   rI   ctypes	pythonapiPyThreadState_SetAsyncExcc_long	py_object
SystemExit
ValueError)r   	thread_idresr   r   r   killy   s   

zKillerThread.kill)r<   r=   r>   r   rV   __classcell__r   r   rJ   r   rC   t   s    rC   c                       s<   e Zd ZdZd fdd	Zdd Zddd	Zd
d Z  ZS )ThreadedRunnerzkRuns a dash application in a thread.

    This is the default flavor to use in dash integration tests.
    F   c                       t  j||d d | _d S N)r   r   )rD   r   threadr   rJ   r   r   r         
zThreadedRunner.__init__c                 C   s   | j  r
| |S td)NzThread is not alive.)r\   is_aliver.   r   )r   r-   r   r   r   running_and_accessible   s   

z%ThreadedRunner.running_and_accessiblec              
      s    fdd}d}j sp|dk rpz4jr$j r  nj  t|d_dj_j  tj	fdd|d	 j _ W n# t
yh } zt| d
_ |d7 }td W Y d}~nd}~ww j sp|dk sj _ j s}tddS )z)Start the app server in threading flavor.c               
      s   d j j_d jj_ } dvr"tj | d< _t jd7  _n| d _z jdddi|  W d S  t	yC   t
d Y d S  tyU } zt
| |d }~ww )NTr   rL   threadedServer stoppedr   )scriptsconfigserve_locallycsscopyr   r@   r   runrR   r   r1   	Exceptionr   optionserrorr   r$   r   r   r   rg      s    



z!ThreadedRunner.start.<locals>.runr   rY   targetTc                            jS r   )r_   r-   r   r'   r   r   <lambda>       z&ThreadedRunner.start.<locals>.<lambda>timeoutFrL   Nzthreaded server failed to start)r   r\   r^   r(   rV   rC   daemonr%   r   untilrh   r   r   timesleepr   )r   r   start_timeoutr$   rg   retrieserrr   rl   r   r%      s6   




zThreadedRunner.startc                 C   s0   | j   | j   t| j j| j d| _d S )NF)r\   rV   joinr   	until_notr^   r   r   r'   r   r   r   r(      s   


zThreadedRunner.stopFrY   rY   )	r<   r=   r>   r?   r   r_   r%   r(   rW   r   r   rJ   r   rX      s    
3rX   c                       s0   e Zd Zd	 fdd	Zd
ddZdd Z  ZS )MultiProcessRunnerFrY   c                    s   t  || d | _d S r   rD   r   procr   rJ   r   r   r      s   
zMultiProcessRunner.__init__c                    sT    dd_ fdd}tj|d_j  tjfdd|d d	_d S )
Nr   r   c               
      sv   d j j_d jj_ } z jdddi|  W d S  ty(   td   t	y: } zt
| |d }~ww )NTr`   ra   r   )rb   rc   rd   re   rf   rg   rR   r   r1   rh   r   ri   )r   r$   r   r   rn      s   



z(MultiProcessRunner.start.<locals>.targetrm   c                      ro   r   r.   r-   r   r'   r   r   rp      rq   z*MultiProcessRunner.start.<locals>.<lambda>rr   T)	r*   r   multiprocessProcessr   r%   r   ru   r   )r   r   rx   r$   rn   r   rl   r   r%      s   

zMultiProcessRunner.startc              	   C   s   t | jj}|jddD ]}z|  W q t jy   Y qw z|  W n
 t jy0   Y nw z|d W d S  t jt jfyG   Y d S w )NT)	recursiverL   )	psutilr   r   pidchildrenrV   NoSuchProcessr   TimeoutExpired)r   processr   r   r   r   r(      s"   zMultiProcessRunner.stopr}   r~   )r<   r=   r>   r   r%   r(   rW   r   r   rJ   r   r      s    
r   c                       s>   e Zd ZdZd fdd	Z					dd	d
Zdd Z  ZS )ProcessRunnerz}Runs a dash application in a waitress-serve subprocess.

    This flavor is closer to production environment but slower.
    FrY   c                    rZ   r[   r   r   rJ   r   r   r     r]   zProcessRunner.__init__Nr   r   c              	      s   |s|st d dS | _tj|r|nd| d| d| d j d}td| ztj	|tj
tj
d	 _tj fd
d|d W n ttfy[   td d _   Y dS w d _dS )z7Start the server with waitress-serve in process flavor.zAthe process runner needs to start with at least one valid commandNz waitress-serve --listen=0.0.0.0: :z.serverposixstart dash process with %s)stdoutstderrc                      ro   r   r   r   r'   r   r   rp   /  rq   z%ProcessRunner.start.<locals>.<lambda>rr   'process server has encountered an errorFT)loggingrk   r   shlexsplitr:   r   debug
subprocessPopenPIPEr   r   ru   OSErrorrS   r   r   r(   )r   r   r   raw_commandr   rx   r#   r   r'   r   r%     s2   	


zProcessRunner.startc                 C   s   | j rMz1td| j j | j   | jr(tj| jr(t	d| j t
| j tj}| j j| jd W n |yL   td | j   | j   Y nw td d S )Nzproc.terminate with pid %szremoving temporary app path %srr   zPsubprocess terminate not success, trying to kill the subprocess in a safe mannerzprocess stop completes!)r   r   r1   r   	terminater;   ospathexistsr   shutilrmtreer   r   communicater   r   rV   )r   _exceptr   r   r   r(   9  s&   


zProcessRunner.stopr}   )Nr   Nr   rY   )r<   r=   r>   r?   r   r%   r(   rW   r   r   rJ   r   r     s    
'r   c                       (   e Zd Zd	 fdd	Zd
ddZ  ZS )RRunnerFrY   c                    rZ   r[   r   r   rJ   r   r   r   Q  r]   zRRunner.__init__   Nc              	      s  t j|rt j|r st j| td  nt jjs#dnt 	dt
 j_zt j W n tyF   tdj Y nw t jjd}td td| td td	| t|d
dd}|| W d   n1 s|w   Y  |} st D ] }d|d ddvrt jt j|d  td   nq rtd   fddt  D }|D ]6}t jjt j|}	t j|	rtd|	 t|	 td|j t||	 tdt |	 qntd td| tj dt j| dj d}
td|
 z t!j"|
t!j#t!j#jr)jn d_$t%j&fd d!|d" W n tt'fyO   td# d$_(Y dS w d%_(dS )&z-Start the server with subprocess and Rscript.z&RRunner inferred cwd from app path: %s/tmpTEMPcannot make temporary folder %szapp.Rz$RRunner start => app is R code chunkz+make a temporary R file for execution => %szcontent of the dashR app%swutf-8encodingN/dash/testing/rL   \/get cwd from inspect => %sz3RRunner inferred cwd from the Python call stack: %sc                    :   g | ]}| d stjtj |rtj |qS __
startswithr   r   isdirr{   .0_cwdr   r   
<listcomp>      z!RRunner.start.<locals>.<listcomp>delete existing target %scopying %s => %scopied with %szRRunner found no cwd in the Python call stack. You may wish to specify an explicit working directory using something like: dashr.run_server(app, cwd=os.path.dirname(__file__))z Run dashR app with Rscript => %szRscript -e 'source("z")'r   r   r   r   r   c                      ro   r   r   r   r'   r   r   rp     rq   zRRunner.start.<locals>.<lambda>rr   r   FT)r   r   isfiler   dirnamer   r1   r{   r:   getenvuuiduuid4hexr   mkdirr;   r   r   r   openwriteinspectstackreplacerealpathwarninglistdirbasenamer   r   copytreer   r   r   r   r   r   r   ru   rS   r   r   r   rx   r   r   fpentryassetsassetrn   r#   r   r   r   r   r%   V  s   






zRRunner.startr}   )r   Nr<   r=   r>   r   r%   rW   r   r   rJ   r   r   P      r   c                       r   )JuliaRunnerFrY   c                    rZ   r[   r   r   rJ   r   r   r     r]   zJuliaRunner.__init__   Nc              	      s  t j|rt j|r st j| td  nt jjs#dnt 	dt
 j_zt j W n tyF   tdj Y nw t jjd}td td| td td	| t|d
dd}|| W d   n1 s|w   Y  |} st D ] }d|d ddvrt jt j|d  td   nq rtd   fddt  D }|D ]6}t jjt j|}	t j|	rtd|	 t|	 td|j t||	 tdt |	 qntd td| tj dt j| j d}
td|
 z t!j"|
t!j#t!j#jr(jn d_$t%j&fdd |d! W n tt'fyN   td" d#_(Y dS w d$_(dS )%z+Start the server with subprocess and julia.z*JuliaRunner inferred cwd from app path: %sr   r   r   zapp.jlz,JuliaRunner start => app is Julia code chunkz/make a temporary Julia file for execution => %szcontent of the Dash.jl appr   r   r   r   Nr   rL   r   r   r   z7JuliaRunner inferred cwd from the Python call stack: %sc                    r   r   r   r   r   r   r   r     r   z%JuliaRunner.start.<locals>.<listcomp>r   r   r   zJuliaRunner found no cwd in the Python call stack. You may wish to specify an explicit working directory using something like: dashjl.run_server(app, cwd=os.path.dirname(__file__))z Run Dash.jl app with julia => %szjulia --project r   zstart Dash.jl process with %sr   c                      ro   r   r   r   r'   r   r   rp   	  rq   z#JuliaRunner.start.<locals>.<lambda>rr   r   FTr   r   r   r   r   r%     s   






zJuliaRunner.startr}   )r   Nr   r   r   rJ   r   r     r   r   )r   )"r8   r   rv   r   r   rF   r   r   r   r   rM   r   r)   r   r   dash.testing.errorsr   r   r   r   dash.testingr   	getLoggerr<   r   r   r   ThreadrC   rX   r   r   r   r   r   r   r   r   <module>   s4    

9J2Ia