
    ^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rSSKrSSK	J
r
Jr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  SS	KJr  SS
KJrJr  SSKJrJr  SSKJ r   SSK!J"r"J#r#  SSK$J%r%  SSK&J'r'  \RP                  " S\)SS9  \*" \RV                  " SS5      5      r, " S S\\#5      r- " S S\ 5      r. " S S\"5      r/SSK0J1r1  SSK2J3r3  S\1-  \-4S\3-  \/4/r4g) zGateway API handlers.    )annotationsN)Any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                     ^  \ rS rSrSrSrSrSrSrSS jr	S r
S rS rS rU 4S	 jrS
 rS rS rSU 4S jjrU 4S jr\S 5       rSrU =r$ )WebSocketChannelsHandler'   z$Gateway web socket channels handler.Nc                .    [         R                  " X5      $ )zCheck origin for the socket.)r   check_origin)selforigins     Y/home/james-whalen/.local/lib/python3.13/site-packages/jupyter_server/gateway/handlers.pyr    %WebSocketChannelsHandler.check_origin/   s    **488    c                    g)zVUndo the set_default_headers in JupyterHandler which doesn't make sense for websocketsN r!   s    r#   set_default_headers,WebSocketChannelsHandler.set_default_headers3   s    r%   c                    0 $ )z+Get the compression options for the socket.r'   r(   s    r#   get_compression_options0WebSocketChannelsHandler.get_compression_options6   s	     	r%   c                D   U R                   c1  U R                  R                  S5        [        R                  " S5      eU R                  SS5      (       a0  U R                  c   eU R                  S5      U R                  l        gU R                  R                  S5        g)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#   authenticate%WebSocketChannelsHandler.authenticate;   s     $HHIJ--$$\400<<+++#'#4#4\#BDLL HH67r%   c                    U R                   R                  SU R                  R                  5        [	        U R
                  S9U l        [        [        R                  " 5       R                  S9U l        g)zInitialize the socket.z$Initializing websocket connection %s)config)gateway_urlN)r1   debugrequestpathr   r9   r5   GatewayWebSocketClientr   instanceurlgatewayr(   s    r#   
initialize#WebSocketChannelsHandler.initializeL   sJ    =t||?P?PQdkk2--:P:P:R:V:VWr%   c                v   >#    U R                  5         Xl        XS'   [        TU ]  " U0 UD6I Sh  vN   g N7f)zGet the socket.	kernel_idN)r6   rE   superget)r!   rE   argskwargs	__class__s       r#   rG   WebSocketChannelsHandler.getR   s6     "'{gk4*6***s   .979c                    U R                   c(  U R                  b  U R                  R                  5         gU R                  S5        g)zSend a ping to the socket.Nr%   )ws_connectionping_callbackstoppingr(   s    r#   	send_ping"WebSocketChannelsHandler.send_pingY   s9    %$*<*<*H##%		#r%   c                    [        U R                  [        S-  5      U l        U R                  R	                  5         U R
                  c   eU R
                  R                  UU R                  U R                  5       S9  g)z_Handle web socket connection open to notebook server and delegate to gateway web socket handleri  N)rE   message_callbackcompression_options)	r   rQ   r   rN   startrA   on_openwrite_messager,   )r!   rE   rH   rI   s       r#   openWebSocketChannelsHandler.opena   sm    -dnn>[^b>bc  "||'''!// $ < < > 	 	
r%   c                X    U R                   c   eU R                   R                  U5        g)z.Forward message to gateway web socket handler.N)rA   
on_message)r!   messages     r#   r\   #WebSocketChannelsHandler.on_messagem   s$    ||'''(r%   c                Z  > U R                   (       a%  [        U[        5      (       a  Sn[        TU ]  XS9  gU R
                  R                  [        R                  5      (       aF  [        R                  [        [        U5      5      5      nU R
                  R                  SU 35        gg)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)rM   
isinstancebytesrF   rX   r1   isEnabledForloggingDEBUGr   _get_message_summaryr
   r   r;   )r!   r]   r`   msg_summaryrJ   s       r#   rX   &WebSocketChannelsHandler.write_messager   s    '5))G!'!9XX""7==112GGTXY`TaHbcKHHNNQR]Q^_ 2r%   c                   > U R                   R                  SU R                  R                  5        U R                  c   eU R                  R                  5         [        TU ]  5         g)zHandle a closing socket.zClosing websocket connection %sN)r1   r;   r<   r=   rA   on_closerF   )r!   rJ   s    r#   rj   !WebSocketChannelsHandler.on_close~   sK    8$,,:K:KL||'''r%   c                L   / nU S   nUR                  SU 35        US:X  a'  UR                  SR                  U S   S   5      5        OLUS:X  a5  UR                  SR                  U S   S	   U S   S
   U S   S   5      5        OUR                  S5        SR                  U5      $ )zGet a summary of a message.msg_typeztype: statusz, state: {}contentexecution_stateerrorz
, {}:{}:{}enameevalue	tracebackz, ... )appendformatjoin)r]   summarymessage_types      r#   rf   -WebSocketChannelsHandler._get_message_summary   s     z*~./8#NN=//	0BCT0UVWW$NN##I&w/I&x0I&{3 NN7#wwwr%   )rA   rE   rN   r5   N)F)__name__
__module____qualname____firstlineno____doc__r5   rA   rE   rN   r    r)   r,   r6   rB   rG   rQ   rY   r\   rX   rj   staticmethodrf   __static_attributes____classcell__rJ   s   @r#   r   r   '   sg    .GGIM9e
8"X+

)

    r%   r   c                  \   ^  \ rS rSrSrU 4S jrS rS rS rS r	S r
S	 rS
 rS rSrU =r$ )r>      z;Proxy web socket connection to a kernel/enterprise gateway.c                x   > [         TU ]  5         SU l        SU l        [	        5       U l        SU l        SU l        g)z)Initialize the gateway web socket client.NFr   )rF   __init__rE   wsr	   	ws_futuredisconnectedretry)r!   rI   rJ   s     r#   r   GatewayWebSocketClient.__init__   s4    &,h!
r%   c                0  ^ ^#    ST l         UT l        [        R                  " 5       nUR                  c   e[        UR                  UR                  [        U5      S5      nT R                  R                  SU 35        0 nUR                  " S0 UD6n[        U40 UD6n[        S[        U5      5      T l        T R                  R                  T R                   5        ["        R$                  " 5       nUR'                  T R                  UU 4S j5        g7f)zConnect to the socket.NchannelszConnecting to zFuture[Any]c                &   > TR                  T5      $ r|   )_read_messages)futurerT   r!   s    r#   <lambda>1GatewayWebSocketClient._connect.<locals>.<lambda>   s    t7J7JK[7\r%   r'   )r   rE   r   r?   ws_urlr   kernels_endpointr   r1   infoload_connection_argsr   r   r   r   add_done_callback_connection_doner   current
add_future)r!   rE   rT   clientr   rI   r<   loops   ` `     r#   _connectGatewayWebSocketClient._connect   s      "'')}}(((MM##y!	
 	vh/0!#,,6v6f//m->w-GH(()>)>?~~(\]s   DDc                b   U R                   (       dV  UR                  5       cE  UR                  5       U l        SU l        U R
                  R                  SU R                   35        gU R
                  R                  SU R                   S[        R                  " 5       R                   35        g)zHandle a finished connection.Nr   zConnection is ready: ws: z]Websocket connection has been closed via client disconnect or due to error.  Kernel with ID 'z*' may not be terminated on GatewayClient: )r   	exceptionresultr   r   r1   r;   r2   rE   r   r?   r@   )r!   futs     r#   r   'GatewayWebSocketClient._connection_done   s     !!cmmo&=jjlDGDJHHNN6twwi@AHH##'>>"22\]j]s]s]u]y]y\z|r%   c                &   SU l         U R                  b  U R                  R                  5         gU R                  R	                  5       (       dC  U R                  R                  5         U R                  R                  SU R                    35        gg)zHandle a disconnect.TNz-_disconnect: future cancelled, disconnected: )r   r   closer   donecancelr1   r;   r(   s    r#   _disconnect"GatewayWebSocketClient._disconnect   sh     77GGMMO$$&&NN!!#HHNNJ4K\K\J]^_ 'r%   c                  #    U R                   b  SnU R                  (       di   U R                   R                  5       I Sh  vN nUc:  U R                  (       d(  U R                  R                  SU R                   35        OU" U5        OOU R                   b  M  U R                  (       Gdb  U R                  [        R                  " 5       R                  :  Ga3  [        R                  " SS5      S-  n[        [        R                  " 5       R                  SU R                  -  -  [        R                  " 5       R                   5      U-   nU =R                  S-  sl        U R                  R#                  S	UU R                  [        R                  " 5       R                  U R                  5        [$        R&                  " U5      I Sh  vN   [(        R*                  " 5       nUR-                  U R.                  U R                  U5        ggg GN! [         a)  nU R                  R                  SU 35         SnAGNSnAff = f N|7f)
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)r   r   read_message	Exceptionr1   rq   r2   rE   r   r   r?   gateway_retry_maxrandomrandintmingateway_retry_intervalgateway_retry_interval_maxr   asynciosleepr   r   spawn_callbackr   )r!   callbackr]   ejitterretry_intervalr   s          r#   r   %GatewayWebSocketClient._read_messages   s    gg!G$$$(GG$8$8$::G
 ?,,((+GGW)XY # gg!(    TZZ-2H2H2J2\2\%\^^B,t3F!**,CCq$**}U!**,GG 	  JJ!OJHHMM]

&&(:: --///>>#Dt~~xH' &] ! ;  HHNNDQCH @ 0sU   !IH HH AID1II
AIH 
II<IIIc                f    [         R                  " 5       nUR                  U R                  X5        g)z2Web socket connection open against gateway server.N)r   r   r   r   )r!   rE   rT   rI   r   s        r#   rW   GatewayWebSocketClient.on_open  s"    ~~DMM9Gr%   c                   ^ ^ T R                   c7  [        R                  " 5       nUR                  T R                  UU 4S j5        gT R                  T5        g)Send message to gateway server.Nc                &   > TR                  T5      $ r|   )_write_message)r   r]   r!   s    r#   r   3GatewayWebSocketClient.on_message.<locals>.<lambda>  s    4;N;Nw;Wr%   )r   r   r   r   r   r   )r!   r]   r   s   `` r#   r\   !GatewayWebSocketClient.on_message
  s9    77?>>#DOODNN,WX(r%   c                     U R                   (       d*  U R                  b  U R                  R                  U5        ggg! [         a(  nU R                  R                  SU 35         SnAgSnAff = f)r   Nz(Exception writing message to websocket: )r   r   rX   r   r1   rq   )r!   r]   r   s      r#   r   %GatewayWebSocketClient._write_message  sa    	K$$)<%%g. *=$ 	KHHNNEaSIJJ	Ks   9> 
A0A++A0c                $    U R                  5         g)zWeb socket closed event.N)r   r(   s    r#   rj   GatewayWebSocketClient.on_close  s    r%   )r   rE   r   r   r   )r}   r~   r   r   r   r   r   r   r   r   rW   r\   r   rj   r   r   r   s   @r#   r>   r>      s>    E^2	`)IVH
)K r%   r>   c                  @    \ rS rSrSr\R                  SS j5       rSrg)GatewayResourceHandleri  zWRetrieves resources for specific kernelspec definitions from kernel/enterprise gateway.c                  #    SnU R                   nUR                  X5      I Sh  vN nUc#  U R                  R                  SU SU S35        O"[        R
                  " U5      S   =(       d    SnU R                  XdS9  g N\7f)z(Get a gateway resource by name and path.NzKernelspec resource 'z' for 'z7' not found.  Gateway may not support resource serving.r   z
text/plain)set_content_type)kernel_spec_managerget_kernel_spec_resourcer1   r2   	mimetypes
guess_typefinish)r!   kernel_namer=   include_bodymimetypeksmkernel_spec_ress          r#   rG   GatewayResourceHandler.get"  s      #'&& # < <!
 
 "HH'vW[M B% %
 !++D1!4DHO?
s   #BBABr'   N)T)	r}   r~   r   r   r   r   authenticatedrG   r   r'   r%   r#   r   r     s    a@ @r%   r   )_kernel_id_regex)kernel_name_regexz/api/kernels/%s/channelsz/kernelspecs/%s/(?P<path>.*))5r   
__future__r   r   rd   r   osr   warningstypingr   r   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   r>   r   services.kernels.handlersr   services.kernelspecs.handlersr   default_handlersr'   r%   r#   <module>r      s     #    	   & & *  % 8 8 * 3 A = 6 ! ) n !$BII.Mt$T U r / r j@0 @F@Z @* 9 = !#335MN$'88:PQ r%   