o
    ^i.                     @  sr  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ZddlZddl	m
Z
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d e*e+ddZ,G dd dee#Z-G dd de Z.G dd de"Z/ddl0m1Z1 ddl2m3Z3 de1 e-fde3 e/fgZ4dS ) 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                      s   e Zd ZdZdZdZdZdZdddZdd Z	dd Z
d	d
 Zdd Z fddZdd Zdd Zdd Zd fdd	Z fddZedd Z  ZS )WebSocketChannelsHandlerz$Gateway web socket channels handler.Nc                 C  s   t | |S )zCheck origin for the socket.)r   check_origin)selforigin r   Z/home/ubuntu/hpml_nyu/venv/lib/python3.10/site-packages/jupyter_server/gateway/handlers.pyr   /      z%WebSocketChannelsHandler.check_originc                 C  s   dS )zVUndo the set_default_headers in JupyterHandler which doesn't make sense for websocketsNr   r   r   r   r    set_default_headers3   s    z,WebSocketChannelsHandler.set_default_headersc                 C  s   i S )z+Get the compression options for the socket.r   r"   r   r   r    get_compression_options6   s   z0WebSocketChannelsHandler.get_compression_optionsc                 C  s\   | j du r| jd td| ddr&| jdus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"   r   r   r    authenticate;   s   

z%WebSocketChannelsHandler.authenticatec                 C  s6   | j d| jj t| jd| _tt	 j
d| _dS )zInitialize the socket.z$Initializing websocket connection %s)config)gateway_urlN)r'   debugrequestpathr   r-   r+   GatewayWebSocketClientr   instanceurlgatewayr"   r   r   r    
initializeL   s   z#WebSocketChannelsHandler.initializec                   s4   |    || _||d< t j|i |I dH  dS )zGet the socket.	kernel_idN)r,   r7   supergetr   r7   argskwargs	__class__r   r    r9   R   s
   zWebSocketChannelsHandler.getc                 C  s0   | j du r| jdur| j  dS | d dS )zSend a ping to the socket.N    )ws_connectionping_callbackstoppingr"   r   r   r    	send_pingY   s   
z"WebSocketChannelsHandler.send_pingc                 O  sF   t | jtd | _| j  | jdusJ | jj|| j|  d dS )z_Handle web socket connection open to notebook server and delegate to gateway web socket handleri  N)r7   message_callbackcompression_options)	r   rD   r   rA   startr5   on_openwrite_messager$   r:   r   r   r    opena   s   

zWebSocketChannelsHandler.openc                 C  s   | j dusJ | j | dS )z.Forward message to gateway web socket handler.N)r5   
on_message)r   messager   r   r    rK   m   s   z#WebSocketChannelsHandler.on_messageFc                   sb   | j rt|tr
d}t j||d dS | jtjr/t	
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)r@   
isinstancebytesr8   rI   r'   isEnabledForloggingDEBUGr   _get_message_summaryr	   r   r/   )r   rL   rM   msg_summaryr=   r   r    rI   r   s   
z&WebSocketChannelsHandler.write_messagec                   s8   | j d| jj | jdusJ | j  t   dS )zHandle a closing socket.zClosing websocket connection %sN)r'   r/   r0   r1   r5   on_closer8   r"   r=   r   r    rU   ~   s   
z!WebSocketChannelsHandler.on_closec                 C  s   g }| d }| d|  |dkr| d| d d  n |dkr:| 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)rL   summarymessage_typer   r   r    rS      s   




z-WebSocketChannelsHandler._get_message_summaryN)F)__name__
__module____qualname____doc__r+   r5   r7   rA   r   r#   r$   r,   r6   r9   rD   rJ   rK   rI   rU   staticmethodrS   __classcell__r   r   r=   r    r   '   s&    
r   c                      s`   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Z  ZS )r2   z;Proxy web socket connection to a kernel/enterprise gateway.c                   s.   t    d| _d| _t | _d| _d| _dS )z)Initialize the gateway web socket client.NFr   )r8   __init__r7   wsr   	ws_futuredisconnectedretry)r   r<   r=   r   r    rk      s   

zGatewayWebSocketClient.__init__c                   s   d_ |_t }|jdusJ t|j|jt|d}j	d|  i }|j
di |}t|fi |}tdt|_jj t }|j fdd dS )zConnect to the socket.NchannelszConnecting to zFuture[Any]c                   
     S rd   )_read_messagesfuturerE   r   r   r    <lambda>      
 z1GatewayWebSocketClient._connect.<locals>.<lambda>r   )rl   r7   r   r3   ws_urlr   kernels_endpointr
   r'   infoload_connection_argsr   r   r   rm   add_done_callback_connection_doner   current
add_future)r   r7   rE   clientrx   r<   r0   loopr   ru   r    _connect   s&   zGatewayWebSocketClient._connectc                 C  s^   | j s| du r| | _d| _| jd| j  dS | jd| j dt	
 j  dS )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: )rn   	exceptionresultrl   ro   r'   r/   r(   r7   r   r3   r4   )r   futr   r   r    r}      s   
z'GatewayWebSocketClient._connection_donec                 C  sN   d| _ | jdur| j  dS | j s%| j  | jd| j   dS dS )zHandle a disconnect.TNz-_disconnect: future cancelled, disconnected: )rn   rl   closerm   donecancelr'   r/   r"   r   r   r    _disconnect   s   


z"GatewayWebSocketClient._disconnectc              
     sH  | j durNd}| jsHz
| j  I dH }W n ty0 } z| jd|  W Y d}~nd}~ww |du rC| jsB| jd| j  n|| nn| j dus| js| jt	
 jk rtddd }tt	
 jd| j  t	
 j| }|  jd7  _| jd	|| jt	
 j| j t|I dH  t }|| 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)rl   rn   read_message	Exceptionr'   rZ   r(   r7   ro   r   r3   gateway_retry_maxrandomrandintmingateway_retry_intervalgateway_retry_interval_maxrz   asynciosleepr   r~   spawn_callbackr   )r   callbackrL   ejitterretry_intervalr   r   r   r    rr      sT   

z%GatewayWebSocketClient._read_messagesc                 K  s   t  }|| j|| dS )z2Web socket connection open against gateway server.N)r   r~   r   r   )r   r7   rE   r<   r   r   r   r    rH     s   zGatewayWebSocketClient.on_openc                   s<   j du rt }|j fdd dS   dS )Send message to gateway server.Nc                   rq   rd   )_write_messagers   rL   r   r   r    rv     rw   z3GatewayWebSocketClient.on_message.<locals>.<lambda>)rl   r   r~   r   rm   r   )r   rL   r   r   r   r    rK   
  s   
z!GatewayWebSocketClient.on_messagec              
   C  sh   z| j s| jdur| j| W dS W dS W dS  ty3 } z| jd|  W Y d}~dS d}~ww )r   Nz(Exception writing message to websocket: )rn   rl   rI   r   r'   rZ   )r   rL   r   r   r   r    r     s    z%GatewayWebSocketClient._write_messagec                 C  s   |    dS )zWeb socket closed event.N)r   r"   r   r   r    rU     r!   zGatewayWebSocketClient.on_close)re   rf   rg   rh   rk   r   r}   r   rr   rH   rK   r   rU   rj   r   r   r=   r    r2      s    	+r2   c                   @  s    e Zd ZdZejdddZdS )GatewayResourceHandlerzWRetrieves resources for specific kernelspec definitions from kernel/enterprise gateway.Tc                   sf   d}| j }|||I dH }|du r!| jd| d| d n	t|d p)d}| j||d dS )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_resourcer'   r(   	mimetypes
guess_typefinish)r   kernel_namer1   include_bodymimetypeksmkernel_spec_resr   r   r    r9   "  s   
zGatewayResourceHandler.getN)T)re   rf   rg   rh   r   authenticatedr9   r   r   r   r    r     s    r   )_kernel_id_regex)kernel_name_regexz/api/kernels/%s/channelsz/kernelspecs/%s/(?P<path>.*))5rh   
__future__r   r   rQ   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   r2   r   services.kernels.handlersr   services.kernelspecs.handlersr   default_handlersr   r   r   r    <module>   sF    u 

