
    ^h                    <   S r SSKJr  SSKrSSKrSSKrSSKrSSKJrJ	r	  SSK
Jr  SSKJr  SSKJrJrJrJr  SSKrSSKJr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKJr  SSK J!r!J"r"J#r#J$r$  SSK%J&r&J'r'J(r(J)r)  SSK*J+r+J,r,  SSK-J.r.J/r/J0r0  SSK1J2r2  SSK3J4r4  SSK5J6r6J7r7  \(       a  SSK8J9r9   " S S\.5      r: " S S\5      r; " S S\25      r< " S S\/5      r=\R|                  " \=5         " S  S!\	5      r? " S" S#\?5      r@ " S$ S%\5      rA\R|                  " \A5        g)&zKernel gateway managers.    )annotationsN)EmptyQueue)Thread)	monotonic)TYPE_CHECKINGAnyOptionalcast)AsyncKernelClient)KernelClientABC)KernelSpecManager)KernelManagerABC)ensure_async)web)json_decodejson_encode
url_escapeutf8)DottedObjectNameInstanceTypedefault   )UTCutcnow)AsyncMappingKernelManagerServerKernelManageremit_kernel_action_event)SessionManager)url_path_join   )GatewayClientgateway_request)Loggerc                     ^  \ rS rSr% Sr0 rS\S'   \" S5      S 5       r\" S5      S 5       r	U 4S	 jr
S
 rSSS.S jrS rS rSS jrSS jrS rSS jrU 4S jrSrU =r$ )GatewayMappingKernelManager(   z[Kernel manager that supports remote kernels hosted by Jupyter Kernel or Enterprise Gateway.zdict[str, GatewayKernelManager]_kernelskernel_manager_classc                    g)Nz4jupyter_server.gateway.managers.GatewayKernelManager selfs    Y/home/james-whalen/.local/lib/python3.13/site-packages/jupyter_server/gateway/managers.py_default_kernel_manager_class9GatewayMappingKernelManager._default_kernel_manager_class.   s    E    shared_contextc                    gNFr,   r-   s    r/   _default_shared_context3GatewayMappingKernelManager._default_shared_context2       r2   c                   > [         TU ]  " S0 UD6  [        [        R                  " 5       R
                  =(       d    S[        R                  " 5       R                  =(       d    S5      U l        g)z,Initialize a gateway mapping kernel manager. Nr,   )super__init__r!   r#   instanceurlkernels_endpointkernels_urlr.   kwargs	__class__s     r/   r<   $GatewayMappingKernelManager.__init__6   sN    "6"(""$((.B0F0F0H0Y0Y0_]_
r2   c                Z     U R                   R                  U5      $ ! [         a     gf = f)zCComplete override since we want to be more tolerant of missing keysN)r)   popKeyError)r.   	kernel_ids     r/   remove_kernel)GatewayMappingKernelManager.remove_kernel=   s.    	==$$Y// 		s    
**N)rH   pathc               j  #    U R                   R                  SU SU S35        Uc  Ub  U R                  U5      US'   U R                  X R                   S9nUR                  " SSU0UD6I Sh  vN   UR
                  nX@R                  U'   U R                  (       d  U R                  5         U$  NA7f)	ag  Start a kernel for a session and return its kernel_id.

Parameters
----------
kernel_id : uuid
    The uuid to associate the new kernel with. If this
    is not None, this kernel will be persistent whenever it is
    requested.
path : API path
    The API path (unicode, '/' delimited) for the cwd.
    Will be transformed to an OS path relative to root_dir.
z Request start kernel: kernel_id=z, path=''Ncwd)parentlogrH   r,   )	rP   infocwd_for_pathkernel_manager_factorystart_kernelrH   r)   _initialized_cullerinitialize_culler)r.   rH   rK   rB   kms        r/   rT   (GatewayMappingKernelManager.start_kernelD   s      	88D6QRST!1 --d3F5M(((((Coo<	<V<<<LL	#%i ''""$ 	=s   A-B3/B10AB3c                l   #    SnU R                  [        U5      5      nU(       a  UR                  nU$ 7f)zReturn a dictionary of kernel information described in the
JSON standard model.

Parameters
----------
kernel_id : uuid
    The uuid of the kernel.
N)
get_kernelstrkernel)r.   rH   modelrW   s       r/   kernel_model(GatewayMappingKernelManager.kernel_model`   s/      __S^,IIEs   24c                ^  #    U R                   R                  SU R                   35        [        U R                  SS9I Sh  vN n[	        UR
                  5      n0 nU HC  nUS   nX`R                  ;   d  M  U R                  U   R                  U5      I Sh  vN   XTU'   ME     U R                  R                  5       n/ nU H  nXd;  d  M
  U R                   R                  SU S35         U R                  U   R                  5       I Sh  vN nU(       a  XTU'   M\  U R                   R                  SU S35        U R                  R                  US5        UR                  U5        M     [        UR                  5       5      $  GNH N N! [        R                   a    Sn Nf = f7f)	zGet a list of running kernels from the Gateway server.

We'll use this opportunity to refresh the models in each of
the kernels we're managing.
zRequest list kernels: GETmethodNidzKernel zH not present in the list of kernels - possibly culled on Gateway server.z6 no longer active - probably culled on Gateway server.)rP   debugr@   r$   r   bodyr)   refresh_modelcopywarningr   	HTTPErrorrF   appendlistvalues)	r.   rB   responsekernelskernel_modelsr]   kidour_kernels
culled_idss	            r/   list_kernels(GatewayMappingKernelManager.list_kernelso   s     	/0@0@/ABC()9)9%HHhmm, E+Cmm#mmC(66u===%*c"	  mm((*
C'  cU"jk! #'--"4"B"B"DDE ).#&HH$$!#&\] MM%%c40%%c*; < M((*++W I >0 E}} ! E!sg   A F-F
2F-9!F-F0F-F-/ FFFA7F-F-FF*'F-)F**F-c                   #    U R                  U5      n[        UR                  X#S95      I Sh  vN   U R                  U5        g N7f)a  Shutdown a kernel by its kernel uuid.

Parameters
==========
kernel_id : uuid
    The id of the kernel to shutdown.
now : bool
    Shutdown the kernel immediately (True) or gracefully (False)
restart : bool
    The purpose of this shutdown is to restart the kernel (True)
)nowrestartN)rZ   r   shutdown_kernelrI   )r.   rH   rw   rx   rW   s        r/   ry   +GatewayMappingKernelManager.shutdown_kernel   sE      __Y'2--#-GHHH9% 	Is   -AAAc                |   #    U R                  U5      n[        UR                  " SSU0UD65      I Sh  vN   g N7f)zrRestart a kernel by its kernel uuid.

Parameters
==========
kernel_id : uuid
    The id of the kernel to restart.
rw   Nr,   )rZ   r   restart_kernel)r.   rH   rw   rB   rW   s        r/   r|   *GatewayMappingKernelManager.restart_kernel   s6      __Y'2,,???@@@s   2<:<c                t   #    U R                  U5      n[        UR                  5       5      I Sh  vN   g N7f)zvInterrupt a kernel by its kernel uuid.

Parameters
==========
kernel_id : uuid
    The id of the kernel to interrupt.
N)rZ   r   interrupt_kernel)r.   rH   rB   rW   s       r/   r   ,GatewayMappingKernelManager.interrupt_kernel   s,      __Y'2..0111s   .868c                   #    [        U R                  5      nU HE  nU R                  U5      n[        UR	                  US95      I Sh  vN   U R                  U5        MG     g N7f)zShutdown all kernels.)rw   N)rl   r)   rZ   r   ry   rI   )r.   rw   kidsrH   rW   s        r/   shutdown_all(GatewayMappingKernelManager.shutdown_all   sX     DMM"I+Br11c1:;;;y) ;s   AA&	A$
A&c                r   >#    U R                  5       I Sh  vN   [        TU ]	  5       I Sh  vN   g N N7f)z@Override cull_kernels, so we can be sure their state is current.N)rt   r;   cull_kernelsr.   rC   s    r/   r   (GatewayMappingKernelManager.cull_kernels   s1     !!!g"$$$ 	"$s   737577)r@   FFF)__name__
__module____qualname____firstlineno____doc__r)   __annotations__r   r0   r6   r<   rI   rT   r^   rt   ry   r|   r   r   r   __static_attributes____classcell__rC   s   @r/   r'   r'   (   s    e 13H-2#$F %F  
 /3 82,h& 	A	2*% %r2   r'   c                  d   ^  \ rS rSrSrU 4S jr\S 5       rS rSS jr	S r
S rS	 rS
 rSrU =r$ )GatewayKernelSpecManager   zA gateway kernel spec manager.c                  > [         TU ]  " S0 UD6  [        [        R                  " 5       R
                  =(       d    S[        R                  " 5       R                  5      n[        R                  U5      U l	        [        [        R                  " 5       R
                  =(       d    S[        R                  " 5       R                  5      U l        g)z)Initialize a gateway kernel spec manager.r:   Nr,   )r;   r<   r!   r#   r=   r>   kernelspecs_endpointr   _get_endpoint_for_user_filterbase_endpointkernelspecs_resource_endpointbase_resource_endpoint)r.   rB   r   rC   s      r/   r<   !GatewayKernelSpecManager.__init__   s    "6"%""$((.B0F0F0H0]0]
 6SSTab&3""$((.B""$BB'
#r2   c                `    [         R                  R                  S5      nU(       a  U  SU 3$ U $ )z#Get the endpoint for a user filter.KERNEL_USERNAMEz?user=)osenvironget)default_endpointkernel_users     r/   r   6GatewayKernelSpecManager._get_endpoint_for_user_filter   s2     jjnn%67&'vk];;r2   c           	        U R                   (       d  0 $ US   nU H  nX#   S   nU H  nXE   n[        R                  USSS9n[        U5      S:  d  M-  [	        U R                   R
                  SUS   5      nXS   U   S   U'   Xh:w  d  Me  U R                  R                  SU SUS   U   S   U    35        M     M     U$ )zHelper method that replaces any gateway base_url with the server's base_url
This enables clients to properly route through jupyter_server to a gateway
for kernel resources such as logo files
kernelspecs	resourcesz/kernelspecs/r"   )sepmaxsplitz'Replaced original kernel resource path z with new path )rO   r[   rsplitlenr!   base_urlrP   re   )	r.   kernel_specsr   kernel_namer   resource_nameoriginal_pathsplit_eg_base_urlnew_paths	            r/   "_replace_path_kernelspec_resources;GatewayKernelSpecManager._replace_path_kernelspec_resources   s    
 {{I"=1&K#0=I!* ) 8$'JJ}/\]J$^!()A-,,,m=Nq=Q H \d/<[I-X$0Em_ U$$0$?$L[$YZg$h#ik "+ ' r2   c                f    U(       a  [        U R                  [        U5      5      $ U R                  $ )zaBuilds a url for the kernels endpoint
Parameters
----------
kernel_name : kernel name (optional)
)r!   r   r   )r.   r   s     r/   _get_kernelspecs_endpoint_url6GatewayKernelSpecManager._get_kernelspecs_endpoint_url  s+      !3!3Z5LMM!!!r2   c                Z  #    U R                  5       I Sh  vN nU R                  (       d  0 $ U R                  R                  nUR                  S5      nX2R                  :w  a2  U R
                  R                  SU SUR                   S35        X2l        UR                  S5      nU$  N7f)z,Get all of the kernel specs for the gateway.Nr   z'Default kernel name on Gateway server (z ) differs from Notebook server (z').  Updating to Gateway server's value.r   )list_kernel_specsrO   kernel_managerr   default_kernel_namerP   rQ   )r.   fetched_kspecsrW   remote_default_kernel_nameremote_kspecss        r/   get_all_specs&GatewayKernelSpecManager.get_all_specs  s     #5577 {{I[[''%3%7%7	%B"%)?)??HHMM9:T9U V$$&$:$:#;;bd &@"&**=9% 8s   B+B)BB+c                   #    U R                  5       nU R                  R                  SU 35        [        USS9I Sh  vN n[	        UR
                  5      nU R                  U5      nU$  N,7f)zGet a list of kernel specs.zRequest list kernel specs at: ra   rb   N)r   rP   re   r$   r   rf   r   )r.   kernel_spec_urlrn   r   s       r/   r   *GatewayKernelSpecManager.list_kernel_specs)  se     <<>77HIJ(GG"8==1>>|L Hs   <A-A+-A-c                  #    U R                  [        U5      S9nU R                  R                  SU 35         [	        USS9I Sh  vN n[        UR                  5      nU$  N! [        R                   aG  nUR                  S:X  a1  SU S[        R                  " 5       R                   3n[        U5      See SnAff = f7f)	zfGet kernel spec for kernel_name.

Parameters
----------
kernel_name : str
    The name of the kernel.
)r   zRequest kernel spec at: ra   rb   N  zkernelspec z! not found on Gateway server at: )r   r[   rP   re   r$   r   rf   r   rj   status_coder#   r=   r>   rG   )r.   r   rB   r   rn   kernel_specerrormsgs           r/   get_kernel_spec(GatewayKernelSpecManager.get_kernel_spec2  s      <<[IY<Z1/1BCD	5,_UKKH &hmm4K L}} 	  C' $K=0QR_RhRhRjRnRnQopsm-	s;   7CA% A#A% C#A% %C 9AB;;C  Cc                N  #    [        U R                  [        U5      [        U5      5      nU R                  R	                  SU SU 35         [        USS9I Sh  vN nUR                  nU$  N! [        R                   a  nUR                  S:X  a  Sn SnAU$ e SnAff = f7f)zGet kernel spec for kernel_name.

Parameters
----------
kernel_name : str
    The name of the kernel.
path : str
    The name of the desired resource
zRequest kernel spec resource 'z' at: ra   rb   Nr   )
r!   r   r[   rP   re   r$   rf   r   rj   r   )r.   r   rK   kernel_spec_resource_urlrn   kernel_spec_resourcer   s          r/   get_kernel_spec_resource1GatewayKernelSpecManager.get_kernel_spec_resourceK  s      $1''[)93t9$
  	7vVD\C]^_	1,-EeTTH $,== ## U}} 	  C''+$
 $# 		sH   AB%A0 A.A0  B%.A0 0B"BB%BB""B%)r   r   N)r   r   r   r   r   r<   staticmethodr   r   r   r   r   r   r   r   r   r   s   @r/   r   r      sB    (
    2	",2$ $r2   r   c                  2    \ rS rSrSr\" S5      rSS jrSrg)GatewaySessionManagerie  zA gateway session manager.z;jupyter_server.gateway.managers.GatewayMappingKernelManagerc                t   #    Sn U R                   R                  U5      nUSL $ ! [         a     USL $ f = f7f)zRChecks if the kernel is still considered alive and returns true if it's not found.N)r   rZ   	Exception)r.   rH   rW   s      r/   kernel_culled#GatewaySessionManager.kernel_culledj  sP     -1	 $$//	:B Tz  	Tz	s   8% 8
5858r,   N)rH   r[   returnbool)	r   r   r   r   r   r   r   r   r   r,   r2   r/   r   r   e  s    $[\Nr2   r   c                    ^  \ rS rSr% SrSrS\S'   Sr\" S5      S 5       r	U 4S jr
\S	 5       r\" S
5      r\" S
S9rS rSS jr\" SS9S 5       r\" SS9SS j5       r\" SS9S 5       r\" SS9S 5       rS rSS jrSrU =r$ )GatewayKernelManageri|  z6Manages a single kernel remotely via a Gateway Server.NOptional[str]rH   cache_portsc                    gr5   r,   r-   s    r/   _default_cache_ports)GatewayKernelManager._default_cache_ports  r8   r2   c                  > [         TU ]  " S0 UD6  [        [        R                  " 5       R
                  =(       d    S[        R                  " 5       R                  5      U l        U   S=U l        U l	        SU l
        [        5       U l        g)z&Initialize the gateway kernel manager.r:   Nstartingr,   )r;   r<   r!   r#   r=   r>   r?   r@   r\   rH   execution_stater   last_activityrA   s     r/   r<   GatewayKernelManager.__init__  sm    "6"(""$((.B0F0F0H0Y0Y
 	'++dn)#Xr2   c                    U R                   SL$ )z/Has a kernel been started that we are managing.N)r\   r-   s    r/   
has_kernelGatewayKernelManager.has_kernel  s     {{$&&r2   z3jupyter_server.gateway.managers.GatewayKernelClient)klassc                    0 nUR                  U R                  SS95        UR                  U R                  U S.5        U R                  US'   UR                  U5        U R                  " S0 UD6$ )z3Create a client configured to connect to our kernelT)session)connection_filerO   rH   r,   )updateget_connection_infor   rH   client_factory)r.   rB   kws      r/   clientGatewayKernelManager.client  so    
		$**4*89
		#'#7#7	
 ..; 			&""(R((r2   c                  #    Ucx  U R                   R                  SU R                  -  5         [        U R                  SS9I Sh  vN n[	        UR
                  5      nU R                   R                  SU-  5        U(       a  [        R                  R                  US   S	5      R                  [        S
9U l        US   U l        [!        U R"                  [$        5      (       a/  ['        US   5      U R"                  R(                  U R*                  '   Xl        U$  N! [        R                   aF  nUR                  S:X  a0  U R                   R                  SU R                  -  5        Sn SnAGNe SnAff = f7f)zRefresh the kernel model.

Parameters
----------
model : dict
    The model from which to refresh the kernel.  If None, the kernel
    model is fetched from the Gateway server.
NzRequest kernel at: %sra   rb   r   zKernel not found at: %szKernel retrieved: %sr   z%Y-%m-%dT%H:%M:%S.%fZ)tzinfor   connections)rP   re   
kernel_urlr$   r   rf   r   rj   r   ri   datetimestrptimereplacer   r   r   
isinstancerO   r   int_kernel_connectionsrH   r\   )r.   r]   rn   r   s       r/   rg   "GatewayKernelManager.refresh_model  s7     =HHNN2T__DE
3!0!OO $HMM2HHNN1E9:!)!2!2!;!;o&(?"gSg!  $)):#;D $++'@AA
 CFeMFZB[//?3 P== $$+HH$$%>%PQ EsG   ,E=D  DD  CE=D   E:4:E5.E=4E55E::E=zKernel {kernel_id} was started.)success_msgc                  #    UR                  S5      nUGcN  UR                  SS5      nU R                  R                  SU R                  -  5        [        R
                  R                  S5      c]  [        R                  " 5       R                  (       a9  [        R                  " 5       R                  =(       d    S[        R
                  S'   [        R
                  R                  5       nUR                  UR                  S0 5      5        UR                  5        VVs0 s HQ  u  pVUR                  S	5      (       d4  U[        R                  " 5       R                  R                  S
5      ;   d  MO  XV_MS     nnnUR                  S5      b  UR                  S5      c  US   US'   [        X7S.5      n[!        U R                  SSS0US9I Sh  vN n	[#        U	R$                  5      U l        U R&                  S   U l        [+        U R                  [-        [/        U R(                  5      5      5      U l        U R                  R3                  SU R(                   SU 35        gX l        [+        U R                  [-        [/        U R(                  5      5      5      U l        U R5                  5       I Sh  vN U l        U R                  R3                  SU R(                   35        gs  snnf  GN N;7f)zStarts a kernel via HTTP in an asynchronous manner.

Parameters
----------
`**kwargs` : optional
     keyword arguments that are passed down to build the kernel_cmd
     and launching the kernel (e.g. Popen kwargs).
rH   Nr   python3zRequest new kernel at: %sr   r:   envKERNEL_,rN   KERNEL_WORKING_DIR)namer  POSTContent-Typeapplication/jsonrc   headersrf   rd   z%GatewayKernelManager started kernel: z, args: z,GatewayKernelManager using existing kernel: )r   rP   re   r@   r   r   r#   r=   	http_userrh   r   items
startswithallowed_envssplitr   r$   r   rf   r\   rH   r!   r   r[   r   rQ   rg   )
r.   rB   rH   r   payload_envskv
kernel_env	json_bodyrn   s
             r/   rT   !GatewayKernelManager.start_kernel  sP     JJ{+	 **]I>KHHNN69I9IIJ zz~~/08]=S=S=U=_=_0=0F0F0H0R0R0XVX

,-::??,L

5" 56
 +0022FQ<<	**a=3I3I3K3X3X3^3^_b3c.c 2   zz% ,@T1U1]39%=
/0#[$LMI,  ');<	 H &hmm4DK![[.DN+D,<,<jT^^I\>]^DOHHMMA$..AQQYZ`Yabc&N+D,<,<jT^^I\>]^DO $ 2 2 44DKHHMMHHXYZ5 5s9   DK4!AK)3K)9AK4K/C%K46K279K42K4z Kernel {kernel_id} was shutdown.c                  #    U R                   (       au  U R                  R                  SU R                  5         [	        U R                  SS9I Sh  vN nU R                  R                  SUR
                  UR                  5        gg N7! [        R                   a6  nUR                  S:X  a   U R                  R                  S5         SnAge SnAff = f7f)z5Attempts to stop the kernel process cleanly via HTTP.zRequest shutdown kernel at: %sDELETErb   NzShutdown kernel response: %d %sr   z4Shutdown kernel response: kernel not found (ignored))
r   rP   re   r   r$   codereasonr   rj   r   )r.   rw   rx   rn   r   s        r/   ry   $GatewayKernelManager.shutdown_kernel  s      ??HHNN;T__M!0!RR@(--QYQ`Q`a	  S== $$+HHNN#YZZ	sF   8CB B
5B C
B C +CCCCCz!Kernel {kernel_id} was restarted.c                H  #    U R                   (       a  U R                  c   eU R                  S-   nU R                  R                  SU5        [	        USSS0[        0 5      S9I Sh  vN nU R                  R                  SUR                  UR                  5        gg N77f)	zRestarts a kernel via HTTP.Nz/restartzRequest restart kernel at: %sr  r	  r
  r  zRestart kernel response: %d %sr   r   rP   re   r$   r   r  r  )r.   r   r   rn   s       r/   r|   #GatewayKernelManager.restart_kernel   s     
 ????...:5JHHNN:JG,');< _	 H HHNN;X]]HOO\    A&B"(B )8B"z#Kernel {kernel_id} was interrupted.c                H  #    U R                   (       a  U R                  c   eU R                  S-   nU R                  R                  SU5        [	        USSS0[        0 5      S9I Sh  vN nU R                  R                  SUR                  UR                  5        gg N77f)	z*Interrupts the kernel via an HTTP request.Nz
/interruptzRequest interrupt kernel at: %sr  r	  r
  r  z Interrupt kernel response: %d %sr  )r.   r   rn   s      r/   r   %GatewayKernelManager.interrupt_kernel1  s     
 ????...<7JHHNN<jI,');< _	 H HHNN=x}}hoo^ r   c                  #    U R                   (       aG  U R                  5       I Sh  vN U l        U R                  R	                  SU R                   S35        gU R                  R	                  SU R                   S35        g N]7f)z$Is the kernel process still running?NzThe kernel: z
 is alive.Tz no longer exists.F)r   rg   r\   rP   re   r-   s    r/   is_aliveGatewayKernelManager.is_aliveB  se     ?? $ 2 2 44DKHHNN\$++jABHHNN\$++6HIJ 5s   %BBABc                    g)z/Clean up resources when the kernel is shut downNr,   )r.   rx   s     r/   cleanup_resources&GatewayKernelManager.cleanup_resourcesM      r2   )r   r\   rH   r   r@   r   r   r   r   )r   r   r   r   r   rH   r   r\   r   r   r<   propertyr   r   client_classr   r   r   rg   r   rT   ry   r|   r   r$  r'  r   r   r   s   @r/   r   r   |  s    @#I}#F] 
& ' ' $$YZL UVN) %V 51[1[f 6 7]] 9__	> >r2   r   c                     ^  \ rS rSr% SrSrS\S'   S\S'   SU 4S jjrSS	 jrSS
 jr	SS jr
\S 5       rSS jrSS jrSS jrSrU =r$ )ChannelQueueiT  zA queue for a named channel.Nr   channel_namer   response_router_finishedc                T   > [         TU ]  5         Xl        X l        X0l        SU l        g)zInitialize a channel queue.FN)r;   r<   r.  channel_socketrP   r/  )r.   r.  r1  rP   rC   s       r/   r<   ChannelQueue.__init__Z  s'    (,(-%r2   c                H  #    Uc  [        S5      nOUS:  a  Sn[        U5      e[        5       U-   n  U R                  SS9$ ! [         aP    U R
                  (       a  Sn[        U5      Se[        5       U:  a  e [        R                  " S5      I Sh  vN     Of = fMo  7f)z"Asynchronously get from the queue.Ninfr   z''timeout' must be a non-negative numberF)blockzResponse router had finished)	float
ValueErrorr   r   r   r/  RuntimeErrorasynciosleep)r.   timeoutr   end_times       r/   
_async_getChannelQueue._async_getb  s     ?ElGq[;CS/!;('xxex,, '008C&s+5;)mmA&&&' s5   1B"A B"ABBBB"BB"c                  #    UR                  SS5      nU R                  US9I Sh  vN nU R                  R                  SU R                  US   U(       a  US   OS5        U R                  5         [        S	U5      $  NW7f)
zGet a message from the queue.r;  r"   )r;  Nz9Received message on channel: %s, msg_id: %s, msg_type: %smsg_idmsg_typenulldict[str, Any])r   r=  rP   re   r.  	task_doner   )r.   argsrB   r;  r   s        r/   get_msgChannelQueue.get_msgv  su     **Y*OOGO44GM"C
O		
 	$c** 5s   %BA?ABc                   [         R                  " U[        R                  S9R	                  SS5      nU R
                  R                  SU R                  US   U(       a  US   OS5        U R                  R                  U5        g)	zSend a message to the queue.)r   z</z<\/z8Sending message on channel: %s, msg_id: %s, msg_type: %sr@  rA  rB  N)
jsondumpsr-  serialize_datetimer   rP   re   r.  r1  send)r.   r   messages      r/   rL  ChannelQueue.send  sk    **S,*I*IJRRSWY_`FM"C
O		
 	  )r2   c                b    [        U [        R                  5      (       a  U R                  5       $ g)zSerialize a datetime object.N)r   r   	timestamp)dts    r/   rK  ChannelQueue.serialize_datetime  s&     b(++,,<<>!r2   c                    g)zStart the queue.Nr,   r-   s    r/   startChannelQueue.start  r)  r2   c           	        U R                  5       (       d  / nU R                  5       (       aD  U R                  5       nUS   S:w  a  UR                  US   5        U R                  5       (       a  MD  U R                  S:X  a  SU;   a  g[        U5      (       a9  U R                  R                  SU R                   S[        U5       SU S	35        ggg)
zStop the queue.rA  statusiopubshutdown_replyNzStopping channel 'z' with z" unprocessed non-status messages: .)emptyqsize
get_nowaitrk   r.  r   rP   ri   )r.   msgsr   s      r/   stopChannelQueue.stop  s    zz|| D**,,oo'z?h.KKJ0 **,,   G+0@D0H4yy  ():):(;73t9+Moptouuvw  r2   c                    U R                   SL$ )zWhether the queue is alive.N)r1  r-   s    r/   r$  ChannelQueue.is_alive  s    ""$..r2   )r.  r1  rP   r/  )r.  r[   r1  zwebsocket.WebSocketrP   r%   r   )rE  r	   rB   r	   r   rC  )r   rC  r   None)r   rc  r   r   )r   r   r   r   r   r.  r   r<   r=  rF  rL  r   rK  rT  r_  r$  r   r   r   s   @r/   r-  r-  T  sR    &"&L-&"".'(+	*  $/ /r2   r-  c                  "    \ rS rSrSrSS jrSrg)HBChannelQueuei  z"A queue for the heartbeat channel.c                "    U R                  5       $ )zWhether the channel is beating.)r$  r-   s    r/   
is_beatingHBChannelQueue.is_beating  s     }}r2   r,   Nrd  )r   r   r   r   r   rh  r   r,   r2   r/   rf  rf    s
    ,r2   rf  c                     ^  \ rS rSr% SrSrS\S'   S\S'   S\S	'   S\S
'   S\S'   S\S'   S\S'   U 4S jrSU 4S jjrU 4S jr	\
S 5       r\
S 5       r\
S 5       r\
S 5       r\
S 5       rS rSrU =r$ )GatewayKernelClienti  a  Communicates with a single kernel indirectly via a websocket to a gateway server.

There are five channels associated with each kernel:

* shell: for request/reply calls to the kernel.
* iopub: for the kernel to publish results to frontends.
* hb: for monitoring the kernel's heartbeat.
* stdin: for frontends to reply to raw_input calls in the kernel.
* control: for kernel management calls to the kernel.

The messages that can be sent on these channels are exposed as methods of the
client (KernelClient.execute, complete, history, etc.). These methods only
send the message, they don't wait for a reply. To get results, use e.g.
:meth:`get_shell_msg` to fetch messages from the shell channel.
Fr   _channels_stoppedz!Optional[dict[str, ChannelQueue]]_channel_queueszOptional[ChannelQueue]_control_channel_hb_channel_stdin_channel_iopub_channel_shell_channelc                j   > [         TU ]  " S0 UD6  Xl        SU l        SU l        SU l        0 U l        g)z#Initialize a gateway kernel client.NFr,   )r;   r<   rH   r1  response_routerrl  rm  )r.   rH   rB   rC   s      r/   r<   GatewayKernelClient.__init__  s8    "6""=A15!&!r2   c           
       >#    [        [        R                  " 5       R                  =(       d    S[        R                  " 5       R                  [        U R                  5      S5      n[        R                  " 5       R                  [        R                  " 5       R                  [        R                  " 5       R                  S.n[        R                  " U[        R                  " 5       R                  SUS9U l        [        [        TU ]A  XX4US95      I Sh  vN   [#        U R$                  S9U l        U R&                  R)                  5         g N77f)	zStarts the channels for this kernel.

For this class, we establish a websocket connection to the destination
and set up the channel-based queues on which applicable messages will
be posted.
r:   channels)ca_certscertfilekeyfileT)r;  enable_multithreadsslopt)shellrX  stdinhbcontrolN)target)r!   r#   r=   ws_urlr?   r   rH   rx  client_cert
client_key	websocketcreate_connectionKERNEL_LAUNCH_TIMEOUTr1  r   r;   start_channelsr   _route_responsesrt  rT  )	r.   r}  rX  r~  r  r  r  ssl_optionsrC   s	           r/   r  "GatewayKernelClient.start_channels  s     ""$++1r""$55t~~&	
 &..099%..0<<$--/::
 (99!**,BB#	
 G"5Y`"a
 	
 	
  &T-B-BC""$	
s   DEE8Ec                p  > [         TU ]  5         SU l        U R                  R	                  S5        U R
                  c   eU R
                  R                  5         U R                  c   eU R                  R                  5         U R                  (       a"  U R                  R                  5         SU l	        gg)zStops all the running channels for this kernel.

For this class, we close the websocket connection and destroy the
channel-based queues.
TzClosing websocket connectionN)r;   stop_channelsrl  rP   re   r1  closert  joinrm  clearr   s    r/   r  !GatewayKernelClient.stop_channels  s     	!%56""...!!###///!!#  &&(#'D   r2   c                $   U R                   cx  U R                  R                  S5        U R                  c   e[	        SU R                  U R                  5      U l         U R
                  c   eU R                   U R
                  S'   U R                   $ )z-Get the shell channel object for this kernel.zcreating shell channel queuer}  )rr  rP   re   r1  r-  rm  r-   s    r/   shell_channel!GatewayKernelClient.shell_channel       &HHNN9:&&222".w8K8KTXX"VD''333,0,?,?D  )"""r2   c                $   U R                   cx  U R                  R                  S5        U R                  c   e[	        SU R                  U R                  5      U l         U R
                  c   eU R                   U R
                  S'   U R                   $ )z-Get the iopub channel object for this kernel.zcreating iopub channel queuerX  )rq  rP   re   r1  r-  rm  r-   s    r/   iopub_channel!GatewayKernelClient.iopub_channel#  r  r2   c                $   U R                   cx  U R                  R                  S5        U R                  c   e[	        SU R                  U R                  5      U l         U R
                  c   eU R                   U R
                  S'   U R                   $ )z-Get the stdin channel object for this kernel.zcreating stdin channel queuer~  )rp  rP   re   r1  r-  rm  r-   s    r/   stdin_channel!GatewayKernelClient.stdin_channel.  r  r2   c                $   U R                   cx  U R                  R                  S5        U R                  c   e[	        SU R                  U R                  5      U l         U R
                  c   eU R                   U R
                  S'   U R                   $ )z*Get the hb channel object for this kernel.zcreating hb channel queuer  )ro  rP   re   r1  rf  rm  r-   s    r/   
hb_channelGatewayKernelClient.hb_channel9  s     #HHNN67&&222-dD4G4GRD''333)-)9)9D  &r2   c                $   U R                   cx  U R                  R                  S5        U R                  c   e[	        SU R                  U R                  5      U l         U R
                  c   eU R                   U R
                  S'   U R                   $ )z/Get the control channel object for this kernel.zcreating control channel queuer  )rn  rP   re   r1  r-  rm  r-   s    r/   control_channel#GatewayKernelClient.control_channelD  s       (HHNN;<&&222$0D<O<OQUQYQY$ZD!''333.2.C.CD  +$$$r2   c                    U R                   (       d  U R                  c   eU R                  R                  5       nU(       d  OY[        [	        U5      5      nUS   nU R
                  c   eU R
                  U   R                  U5        U R                   (       d  M  U R
                  c   eU R
                  R                  5        H
  nSUl        M     U R                  R                  S5        g! [        R                   a     Ni[         a:  nU R                   (       d  U R                  R                  SU S35         SnANSnAff = f)a  
Reads responses from the websocket and routes each to the appropriate channel queue based
on the message's channel.  It does this for the duration of the class's lifetime until the
channels are stopped, at which time the socket is closed (unblocking the router) and
the thread terminates.  If shutdown happens to occur while processing a response (unlikely),
termination takes place via the loop control boolean.
Nchannelz"Unexpected exception encountered ()Tz!Response router thread exiting...)rl  r1  recvr   r   rm  
put_nowaitr  "WebSocketConnectionClosedExceptionBaseExceptionrP   ri   rm   r/  re   )r.   raw_messageresponse_messager  bechannel_queues         r/   r  $GatewayKernelClient._route_responsesO  s$   	M,,**666"11668"#.tK/@#A *95++777$$W-889IJ ,,,$ ##///!1188:M59M2 ; 	:; ;; 	 	M))  #EbT!KL	Ms%   AC0 AC0 0E		E	0EE	)
rm  rl  rn  ro  rq  rr  rp  r1  rH   rt  )TTTTT)r   r   r   r   r   allow_stdinr   r<   r  r  r*  r  r  r  r  r  r  r   r   r   s   @r/   rk  rk    s    " K66,,''******"!%F(* # # # # # #     % %< <r2   rk  )Br   
__future__r   r9  r   rI  r   queuer   r   	threadingr   timer   typingr   r	   r
   r   r  "jupyter_client.asynchronous.clientr   jupyter_client.clientabcr   jupyter_client.kernelspecr   jupyter_client.managerabcr   jupyter_core.utilsr   tornador   tornado.escaper   r   r   r   	traitletsr   r   r   r   _tzr   r   services.kernels.kernelmanagerr   r   r    services.sessions.sessionmanagerr    utilsr!   gateway_clientr#   r$   loggingr%   r'   r   r   r   registerr-  rf  rk  r,   r2   r/   <module>r     s     #    	    5 5  @ 4 7 6 +  E E ? ?  
 > ! :l%"; l%^K$0 K$\N .R>. R>j   . /X/5 X/v\ v<+ v<r   , -r2   