
    Mh                    V   d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	 ddl
mZ ddlmZ ddlmZmZmZmZ ddlZddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddl m!Z!m"Z"m#Z#m$Z$ ddl%m&Z&m'Z'm(Z(m)Z) ddl*m+Z+m,Z, ddl-m.Z.m/Z/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6m7Z7 erddl8m9Z9  G d de.          Z: G d de          Z; G d de2          Z< G d de/          Z= ej>        e=            G d  d!e	          Z? G d" d#e?          Z@ G d$ d%e          ZA ej>        eA           dS )&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                       e Zd ZU dZi Zded<    ed          d             Z ed          d             Z fdZ	d	 Z
d
d
ddZd Zd ZddZddZd ZddZ fdZ xZS )GatewayMappingKernelManagerz[Kernel manager that supports remote kernels hosted by Jupyter Kernel or Enterprise Gateway.zdict[str, GatewayKernelManager]_kernelskernel_manager_classc                    dS )Nz4jupyter_server.gateway.managers.GatewayKernelManager selfs    _/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/jupyter_server/gateway/managers.py_default_kernel_manager_classz9GatewayMappingKernelManager._default_kernel_manager_class.   s    EE    shared_contextc                    dS NFr+   r,   s    r.   _default_shared_contextz3GatewayMappingKernelManager._default_shared_context2       ur0   c                     t                      j        di | t          t          j                    j        pdt          j                    j        pd          | _        dS )z,Initialize a gateway mapping kernel manager. Nr+   )super__init__r!   r#   instanceurlkernels_endpointkernels_urlr-   kwargs	__class__s     r.   r9   z$GatewayMappingKernelManager.__init__6   s`    ""6"""("$$(.B0F0H0H0Y0_]_
 
r0   c                Z    	 | j                             |          S # t          $ r Y dS w xY w)zCComplete override since we want to be more tolerant of missing keysN)r(   popKeyError)r-   	kernel_ids     r.   remove_kernelz)GatewayMappingKernelManager.remove_kernel=   s?    	=$$Y/// 	 	 	DD	s    
**N)rD   pathc               >  K   | j                             d| d| d           |||                     |          |d<   |                     | | j                   } |j        dd|i| d{V  |j        }|| j        |<   | j        s|                                  |S )	a  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logrD   r+   )	rK   infocwd_for_pathkernel_manager_factorystart_kernelrD   r(   _initialized_cullerinitialize_culler)r-   rD   rF   r?   kms        r.   rO   z(GatewayMappingKernelManager.start_kernelD   s       	SSSDSSSTTT!1 --d33F5M(($((CCbo<<	<V<<<<<<<<<L	#%i ' 	%""$$$r0   c                d   K   d}|                      t          |                    }|r|j        }|S )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-   rD   modelrR   s       r.   kernel_modelz(GatewayMappingKernelManager.kernel_model`   s8       __S^^,, 	IEr0   c                  K   | j                             d| j                    t          | j        d           d{V }t	          |j                  }i }|D ]>}|d         }|| j        v r+| j        |                             |           d{V  |||<   ?| j                                        }g }|D ]}||vr| j         	                    d| d           	 | j        |                                          d{V }n# t          j        $ r d}Y nw xY w|r|||<   j| j         	                    d| d           | j                            |d           |                    |           t          |                                          S )	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.)rK   debugr=   r$   r   bodyr(   refresh_modelcopywarningr   	HTTPErrorrB   appendlistvalues)	r-   r?   responsekernelskernel_modelsrW   kidour_kernels
culled_idss	            r.   list_kernelsz(GatewayMappingKernelManager.list_kernelso   s      	B0@BBCCC()9%HHHHHHHHHhm,,  	+ 	+E+Cdm##mC(66u=========%*c"m((**
 	+ 	+C-''  kckkk  ! #'-"4"B"B"D"DDDDDDDEE} ! ! ! EEE! +).M#&&H$$]#]]]   M%%c4000%%c***M((**+++s   %D  DDFc                   K   |                      |          }t          |                    ||                     d{V  |                     |           dS )aX  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)rT   r   shutdown_kernelrE   )r-   rD   ro   rp   rR   s        r.   rq   z+GatewayMappingKernelManager.shutdown_kernel   sf       __Y''2--#w-GGHHHHHHHHH9%%%%%r0   c                x   K   |                      |          }t           |j        dd|i|           d{V  dS )zRestart a kernel by its kernel uuid.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel to restart.
        ro   Nr+   )rT   r   restart_kernel)r-   rD   ro   r?   rR   s        r.   rs   z*GatewayMappingKernelManager.restart_kernel   sX       __Y'',2,?????@@@@@@@@@@@r0   c                   K   |                      |          }t          |                                           d{V  dS )zInterrupt a kernel by its kernel uuid.

        Parameters
        ==========
        kernel_id : uuid
            The id of the kernel to interrupt.
        N)rT   r   interrupt_kernel)r-   rD   r?   rR   s       r.   ru   z,GatewayMappingKernelManager.interrupt_kernel   sK       __Y''2..0011111111111r0   c                   K   t          | j                  }|D ]U}|                     |          }t          |                    |                     d{V  |                     |           VdS )zShutdown all kernels.)ro   N)re   r(   rT   r   rq   rE   )r-   ro   kidsrD   rR   s        r.   shutdown_allz(GatewayMappingKernelManager.shutdown_all   s      DM"" 	* 	*I++Br11c1::;;;;;;;;;y))))	* 	*r0   c                   K   |                                   d{V  t                                                       d{V  dS )z@Override cull_kernels, so we can be sure their state is current.N)rm   r8   cull_kernelsr-   r@   s    r.   rz   z(GatewayMappingKernelManager.cull_kernels   sY      !!!!!!!!!gg""$$$$$$$$$$$r0   FFF)__name__
__module____qualname____doc__r(   __annotations__r   r/   r4   r9   rE   rO   rX   rm   rq   rs   ru   rx   rz   __classcell__r@   s   @r.   r'   r'   (   sX        ee 13H2222W#$$F F %$F W  
 
 
 
 
   /3     8  2, 2, 2,h& & & & 	A 	A 	A 	A	2 	2 	2* * * *% % % % % % % % %r0   r'   c                  ^     e Zd ZdZ fdZed             Zd ZddZd Z	d Z
d	 Zd
 Z xZS )GatewayKernelSpecManagerzA gateway kernel spec manager.c                z    t                      j        di | t          t          j                    j        pdt          j                    j                  }t                              |          | _	        t          t          j                    j        pdt          j                    j
                  | _        dS )z)Initialize a gateway kernel spec manager.r7   Nr+   )r8   r9   r!   r#   r:   r;   kernelspecs_endpointr   _get_endpoint_for_user_filterbase_endpointkernelspecs_resource_endpointbase_resource_endpoint)r-   r?   r   r@   s      r.   r9   z!GatewayKernelSpecManager.__init__   s    ""6"""%"$$(.B0F0H0H0]
 
 6SSTabb&3"$$(.B"$$B'
 '
###r0   c                V    t           j                            d          }|r|  d| S | S )z#Get the endpoint for a user filter.KERNEL_USERNAMEz?user=)osenvironget)default_endpointkernel_users     r.   r   z6GatewayKernelSpecManager._get_endpoint_for_user_filter   s:     jnn%677 	<&;;k;;;r0   c           	        | j         si S |d         }|D ]}||         d         }|D ]}||         }t                              |dd          }t          |          dk    rvt	          | j         j        d|d                   }||d         |         d         |<   ||k    r8| j                            d| d|d         |         d         |                     |S )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 )rJ   rU   rsplitlenr!   base_urlrK   r^   )	r-   kernel_specsr   kernel_namer   resource_nameoriginal_pathsplit_eg_base_urlnew_paths	            r.   "_replace_path_kernelspec_resourcesz;GatewayKernelSpecManager._replace_path_kernelspec_resources   s(   
 { 	I"=1& 	 	K#K0=I!*   )- 8$'JJ}/\]J$^$^!())A--,,m=Nq=Q   H \dL/<[I-X$00km k k$0$?$L[$YZg$hk k   r0   Nc                X    |r"t          | j        t          |                    S | j        S )zBuilds a url for the kernels endpoint
        Parameters
        ----------
        kernel_name : kernel name (optional)
        )r!   r   r   )r-   r   s     r.   _get_kernelspecs_endpoint_urlz6GatewayKernelSpecManager._get_kernelspecs_endpoint_url  s1      	N !3Z5L5LMMM!!r0   c                ,  K   |                                   d{V }| j        si S | j        j        }|                    d          }||j        k    r-| j                            d| d|j         d           ||_        |                    d          }|S )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_specsrJ   kernel_managerr   default_kernel_namerK   rL   )r-   fetched_kspecsrR   remote_default_kernel_nameremote_kspecss        r.   get_all_specsz&GatewayKernelSpecManager.get_all_specs  s      #5577777777 { 	I['%3%7%7	%B%B"%)???HMMd:T d d$&$:d d d   &@B"&**=99r0   c                   K   |                                  }| j                            d|            t          |d           d{V }t	          |j                  }|                     |          }|S )zGet a list of kernel specs.zRequest list kernel specs at: rZ   r[   N)r   rK   r^   r$   r   r_   r   )r-   kernel_spec_urlrg   r   s       r.   r   z*GatewayKernelSpecManager.list_kernel_specs)  s      <<>>IIIJJJ(GGGGGGGGG"8=11>>|LLr0   c                  K   |                      t          |                    }| j                            d|            	 t	          |d           d{V }t          |j                  }nQ# t          j        $ r?}|j	        dk    r.d| dt          j                    j         }t          |          d d}~ww xY w|S )	zGet kernel spec for kernel_name.

        Parameters
        ----------
        kernel_name : str
            The name of the kernel.
        )r   zRequest kernel spec at: rZ   r[   N  zkernelspec z! not found on Gateway server at: )r   rU   rK   r^   r$   r   r_   r   rc   status_coder#   r:   r;   rC   )r-   r   r?   r   rg   kernel_specerrormsgs           r.   get_kernel_specz(GatewayKernelSpecManager.get_kernel_spec2  s       <<[IYIY<ZZC/CCDDD	5,_UKKKKKKKKKH &hm44KK } 	 	 	 C'' qKppR_RhRjRjRnppsmm-	 s   A0 0B>?:B99B>c                @  K   t          | j        t          |          t          |                    }| j                            d| d|            	 t          |d           d{V }|j        }n+# t          j        $ r}|j	        dk    rd}n Y d}~nd}~ww xY w|S )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: rZ   r[   Nr   )
r!   r   rU   rK   r^   r$   r_   r   rc   r   )r-   r   rF   kernel_spec_resource_urlrg   kernel_spec_resourcer   s          r.   get_kernel_spec_resourcez1GatewayKernelSpecManager.get_kernel_spec_resourceK  s       $1'[)9)93t99$
 $
  	^^^D\^^___	1,-EeTTTTTTTTTH $,=   } 	 	 	 C'''+$$ %$$$$	 $#s   A3 3BBBN)r~   r   r   r   r9   staticmethodr   r   r   r   r   r   r   r   r   s   @r.   r   r      s        ((
 
 
 
 
     \   2	" 	" 	" 	"  ,    2$ $ $ $ $ $ $r0   r   c                  0    e Zd ZdZ ed          Zd	dZdS )
GatewaySessionManagerzA gateway session manager.z;jupyter_server.gateway.managers.GatewayMappingKernelManagerrD   rU   returnboolc                j   K   d}	 | j                             |          }n# t          $ r Y nw xY w|du S )zRChecks if the kernel is still considered alive and returns true if it's not found.N)r   rT   	Exception)r-   rD   rR   s      r.   kernel_culledz#GatewaySessionManager.kernel_culledj  sV      -1	 $//	::BB 	 	 	D	 Tzs   ! 
..N)rD   rU   r   r   )r~   r   r   r   r   r   r   r+   r0   r.   r   r   e  s>        $$X[\\N     r0   r   c                  h    e Zd ZU dZdZded<   dZ ed          d             Z fdZ	e
d             Z ed	          Z ed	
          Zd ZddZ ed          d             Z ed          dd            Z ed          d             Z ed          d             Zd ZddZ xZS )GatewayKernelManagerz6Manages a single kernel remotely via a Gateway Server.NOptional[str]rD   cache_portsc                    dS r3   r+   r,   s    r.   _default_cache_portsz)GatewayKernelManager._default_cache_ports  r5   r0   c                    t                      j        di | t          t          j                    j        pdt          j                    j                  | _        |  dx| _        | _	        d| _
        t                      | _        dS )z&Initialize the gateway kernel manager.r7   Nstartingr+   )r8   r9   r!   r#   r:   r;   r<   r=   rV   rD   execution_stater   last_activityr>   s     r.   r9   zGatewayKernelManager.__init__  s    ""6"""("$$(.B0F0H0H0Y
 
 	'++dn)#XXr0   c                    | j         duS )z/Has a kernel been started that we are managing.N)rV   r,   s    r.   
has_kernelzGatewayKernelManager.has_kernel  s     {$&&r0   z3jupyter_server.gateway.managers.GatewayKernelClient)klassc                    i }|                     |                     d                     |                     | j        | d           | j        |d<   |                     |            | j        di |S )z3Create a client configured to connect to our kernelT)session)connection_filerJ   rD   r+   )updateget_connection_infor   rD   client_factory)r-   r?   kws      r.   clientzGatewayKernelManager.client  s    
		$**4*88999
		#'#7 	
 	
 	
 .; 			&"t"((R(((r0   c                  K   || j                             d| j        z             	 t          | j        d           d{V }t	          |j                  }nM# t          j        $ r;}|j        dk    r%| j         	                    d| j        z             d}n Y d}~nd}~ww xY w| j                             d|z             |rt          j
                            |d         d	                              t          
          | _        |d         | _        t!          | j        t$                    r't'          |d                   | j        j        | j        <   || _        |S )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: %srZ   r[   r   zKernel not found at: %szKernel retrieved: %sr   z%Y-%m-%dT%H:%M:%S.%fZ)tzinfor   connections)rK   r^   
kernel_urlr$   r   r_   r   rc   r   rb   datetimestrptimereplacer   r   r   
isinstancerJ   r   int_kernel_connectionsrD   rV   )r-   rW   rg   r   s       r.   r`   z"GatewayKernelManager.refresh_model  s~      =HNN2T_DEEE
3!0!O!O!OOOOOOO $HM22 =   $++H$$%>%PQQQ EE EEEE HNN1E9::: 
	\!)!2!;!;o&(?" "gSg!!  $)):#;D $+'@AA \
 CFeMFZB[B[/?s   A B#(1BB#zKernel {kernel_id} was started.)success_msgc                  K   |                     d          }||                     dd          }| j                            d| j        z             t          j                             d          ?t          j                    j        r't          j                    j        pdt          j        d<   t          j        	                                }|
                    |                     di                      d	 |                                D             }|                     d
           |                     d          |d
         |d<   t          ||d          }t          | j        dddi|           d{V }t          |j                  | _        | j        d         | _        t%          | j        t'          t)          | j                                      | _        | j                            d| j         d|            dS || _        t%          | j        t'          t)          | j                                      | _        |                                  d{V | _        | j                            d| j                    dS )a  Starts 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).
        rD   Nr   python3zRequest new kernel at: %sr   r7   envc                    i | ]J\  }}|                     d           s-|t          j                    j                            d          v G||KS )KERNEL_,)
startswithr#   r:   allowed_envssplit).0kvs      r.   
<dictcomp>z5GatewayKernelManager.start_kernel.<locals>.<dictcomp>  sd       Q<<	** /0=3I3K3K3X3^3^_b3c3c.c.c 1.c.c.cr0   rI   KERNEL_WORKING_DIR)namer   POSTContent-Typeapplication/jsonr\   headersr_   r]   z%GatewayKernelManager started kernel: z, args: z,GatewayKernelManager using existing kernel: )r   rK   r^   r=   r   r   r#   r:   	http_userra   r   itemsr   r$   r   r_   rV   rD   r!   r   rU   r   rL   r`   )r-   r?   rD   r   payload_envs
kernel_env	json_bodyrg   s           r.   rO   z!GatewayKernelManager.start_kernel  sp      JJ{++	 **]I>>KHNN69IIJJJ z~~/008]=S=U=U=_80=0F0H0H0R0XVX
,-:??,,L

5" 5 5666 *0022  J zz%  ,@T1U1U1]39%=
/0#[$L$LMMI, ');<	        H &hm44DK![.DN+D,<jT^I\I\>]>]^^DOHMMb$.bbZ`bbccccc&DN+D,<jT^I\I\>]>]^^DO $ 2 2 4 4444444DKHMMYYYZZZZZr0   z Kernel {kernel_id} was shutdown.Fc                j  K   | j         r| j                            d| j                   	 t	          | j        d           d{V }| j                            d|j        |j                   dS # t          j        $ r2}|j	        dk    r| j                            d           n Y d}~dS d}~ww xY wdS )z5Attempts to stop the kernel process cleanly via HTTP.zRequest shutdown kernel at: %sDELETEr[   NzShutdown kernel response: %d %sr   z4Shutdown kernel response: kernel not found (ignored))
r   rK   r^   r   r$   codereasonr   rc   r   )r-   ro   rp   rg   r   s        r.   rq   z$GatewayKernelManager.shutdown_kernel  s       ? 		HNN;T_MMM!0!R!R!RRRRRRR@(-QYQ`aaaaa=   $++HNN#YZZZZ [ZZZZZ		 		s   AA/ /B0>'B++B0z!Kernel {kernel_id} was restarted.c                  K   | j         r~| j        J | j        dz   }| j                            d|           t	          |dddit          i                      d{V }| j                            d|j        |j                   dS dS )	zRestarts a kernel via HTTP.Nz/restartzRequest restart kernel at: %sr   r   r   r   zRestart kernel response: %d %sr   r   rK   r^   r$   r   r   r   )r-   r   r   rg   s       r.   rs   z#GatewayKernelManager.restart_kernel   s      
 ? 
	]?...:5JHNN:JGGG,');< __	        H HNN;X]HO\\\\\
	] 
	]r0   z#Kernel {kernel_id} was interrupted.c                  K   | j         r~| j        J | j        dz   }| j                            d|           t	          |dddit          i                      d{V }| j                            d|j        |j                   dS dS )	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   rg   s      r.   ru   z%GatewayKernelManager.interrupt_kernel1  s      
 ? 
	_?...<7JHNN<jIII,');< __	        H HNN=x}ho^^^^^
	_ 
	_r0   c                   K   | j         rD|                                  d{V | _        | j                            d| j         d           dS | j                            d| j         d           dS )z$Is the kernel process still running?NzThe kernel: z
 is alive.Tz no longer exists.F)r   r`   rV   rK   r^   r,   s    r.   is_alivezGatewayKernelManager.is_aliveB  s      ? 	 $ 2 2 4 4444444DKHNNA$+AAABBB4HNNI$+IIIJJJ5r0   c                    dS )z/Clean up resources when the kernel is shut downNr+   )r-   rp   s     r.   cleanup_resourcesz&GatewayKernelManager.cleanup_resourcesM        r0   r   r|   r}   )r~   r   r   r   rD   r   rV   r   r   r9   propertyr   r   client_classr   r   r   r`   r   rO   rq   rs   ru   r  r  r   r   s   @r.   r   r   |  s        @@#I####FW]  
& 
& 
& 
& 
& ' ' X' $#$YZZLT UVVVN) ) ) % % % %V 5  1[ 1[ 1[f 6      7  ] ] ] 9  _ _ _	 	 	> > > > > > > >r0   r   c                       e Zd ZU dZdZded<   ded<   d fdZddZddZddZ	e
d             ZddZddZd dZ xZS )!ChannelQueuezA queue for a named channel.Nr   channel_namer   response_router_finishedrU   channel_socketwebsocket.WebSocketrK   r%   c                    t                                                       || _        || _        || _        d| _        dS )zInitialize a channel queue.FN)r8   r9   r  r  rK   r  )r-   r  r  rK   r@   s       r.   r9   zChannelQueue.__init__Z  s>    (,(-%%%r0   c                X  K   |t          d          }n|dk     rd}t          |          t                      |z   }	 	 |                     d          S # t          $ rI | j        rd}t          |          dt                      |k    r t          j        d           d{V  Y nw xY wn)	z"Asynchronously get from the queue.Ninfr   z''timeout' must be a non-negative numberTF)blockzResponse router had finished)	float
ValueErrorr   r   r   r  RuntimeErrorasynciosleep)r-   timeoutr   end_times       r.   
_async_getzChannelQueue._async_getb  s      ?EllGGq[[;CS//!;;(		''xxex,,, ' ' '0 68C&s++5;;))mA&&&&&&&&&&&'		's   A AB('B(argsr	   r?   r   dict[str, Any]c                  K   |                     dd          }|                     |           d{V }| j                            d| j        |d         |r|d         nd           |                                  t          d	|          S )
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nullr  )r   r  rK   r^   r  	task_doner   )r-   r  r?   r  r   s        r.   get_msgzChannelQueue.get_msgv  s      **Y**OOGO44444444GM".C
OO		
 	
 	
 	$c***r0   r   Nonec                   t          j        |t          j                                      dd          }| j                            d| j        |d         |r|d         nd           | j        	                    |           dS )	zSend a message to the queue.)r   z</z<\/z8Sending message on channel: %s, msg_id: %s, msg_type: %sr  r   r!  N)
jsondumpsr  serialize_datetimer   rK   r^   r  r  send)r-   r   messages      r.   r)  zChannelQueue.send  s    *S,*IJJJRRSWY_``FM".C
OO		
 	
 	
 	  )))))r0   c                b    t          | t          j                  r|                                 S dS )zSerialize a datetime object.N)r   r   	timestamp)dts    r.   r(  zChannelQueue.serialize_datetime  s,     b(+,, 	"<<>>!tr0   c                    dS )zStart the queue.Nr+   r,   s    r.   startzChannelQueue.start  r  r0   c           	        |                                  sg }|                                 rO|                                 }|d         dk    r|                    |d                    |                                 O| j        dk    rd|v rdS t          |          r:| j                            d| j         dt          |           d| d	           dS dS dS )
zStop the queue.r   statusiopubshutdown_replyNzStopping channel 'z' with z" unprocessed non-status messages: .)emptyqsize
get_nowaitrd   r  r   rK   rb   )r-   msgsr   s      r.   stopzChannelQueue.stop  s    zz|| 	 D**,, 1oo''z?h..KKJ000 **,, 1  G++0@D0H0H4yy   w):ww3t99wwptwww    	 	 r0   c                    | j         duS )zWhether the queue is alive.N)r  r,   s    r.   r  zChannelQueue.is_alive  s    "$..r0   )r  rU   r  r  rK   r%   r   )r  r	   r?   r	   r   r  )r   r  r   r$  )r   r$  r   r   )r~   r   r   r   r  r   r9   r  r#  r)  r   r(  r/  r9  r  r   r   s   @r.   r  r  T  s         &&"&L&&&&"""". . . . . .' ' ' '(+ + + +	* 	* 	* 	*   \      $/ / / / / / / /r0   r  c                      e Zd ZdZddZdS )HBChannelQueuez"A queue for the heartbeat channel.r   r   c                *    |                                  S )zWhether the channel is beating.)r  r,   s    r.   
is_beatingzHBChannelQueue.is_beating  s     }}r0   Nr;  )r~   r   r   r   r?  r+   r0   r.   r=  r=    s.        ,,     r0   r=  c                       e Zd ZU dZdZded<   ded<   ded<   ded	<   ded
<   ded<   ded<    fdZd fd	Z fdZe	d             Z
e	d             Ze	d             Ze	d             Ze	d             Zd Z xZS )GatewayKernelClienta  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                     t                      j        di | || _        d| _        d| _        d| _        i | _        dS )z#Initialize a gateway kernel client.NFr+   )r8   r9   rD   r  response_routerrB  rC  )r-   rD   r?   r@   s      r.   r9   zGatewayKernelClient.__init__  sM    ""6""""=A15!&!r0   Tc           	     ~  K   t          t          j                    j        pdt          j                    j        t          | j                  d          }t          j                    j        t          j                    j        t          j                    j	        d}t          j        |t          j                    j        d|          | _        t          t                                          |||||                     d{V  t#          | j                  | _        | j                                         dS )	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.
        r7   channels)ca_certscertfilekeyfileT)r  enable_multithreadsslopt)shellr2  stdinhbcontrolN)target)r!   r#   r:   ws_urlr<   r   rD   rM  client_cert
client_key	websocketcreate_connectionKERNEL_LAUNCH_TIMEOUTr  r   r8   start_channelsr   _route_responsesrJ  r/  )	r-   rR  r2  rS  rT  rU  rW  ssl_optionsr@   s	           r.   r]  z"GatewayKernelClient.start_channels  s@      "$$+1r"$$5t~&&	
 
 &.009%.00<$-//:
 
 (9!*,,B#	
 
 
 GG""e5RY`"aa
 
 	
 	
 	
 	
 	
 	
 	
  &T-BCCC""$$$$$r0   c                d   t                                                       d| _        | j                            d           | j        J | j                                         | j        J | j                                         | j	        r"| j	        
                                 d| _	        dS dS )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)r8   stop_channelsrB  rK   r^   r  closerJ  joinrC  clearr{   s    r.   ra  z!GatewayKernelClient.stop_channels  s     	!%5666"...!!####///!!### 	( &&(((#'D   	( 	(r0   c                    | j         [| j                            d           | j        J t	          d| j        | j                  | _         | j        J | j         | j        d<   | j         S )z-Get the shell channel object for this kernel.Nzcreating shell channel queuerR  )rH  rK   r^   r  r  rC  r,   s    r.   shell_channelz!GatewayKernelClient.shell_channel  r     &HNN9:::&222".w8KTX"V"VD'333,0,?D )""r0   c                    | j         [| j                            d           | j        J t	          d| j        | j                  | _         | j        J | j         | j        d<   | j         S )z-Get the iopub channel object for this kernel.Nzcreating iopub channel queuer2  )rG  rK   r^   r  r  rC  r,   s    r.   iopub_channelz!GatewayKernelClient.iopub_channel#  rg  r0   c                    | j         [| j                            d           | j        J t	          d| j        | j                  | _         | j        J | j         | j        d<   | j         S )z-Get the stdin channel object for this kernel.Nzcreating stdin channel queuerS  )rF  rK   r^   r  r  rC  r,   s    r.   stdin_channelz!GatewayKernelClient.stdin_channel.  rg  r0   c                    | j         [| j                            d           | j        J t	          d| j        | j                  | _         | j        J | j         | j        d<   | j         S )z*Get the hb channel object for this kernel.Nzcreating hb channel queuerT  )rE  rK   r^   r  r=  rC  r,   s    r.   
hb_channelzGatewayKernelClient.hb_channel9  sr     #HNN6777&222-dD4GRRD'333)-)9D &r0   c                    | j         [| j                            d           | j        J t	          d| j        | j                  | _         | j        J | j         | j        d<   | j         S )z/Get the control channel object for this kernel.Nzcreating control channel queuerU  )rD  rK   r^   r  r  rC  r,   s    r.   control_channelz#GatewayKernelClient.control_channelD  st      (HNN;<<<&222$0D<OQUQY$Z$ZD!'333.2.CD +$$r0   c                .   	 | j         sy| j        J | j                                        }|snTt          t	          |                    }|d         }| j        J | j        |                             |           | j         ynL# t          j        $ r Y n;t          $ r/}| j         s| j
                            d| d           Y d}~nd}~ww xY w| j        J | j                                        D ]	}d|_        
| j
                            d           dS )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...)rB  r  recvr   r   rC  
put_nowaitrZ  "WebSocketConnectionClosedExceptionBaseExceptionrK   rb   rf   r  r^   )r-   raw_messageresponse_messagerq  bechannel_queues         r.   r^  z$GatewayKernelClient._route_responsesO  sd   	M, K*666"16688" #.tK/@/@#A#A *95+777$W-889IJJJ , K ; 	 	 	D 	M 	M 	M) M  !Kb!K!K!KLLL	M
 #///!188:: 	: 	:M59M22:;;;;;s   B B C	C%CC)TTTTT)r~   r   r   r   allow_stdinr   r9   r]  ra  r  rf  ri  rk  rm  ro  r^  r   r   s   @r.   rA  rA    sm         " K6666,,,,''''************" " " " "!% !% !% !% !% !%F( ( ( ( (* # # X# # # X# # # X#     X  % % X%< < < < < < <r0   rA  )Br   
__future__r   r  r   r&  r   queuer   r   	threadingr   timer   typingr   r	   r
   r   rZ  "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  r=  rA  r+   r0   r.   <module>r     s     # " " " " "    				                     5 5 5 5 5 5 5 5 5 5 5 5     @ @ @ @ @ @ 4 4 4 4 4 4 7 7 7 7 7 7 6 6 6 6 6 6 + + + + + +       E E E E E E E E E E E E ? ? ? ? ? ? ? ? ? ? ? ?                 
 > = = = = = ! ! ! ! ! ! : : : : : : : : l% l% l% l% l%"; l% l% l%^K$ K$ K$ K$ K$0 K$ K$ K$\    N   .R> R> R> R> R>. R> R> R>j   . / / /X/ X/ X/ X/ X/5 X/ X/ X/v    \   v< v< v< v< v<+ v< v< v<r  , - - - - -r0   