
    Ke.                        d 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	 ddl
mZ ddlmZ ddlmZ ddlmZmZmZ ddlmZ dd	lmZmZ dd
lmZmZ ddlmZ ddlmZm Z  ddl!m"Z" ddl#m$Z$  ej%        de&d            e' ej(        dd                    Z) G d dee           Z* G d de          Z+ G d de          Z,ddl-m.Z. ddl/m0Z0 de.z  e*fde0z  e,fgZ1dS )zGateway API handlers.    N)Optionalcast)Session)web)Future)json_decode
url_escapeutf8)HTTPRequest)IOLoopPeriodicCallback)WebSocketHandlerwebsocket_connect)LoggingConfigurable   )
APIHandlerJupyterHandler)url_path_join   )GatewayClientzhThe jupyter_server.gateway.handlers module is deprecated and will not be supported in Jupyter Server 3.0)
stacklevelGATEWAY_WS_PING_INTERVAL_SECS30c                        e Zd ZdZdZdZdZdZddZd Z	d Z
d Zd Z fdZd	 Zd
 Zd Zd fd	Z fdZed             Z xZS )WebSocketChannelsHandlerz$Gateway web socket channels handler.Nc                 ,    t          j        | |          S )zCheck origin for the socket.)r   check_origin)selforigins     ?lib/python3.11/site-packages/jupyter_server/gateway/handlers.pyr   z%WebSocketChannelsHandler.check_origin,   s    *4888    c                     dS )zVUndo the set_default_headers in JupyterHandler which doesn't make sense for websocketsN r   s    r    set_default_headersz,WebSocketChannelsHandler.set_default_headers0   s    r!   c                     i S )z+Get the compression options for the socket.r#   r$   s    r    get_compression_optionsz0WebSocketChannelsHandler.get_compression_options4   s	     	r!   c                 $   | j         .| j                            d           t          j        d          |                     dd          r*| j        J |                     d          | j        _        dS | j                            d           dS )zRun before finishing the GET request

        Extend this method to add logic that should fire before
        the websocket finishes completing.
        Nz*Couldn't authenticate WebSocket connectioni  
session_idzNo session ID specified)current_userlogwarningr   	HTTPErrorget_argumentsessionr$   s    r    authenticatez%WebSocketChannelsHandler.authenticate9   s     $HIJJJ-$$$\400 	8<+++#'#4#4\#B#BDL   H677777r!   c                     | j                             d| j        j                   t	          | j                  | _        t          t          j	                    j
                  | _        dS )zInitialize the socket.z$Initializing websocket connection %s)config)gateway_urlN)r+   debugrequestpathr   r2   r/   GatewayWebSocketClientr   instanceurlgatewayr$   s    r    
initializez#WebSocketChannelsHandler.initializeJ   sT    =t|?PQQQdk222--:P:R:R:VWWWr!   c                    K   |                                   || _        ||d<    t                      j        |i | d{V  dS )zGet the socket.	kernel_idN)r0   r=   superget)r   r=   argskwargs	__class__s       r    r?   zWebSocketChannelsHandler.getP   s]      "'{eggk4*6***********r!   c                     | j         "| j        | j                                         dS |                     d           dS )zSend a ping to the socket.Nr!   )ws_connectionping_callbackstoppingr$   s    r    	send_pingz"WebSocketChannelsHandler.send_pingW   s@    %$*<*H##%%%F		#r!   c                     t          | j        t          dz            | _        | j                                         | j        J | j                            || j        |                                            dS )z_Handle web socket connection open to notebook server and delegate to gateway web socket handleri  N)r=   message_callbackcompression_options)	r   rH   r   rE   startr:   on_openwrite_messager'   )r   r=   r@   rA   s       r    openzWebSocketChannelsHandler.open_   s    -dn>[^b>bcc  """|'''!/ $ < < > > 	 	
 	
 	
 	
 	
r!   c                 L    | j         J | j                             |           dS )z.Forward message to gateway web socket handler.N)r:   
on_message)r   messages     r    rQ   z#WebSocketChannelsHandler.on_messagek   s,    |'''(((((r!   Fc                 |   | j         r<t          |t                    rd}t                                          ||           dS | j                            t          j                  rSt          
                    t          t          |                              }| j                            d|            dS dS )zdSend message back to notebook client.  This is called via callback from self.gateway._read_messages.T)binaryz?Notebook client closed websocket connection - message dropped: N)rD   
isinstancebytesr>   rN   r+   isEnabledForloggingDEBUGr   _get_message_summaryr   r
   r4   )r   rR   rT   msg_summaryrB   s       r    rN   z&WebSocketChannelsHandler.write_messagep   s     	'5)) GG!!'&!99999X""7=11 	2GGTXY`TaTaHbHbccKHNN_R]__    	 	r!   c                     | j                             d| j        j                   | j        J | j                                         t                                                       dS )zHandle a closing socket.zClosing websocket connection %sN)r+   r4   r5   r6   r:   on_closer>   )r   rB   s    r    r]   z!WebSocketChannelsHandler.on_close|   s]    8$,:KLLL|'''r!   c                    g }| d         }|                     d|            |dk    r5|                     d                    | d         d                              nj|dk    rO|                     d                    | d         d	         | d         d
         | d         d                              n|                     d           d                    |          S )zGet a summary of a message.msg_typeztype: statusz, state: {}contentexecution_stateerrorz
, {}:{}:{}enameevalue	tracebackz, ... )appendformatjoin)rR   summarymessage_types      r    rZ   z-WebSocketChannelsHandler._get_message_summary   s     z*...///8##NN=//	0BCT0UVVWWWWW$$NN##I&w/I&x0I&{3     NN7###wwwr!   N)F)__name__
__module____qualname____doc__r/   r:   r=   rE   r   r%   r'   r0   r;   r?   rH   rO   rQ   rN   r]   staticmethodrZ   __classcell__rB   s   @r    r   r   $   s$       ..GGIM9 9 9 9    
8 8 8"X X X+ + + + +  

 

 

) ) )

 
 
 
 
 
         \         r!   r   c                   R     e Zd ZdZ fdZd Zd Zd Zd Zd Z	d Z
d	 Zd
 Z xZS )r7   z;Proxy web socket connection to a kernel/enterprise gateway.c                     t                                                       d| _        d| _        t	                      | _        d| _        d| _        dS )z)Initialize the gateway web socket client.NFr   )r>   __init__r=   wsr   	ws_futuredisconnectedretry)r   rA   rB   s     r    rw   zGatewayWebSocketClient.__init__   sE    !'!


r!   c                    K   d _         | _        t          j                    }|j        J t          |j        |j        t          |          d          } j        	                    d|            i } |j
        di |}t          |fi |}t          t          t          |                     _         j                             j                   t%          j                    }|                     j         fd           dS )zConnect to the socket.NchannelszConnecting to c                 .                                   S rm   )_read_messages)futurerJ   r   s    r    <lambda>z1GatewayWebSocketClient._connect.<locals>.<lambda>   s    t7J7JK[7\7\ r!   r#   )rx   r=   r   r8   ws_urlr   kernels_endpointr	   r+   infoload_connection_argsr   r   r   r   ry   add_done_callback_connection_doner   current
add_future)r   r=   rJ   clientr   rA   r5   loops   ` `     r    _connectzGatewayWebSocketClient._connect   s      "'))}(((M#y!!	
 
 	/v//000,,66v66f////f&7&@&@AA(()>???~(\(\(\(\(\]]]]]r!   c                 V   | j         sX|                                D|                                | _        d| _        | j                            d| j                    dS | j                            d                    | j	        t          j                    j                             dS )zHandle a finished connection.Nr   zConnection is ready: ws: zWebsocket connection has been closed via client disconnect or due to error.  Kernel with ID '{}' may not be terminated on GatewayClient: {})rz   	exceptionresultrx   r{   r+   r4   r,   ri   r=   r   r8   r9   )r   futs     r    r   z'GatewayWebSocketClient._connection_done   s     !	&)mmoo&=jjllDGDJHNN@tw@@AAAAAHQQWQWNM$:$<$<$@R R    r!   c                    d| _         | j        | j                                         dS | j                                        s=| j                                         | j                            d| j                     dS dS )zHandle a disconnect.TNz-_disconnect: future cancelled, disconnected: )rz   rx   closery   donecancelr+   r4   r$   s    r    _disconnectz"GatewayWebSocketClient._disconnect   s     7GMMOOOOO$$&& 	`N!!###HNN^4K\^^_____	` 	`r!   c                   K   | j         d}| j        s	 | j                                          d{V }n4# t          $ r'}| j                            d|            Y d}~nd}~ww xY w|*| j        s"| j                            d| j                    n ||           nn| j         | j        s"| j        t          j
                    j        k     rt          j        dd          dz  }t          t          j
                    j        d| j        z  z  t          j
                    j                  |z   }| xj        dz  c_        | j                            d	|| j        t          j
                    j        | j                   t%          j        |           d{V  t)          j                    }|                    | j        | j        |           dS dS dS )
z"Read messages from gateway server.Nz*Exception reading message from websocket: zLost connection to Gateway: 
   d   g{Gz?r   r   zKAttempting to re-establish the connection to Gateway in %s secs (%s/%s): %s)rx   rz   read_message	Exceptionr+   rc   r,   r=   r{   r   r8   gateway_retry_maxrandomrandintmingateway_retry_intervalgateway_retry_interval_maxr   asynciosleepr   r   spawn_callbackr   )r   callbackrR   ejitterretry_intervalr   s          r    r   z%GatewayWebSocketClient._read_messages   s5     g!G$ $(G$8$8$:$:::::::GG    HNNHQHH        ?, Z(()X)X)XYYY    # g!(   	ITZ-2H2J2J2\%\%\^B,,t3F!*,,Cq$*}U!*,,G  	  JJ!OJJHMM]
&((:   -/////////>##Dt~xHHHHH'	I 	I%\%\s   4 
A%A  A%c                 d    t          j                    }|                    | j        ||           dS )z2Web socket connection open against gateway server.N)r   r   r   r   )r   r=   rJ   rA   r   s        r    rM   zGatewayWebSocketClient.on_open  s0    ~DM96FGGGGGr!   c                       j         4t          j                    }|                     j         fd           dS                                 dS )Send message to gateway server.Nc                 .                                   S rm   )_write_message)r   rR   r   s    r    r   z3GatewayWebSocketClient.on_message.<locals>.<lambda>  s    4;N;Nw;W;W r!   )rx   r   r   r   ry   r   )r   rR   r   s   `` r    rQ   z!GatewayWebSocketClient.on_message
  s[    7?>##DOODN,W,W,W,W,WXXXXX(((((r!   c                     	 | j         s#| j        | j                            |           dS dS dS # t          $ r(}| j                            d|            Y d}~dS d}~ww xY w)r   Nz(Exception writing message to websocket: )rz   rx   rN   r   r+   rc   )r   rR   r   s      r    r   z%GatewayWebSocketClient._write_message  s    	K$ /)<%%g...../ /)<)< 	K 	K 	KHNNIaIIJJJJJJJJJ	Ks   (0 
A"AA"c                 .    |                                   dS )zWeb socket closed event.N)r   r$   s    r    r]   zGatewayWebSocketClient.on_close  s    r!   )rn   ro   rp   rq   rw   r   r   r   r   rM   rQ   r   r]   rs   rt   s   @r    r7   r7      s        EE    ^ ^ ^2   	` 	` 	`)I )I )IVH H H
) ) )K K K      r!   r7   c                   4    e Zd ZdZej        dd            ZdS )GatewayResourceHandlerzWRetrieves resources for specific kernelspec definitions from kernel/enterprise gateway.Tc                   K   d}| j         }|                    ||           d{V }|/| j                            d                    ||                     nt          j        |          d         pd}|                     ||           dS )z(Get a gateway resource by name and path.NzWKernelspec resource '{}' for '{}' not found.  Gateway may not support resource serving.r   z
text/plain)set_content_type)kernel_spec_managerget_kernel_spec_resourcer+   r,   ri   	mimetypes
guess_typefinish)r   kernel_namer6   include_bodymimetypeksmkernel_spec_ress          r    r?   zGatewayResourceHandler.get"  s       #'& # < <!
 !
 
 
 
 
 
 
 "H%%+VD+%>%>   
 !+D11!4DHOh?????r!   N)T)rn   ro   rp   rq   r   authenticatedr?   r#   r!   r    r   r     sB        aa@ @ @ @ @ @r!   r   )_kernel_id_regex)kernel_name_regexz/api/kernels/%s/channelsz/kernelspecs/%s/(?P<path>.*))2rq   r   rX   r   osr   warningstypingr   r   jupyter_client.sessionr   tornador   tornado.concurrentr   tornado.escaper   r	   r
   tornado.httpclientr   tornado.ioloopr   r   tornado.websocketr   r   traitlets.config.configurabler   base.handlersr   r   utilsr   gateway_clientr   warnDeprecationWarningintgetenvr   r   r7   r   services.kernels.handlersr   services.kernelspecs.handlersr   default_handlersr#   r!   r    <module>r      sw           				   ! ! ! ! ! ! ! ! * * * * * *       % % % % % % 8 8 8 8 8 8 8 8 8 8 * * * * * * 3 3 3 3 3 3 3 3 A A A A A A A A = = = = = = 6 6 6 6 6 6 6 6 ! ! ! ! ! ! ) ) ) ) ) ) n    !$IBI.Mt$T$T U U s  s  s  s  s / s  s  s lB B B B B0 B B BJ@ @ @ @ @Z @ @ @* 9 8 8 8 8 8 = = = = = = !#335MN$'88:PQ   r!   