
    $g8H                     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        ]/var/www/dash_apps/app1/venv/lib/python3.12/site-packages/dash/testing/application_runners.py
import_appr      sd    " %%h/
)* J   7828*=
	  s    	A$AAc                   z    e Zd ZdZdZd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                 f    || _         || _        d| _        d | _        || _        || _        d | _        y )Nr  )schemehostportstarted	keep_openstop_timeout_tmp_app_path)selfr   r   r   r   s        r   __init__zBaseDashRunner.__init__@   s5    		"(!    c                     t         NNotImplementedErrorr    argskwargss      r   startzBaseDashRunner.startI       !!r"   c                     t         r$   r%   r    s    r   stopzBaseDashRunner.stopL   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.accessibleO   s8    	LL  ""33 		s    88c                 &     | j                   |i |S r$   )r*   r'   s      r   __call__zBaseDashRunner.__call__W   s    tzz4*6**r"   c                     | S r$    r-   s    r   	__enter__zBaseDashRunner.__enter__Z   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                 R    | j                    d| j                   d| j                   S )zThe default server url.z://:)r   r   r   r-   s    r   r4   zBaseDashRunner.urlh   s'     ++c$))Adii[99r"   c                 (    t         j                  dk(  S )Nwin32)sysplatformr-   s    r   
is_windowszBaseDashRunner.is_windowsm   s    ||w&&r"   c                     | j                   S r$   )r   r-   s    r   tmp_app_pathzBaseDashRunner.tmp_app_pathq   s    !!!r"   N)http	localhost)__name__
__module____qualname____doc__
_next_portr!   r*   r.   staticmethodr5   r7   r:   rA   propertyr4   rH   rJ   r9   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 )Nr9   )superr!   list	threading_activekeys_old_threads)r    r)   	__class__s     r   r!   zKillerThread.__init__w   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)rX   rY   rZ   r\   ctypes	pythonapiPyThreadState_SetAsyncExcc_long	py_object
SystemExit
ValueError)r    	thread_idress      r   killzKillerThread.kill{   s    i//0 	<ID---""<<i(&*:*::*FC ax #6yk!BCCQw  ::MM),d !!:;;	<r"   )rM   rN   rO   r!   ri   __classcell__r]   s   @r   rU   rU   v   s    ;<r"   rU   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   )rW   r!   threadr    r   r   r]   s      r   r!   zThreadedRunner.__init__   s    9<Hr"   c                 n    | j                   j                         r| j                  |      S t        d      )NzThread is not alive.)rp   is_aliver5   r   )r    r4   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   r_   threadedServer stoppedr9   )scriptsconfigserve_locallycsscopyr   rQ   r   runre   r   r<   	Exceptionr   )optionserrorr   r)   r    s     r   r~   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$   )rt   r4   r-   s   r   <lambda>z&ThreadedRunner.start.<locals>.<lambda>   s    D77A r"   timeoutFr_   Nzthreaded server failed to start)r   rp   rs   r.   ri   rU   daemonr*   r   untilr   r   r   timesleepr   )r    r   start_timeoutr)   r~   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)rp   ri   joinr   	until_notrs   r   r   r-   s    r   r.   zThreadedRunner.stop   sG    t{{++T->->?r"   Fr   r   )	rM   rN   rO   rP   r!   rt   r*   r.   rj   rk   s   @r   rm   rm      s    
:1Ifr"   rm   c                   .     e Zd Zd fd	ZddZd Z xZS )MultiProcessRunnerc                 4    t         |   ||       d | _        y r$   rW   r!   procrq   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)NTrw   rx   r9   )ry   rz   r{   r|   r}   r~   re   r   r<   r   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$   r5   r4   r-   s   r   r   z*MultiProcessRunner.start.<locals>.<lambda>   s    4??4884 r"   r   T)	r1   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)	recursiver_   )	psutilr   r   pidchildrenri   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   )rM   rN   rO   r!   r*   r.   rj   rk   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 ro   r   rq   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: rC   z.serverposixstart dash process with %s)stdoutstderrc                  :     j                   j                        S r$   r   r-   s   r   r   z%ProcessRunner.start.<locals>.<lambda>1      ttxx8 r"   r   'process server has encountered an errorFT)loggingr   r   shlexsplitrH   r   debug
subprocessPopenPIPEr   r   r   OSErrorrf   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   	terminaterJ   ospathexistsr   shutilrmtreer   r   communicater   r   ri   )r    _excepts     r   r.   zProcessRunner.stop;  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   )rM   rN   rO   rP   r!   r*   r.   rj   rk   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 ro   r   rq   s      r   r!   zRRunner.__init__S  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/r_   \/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   rH   getenvuuiduuid4hexr   mkdirrJ   r   r   r   openwriteinspectstackreplacerealpathwarninglistdir
startswithisdirbasenamer   r   copytreer   r   r   r   r   r   r   r   rf   r   r    r   r   r   r   fpentry_assetsassetr   r(   s   `           r   r*   zRRunner.startX  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rM   rN   rO   r!   r*   rj   rk   s   @r   r   r   R  s    
Xr"   r   c                   (     e Zd Zd fd	ZddZ xZS )JuliaRunnerc                 6    t         |   ||       d | _        y ro   r   rq   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   r_   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   rk   s   @r   r   r     s    
Yr"   r   )r   )"rF   r   r   r   r   rY   r   r   r   r   r`   r	   r0   r   r   dash.testing.errorsr   r   r   r   dash.testingr   	getLoggerrM   r   r   r   ThreadrU   rm   r   r   r   r   r9   r"   r   <module>r     s    
 	               			8	$88" 8"v<9## <.G^ GT/ /dF/N F/R^m ^B_- _r"   