
    VfG                     x   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j,                  e      ZddZ G d d      Z G d dej6                        Z G d	 d
e      Z G d de      Z G d de      Z G d de      Z  G d de      Z!y)    N)NoAppFoundErrorTestingTimeoutErrorServerCloseErrorDashAppLoadingError)waitc                     	 t        j                  |       }||   }|S # t        $ r)}t        j	                  d       t        d|        |d}~ww xY 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_moduleappapp_name_missings        i/var/www/html/software/conda/envs/catlas/lib/python3.12/site-packages/dash/testing/application_runners.py
import_appr      sd    " %%h/
)* J   7828*=
	  s    	A$AAc                   x    e Zd ZdZdZd Zd Zd Zed        Z	d Z
d Zd	 Zed
        Zed        Zed        Zy)BaseDashRunnerz4Base context manager class for running applications.i  c                 J    d| _         d | _        || _        || _        d | _        y )Nr  )portstarted	keep_openstop_timeout_tmp_app_path)selfr   r   s      r   __init__zBaseDashRunner.__init__@   s'    	"(!    c                     t         NNotImplementedErrorr   argskwargss      r   startzBaseDashRunner.startG       !!r    c                     t         r"   r#   r   s    r   stopzBaseDashRunner.stopJ   r)   r    c                 v    	 t        j                  |        y# t         j                  j                  $ r Y yw xY w)NFT)requestsget
exceptionsRequestException)urls    r   
accessiblezBaseDashRunner.accessibleM   s8    	LL  ""33 		s    88c                 &     | j                   |i |S r"   )r(   r%   s      r   __call__zBaseDashRunner.__call__U   s    tzz4*6**r    c                     | S r"    r+   s    r   	__enter__zBaseDashRunner.__enter__X   s    r    c                     | j                   r2| j                  s&	 t        j                  d       | j	                          t        j                  d       y # t
        $ r}t        d| j                   d      |d }~ww xY w)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_servers        r   __exit__zBaseDashRunner.__exit__[   sn    <<*45		
 	'(	 ' *&01B1B0C9M)**s   %A 	A=A88A=c                      d| j                    S )zThe default server url.zhttp://localhost:)r   r+   s    r   r2   zBaseDashRunner.urlf   s     #499+..r    c                 (    t         j                  dk(  S )Nwin32)sysplatformr+   s    r   
is_windowszBaseDashRunner.is_windowsk   s    ||w&&r    c                     | j                   S r"   )r   r+   s    r   tmp_app_pathzBaseDashRunner.tmp_app_patho   s    !!!r    N)__name__
__module____qualname____doc__
_next_portr   r(   r,   staticmethodr3   r5   r8   r?   propertyr2   rE   rG   r7   r    r   r   r   ;   sx    >J"""  +	) / / ' ' " "r    r   c                   $     e Zd Z fdZd Z xZS )KillerThreadc                 |    t        |   di | t        t        j                  j                               | _        y )Nr7   )superr   list	threading_activekeys_old_threads)r   r'   	__class__s     r   r   zKillerThread.__init__u   s/    "6" !2!2!7!7!9:r    c                    t        t        j                        D ]  }|| j                  v rt        j
                  j                  t	        j                  |      t	        j                  t                    }|dk(  rt        d|       |dkD  sut        j
                  j                  t	        j                  |      d        t        d       y )Nr   zInvalid thread id:    zStopping thread failure)rS   rT   rU   rW   ctypes	pythonapiPyThreadState_SetAsyncExcc_long	py_object
SystemExit
ValueError)r   	thread_idress      r   killzKillerThread.killy   s    i//0 	<ID---""<<i(&*:*::*FC ax #6yk!BCCQw  ::MM),d !!:;;	<r    )rH   rI   rJ   r   rd   __classcell__rX   s   @r   rP   rP   t   s    ;<r    rP   c                   8     e Zd ZdZd fd	Zd ZddZd Z xZS )ThreadedRunnerzkRuns a dash application in a thread.

    This is the default flavor to use in dash integration tests.
    c                 6    t         |   ||       d | _        y N)r   r   )rR   r   threadr   r   r   rX   s      r   r   zThreadedRunner.__init__   s    9<Hr    c                 n    | j                   j                         r| j                  |      S t        d      )NzThread is not alive.)rk   is_aliver3   r   )r   r2   s     r   running_and_accessiblez%ThreadedRunner.running_and_accessible   s-    ;;!??3''!"899r    c                      fd}d} j                   s|dk  r	  j                  rE j                  j                         r j                          n j                  j	                          t        |       _        d j                  _         j                  j                          t        j                   fd|        j                  j                          _          j                   s|dk  rى j                  j                          _          j                   st        d      y
# t        $ r@}t        j                  |       d _         |d	z  }t        j                  d	       Y d
}~d
}~ww xY w)z)Start the app server in threading flavor.c                     dj                   j                  _        dj                  j                  _        j	                         } dvr4t
        j                  x| d<   _        t
        xj                  dz  c_        n
| d   _        	  j                  dddi|  y # t        $ r t        j                  d       Y y t        $ r}t        j                  |       |d }~ww xY w)NTr   rZ   threadedServer stoppedr7   )scriptsconfigserve_locallycsscopyr   rL   r   runr`   r   r:   	Exceptionr   )optionserrorr   r'   r   s     r   ry   z!ThreadedRunner.start.<locals>.run   s    /3CKK,+/CGGNN(kkmGV#.<.G.GG$)))Q.)#FO	111 .,-   's   B   C$ C$CC$r      targetTc                  :     j                   j                        S r"   )ro   r2   r+   s   r   <lambda>z&ThreadedRunner.start.<locals>.<lambda>   s    D77A r    timeoutFrZ   Nzthreaded server failed to start)r   rk   rn   r,   rd   rP   daemonr(   r   untilrz   r   r   timesleepr   )r   r   start_timeoutr'   ry   retrieserrs   `` `   r   r(   zThreadedRunner.start   s   	( ,,7Q;;;{{++-		((**#6%)"!!#

A=  ${{335 ,,7Q;, {{++-||%&GHH     %$1

1	s   CD. .	E776E22E7c                     | j                   j                          | j                   j                          t        j                  | j                   j
                  | j                         d| _        y )NF)rk   rd   joinr   	until_notrn   r   r   r+   s    r   r,   zThreadedRunner.stop   sG    t{{++T->->?r    Fr}   r}   )	rH   rI   rJ   rK   r   ro   r(   r,   re   rf   s   @r   rh   rh      s    
:1Ifr    rh   c                   .     e Zd Zd fd	ZddZd Z xZS )MultiProcessRunnerc                 4    t         |   ||       d | _        y r"   rR   r   procrl   s      r   r   zMultiProcessRunner.__init__   s    L1	r    c                      j                  dd       _        fd}t        j                  |       _         j                  j                          t        j                   fd|       d _        y )Nr   r   c                  H   dj                   j                  _        dj                  j                  _        j	                         } 	  j
                  dddi|  y # t        $ r t        j                  d        t        $ r}t        j                  |       |d }~ww xY w)NTrr   rs   r7   )rt   ru   rv   rw   rx   ry   r`   r   r:   rz   r   )r{   r|   r   r'   s     r   r   z(MultiProcessRunner.start.<locals>.target   s    /3CKK,+/CGGNN(kkmG111 ,-   's   	A 'B!BB!r~   c                  :     j                   j                        S r"   r3   r2   r+   s   r   r   z*MultiProcessRunner.start.<locals>.<lambda>   s    4??4884 r    r   T)	r/   r   multiprocessProcessr   r(   r   r   r   )r   r   r   r'   r   s   `` ` r   r(   zMultiProcessRunner.start   sR    JJvt,		 !((7			

4mLr    c                    t        j                  | j                  j                        }|j	                  d      D ]  }	 |j                           	 |j                          	 |j                  d       y # t         j                  $ r Y Ow xY w# t         j                  $ r Y Aw xY w# t         j                  t         j                  f$ r Y y w xY w)NT)	recursiverZ   )	psutilr   r   pidchildrenrd   NoSuchProcessr   TimeoutExpired)r   processr   s      r   r,   zMultiProcessRunner.stop   s    ../$$t$4 	D				LLN	LLO '' 
 ## 		
 %%v';';< 		s6    A6B $B( 6BBB%$B%(#CCr   r   )rH   rI   rJ   r   r(   r,   re   rf   s   @r   r   r      s    
0r    r   c                   <     e Zd ZdZd fd	Z	 	 	 	 	 ddZd Z xZS )ProcessRunnerz}Runs a dash application in a waitress-serve subprocess.

    This flavor is closer to production environment but slower.
    c                 6    t         |   ||       d | _        y rj   r   rl   s      r   r   zProcessRunner.__init__      9<H	r    c           	          |s|st        j                  d       y| _        t        j                  |r|nd| d| d| d j
                         }t        j                  d|       	 t        j                  |t        j                  t        j                  	       _        t        j                   fd
|       d _        y# t        t        f$ r/ t        j!                  d       d _         j%                          Y yw xY w)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                  :     j                   j                        S r"   r   r+   s   r   r   z%ProcessRunner.start.<locals>.<lambda>/      ttxx8 r    r   'process server has encountered an errorFT)loggingr|   r   shlexsplitrE   r   debug
subprocessPopenPIPEr   r   r   OSErrorra   r   r   r,   )r   r   r   raw_commandr   r   r&   s   `      r   r(   zProcessRunner.start  s     kMMS 	{{ 3D6:,aHXGYY`aoo%	
 	148	"((Z__Z__DI JJ8-P  $ 	FG DLIIK		s   *AC ;DDc                    | j                   r	 t        j                  d| j                   j                         | j                   j	                          | j
                  rht        j                  j                  | j
                        r?t        j                  d| j
                         t        j                  | j
                         t        j                  }| j                   j                  | j                         t        j                  d       y # $ rL t        j!                  d       | j                   j#                          | j                   j                          Y fw xY w)Nzproc.terminate with pid %szremoving temporary app path %sr   zPsubprocess terminate not success, trying to kill the subprocess in a safe mannerzprocess stop completes!)r   r   r:   r   	terminaterG   ospathexistsr   shutilrmtreer   r   communicater   r   rd   )r   _excepts     r   r,   zProcessRunner.stop9  s    99(8$))--H		##%$$8I8I)JLL!A4CTCTUMM$"3"34$33		%% -- &  	-.  (  6 		 		%%'(s   C.D AE#"E#r   )Nr   Nr   r}   )rH   rI   rJ   rK   r   r(   r,   re   rf   s   @r   r   r     s)    
 %N/r    r   c                   (     e Zd Zd fd	ZddZ xZS )RRunnerc                 6    t         |   ||       d | _        y rj   r   rl   s      r   r   zRRunner.__init__Q  r   r    c           	      v
    t         j                  j                  |      rYt         j                  j                  |      r:|st         j                  j	                  |      }t
        j                  d|       njt         j                  j                   j                  sdnt        j                  d      t        j                         j                         _        	 t        j                   j                         t         j                  j                   j                  d      }t
        j                  d       t
        j                  d|       t
        j%                  d       t
        j%                  d	|       t'        |d
d      5 }|j)                  |       ddd       |}|st+        j,                         D ]p  }d|d   j/                  dd      vst         j                  j	                  t         j                  j1                  |d               }t
        j3                  d|        n |rt
        j                  d|       t        j4                  |      D cg c]p  }|j7                  d      s]t         j                  j9                  t         j                  j                  ||            r t         j                  j                  ||      r }}|D ]  }	t         j                  j                   j                  t         j                  j;                  |	            }
t         j                  j                  |
      r+t
        j%                  d|
       t=        j>                  |
       t
        j%                  d|	 j                         t=        j@                  |	|
       t
        j%                  dt        j4                  |
              nt
        j3                  d       t
        j                  d|       tC        jD                  dt         j                  j1                  |       d j                         }t
        j%                  d|       	 tG        jH                  |tF        jJ                  tF        jJ                   j                  r j                  n|       _&        tO        jP                   fd|        d# _*        y# t         $ r$ t
        j#                  d j                         Y w xY w# 1 sw Y   ^xY wc c}w # t         tR        f$ r t
        j#                  d!       d" _*        Y yw xY w)$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/rZ   \/get cwd from inspect => %sz3RRunner inferred cwd from the Python call stack: %s__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   cwdc                  :     j                   j                        S r"   r   r+   s   r   r   zRRunner.start.<locals>.<lambda>  r   r    r   r   FT+r   r   isfiler   dirnamer   r:   r   rE   getenvuuiduuid4hexr   mkdirrG   r   r   r   openwriteinspectstackreplacerealpathwarninglistdir
startswithisdirbasenamer   r   copytreer   r   r   r   r   r   r   r   ra   r   r   r   r   r   r   fpentry_assetsassetr   r&   s   `           r   r(   zRRunner.startV  s    77>>#277>>##6ggooc*DcJ "$"oo299V3DdjjlFVFV"DW**+ 77<< 1 17;DKK>?KKEtLLL34LLs#dC'2 b C $]]_ E'uQx/?/?c/JJ ggoobgg.>.>uQx.HI'CSI	
 QSVW  ZZ_<<-"''--SRS@T2U GGLLa(  $ GEWW\\$*;*;RWW=M=Me=TUFww~~f-%@&If-LL!3UD<M<MNOOE62LL!12::f3EFG K 	6<{{#BGG$4$4S$9#:$?oo%
 	148	"((!!)-):):D%%	DI JJ8-P Q  W  !BDDUDUVW "R $ 	FG DL	s8   S 
S8A5TA,T
 )S54S58T
+T87T8r   )   NrH   rI   rJ   r   r(   re   rf   s   @r   r   r   P  s    
Xr    r   c                   (     e Zd Zd fd	ZddZ xZS )JuliaRunnerc                 6    t         |   ||       d | _        y rj   r   rl   s      r   r   zJuliaRunner.__init__  r   r    c           	      t
    t         j                  j                  |      rYt         j                  j                  |      r:|st         j                  j	                  |      }t
        j                  d|       njt         j                  j                   j                  sdnt        j                  d      t        j                         j                         _        	 t        j                   j                         t         j                  j                   j                  d      }t
        j                  d       t
        j                  d|       t
        j%                  d       t
        j%                  d	|       t'        |d
d      5 }|j)                  |       ddd       |}|st+        j,                         D ]p  }d|d   j/                  dd      vst         j                  j	                  t         j                  j1                  |d               }t
        j3                  d|        n |rt
        j                  d|       t        j4                  |      D cg c]p  }|j7                  d      s]t         j                  j9                  t         j                  j                  ||            r t         j                  j                  ||      r }}|D ]  }	t         j                  j                   j                  t         j                  j;                  |	            }
t         j                  j                  |
      r+t
        j%                  d|
       t=        j>                  |
       t
        j%                  d|	 j                         t=        j@                  |	|
       t
        j%                  dt        j4                  |
              nt
        j3                  d       t
        j                  d|       tC        jD                  dt         j                  j1                  |        j                         }t
        j%                  d|       	 tG        jH                  |tF        jJ                  tF        jJ                   j                  r j                  n|       _&        tO        jP                   fd|       d" _*        y# t         $ r$ t
        j#                  d j                         Y w xY w# 1 sw Y   ]xY wc c}w # t         tR        f$ r t
        j#                  d        d! _*        Y yw xY w)#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   rZ   r   r   r   z7JuliaRunner inferred cwd from the Python call stack: %sr   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                  :     j                   j                        S r"   r   r+   s   r   r   z#JuliaRunner.start.<locals>.<lambda>	  r   r    r   r   FTr   r   s   `           r   r(   zJuliaRunner.start  s    77>>#277>>##6ggooc*H#N "$"oo299V3DdjjlFVFV"DW**+ 77<< 1 18<DKKFGKKI4PLL56LLs#dC'2 b C $]]_ E'uQx/?/?c/JJ ggoobgg.>.>uQx.HI'CSI	
 Ms  ZZ_<<-"''--SRS@T2U GGLLa(  $ GEWW\\$*;*;RWW=M=Me=TUFww~~f-%@&If-LL!3UD<M<MNOOE62LL!12::f3EFG L 	6<{{rww//456$//>Q
 	4d;	"((!!)-):):D%%	DI JJ8-P S  W  !BDDUDUVW &P $ 	FG DL	s8   S 
S7A5TA,T	 )S43S47T	+T76T7r   )   Nr   rf   s   @r   r   r     s    
Yr    r   )r   )"rC   r   r   r   r   rT   r   r   r   r   r[   r	   r.   r   r   dash.testing.errorsr   r   r   r   dash.testingr   	getLoggerrH   r   r   r   ThreadrP   rh   r   r   r   r   r7   r    r   <module>r     s    
 	               			8	$86" 6"r<9## <.G^ GT/ /dF/N F/R^m ^B_- _r    