o
    tf.                     @  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_SECSZ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   h/var/www/html/software/conda/envs/catlas/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  Z
session_idzNo session ID specified)current_userlogwarningr   	HTTPErrorZ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)Z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)   r3   supergetr   r3   argskwargs	__class__r   r   r5   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stopZ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)r3   message_callbackZcompression_options)	r   r?   r   r=   startr1   on_openwrite_messager#   r6   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)r1   
on_message)r   messager   r   r   rE   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bytesr4   rC   r%   isEnabledForloggingDEBUGr   _get_message_summaryr	   r   r+   )r   rF   rG   Zmsg_summaryr9   r   r   rC   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+   r,   r-   r1   on_closer4   r!   r9   r   r   rN   ~   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: {}contentZexecution_stateerrorz
, {}:{}:{}ZenameZevalue	tracebackz, ... )appendformatjoin)rF   summaryZmessage_typer   r   r   rM      s   




z-WebSocketChannelsHandler._get_message_summaryN)F)__name__
__module____qualname____doc__r(   r1   r3   r=   r   r"   r#   r)   r2   r5   r?   rD   rE   rC   rN   staticmethodrM   __classcell__r   r   r9   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 )r.   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   )r4   __init__r3   wsr   	ws_futuredisconnectedretry)r   r8   r9   r   r   r`      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.NZchannelszConnecting to zFuture[Any]c                   
     S rY   )_read_messagesfuturer@   r   r   r   <lambda>      
 z1GatewayWebSocketClient._connect.<locals>.<lambda>r   )ra   r3   r   r/   ws_urlr   Zkernels_endpointr
   r%   infoZload_connection_argsr   r   r   rb   add_done_callback_connection_doner   current
add_future)r   r3   r@   clientrl   r8   r,   loopr   ri   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: )rc   	exceptionresultra   rd   r%   r+   r&   r3   r   r/   r0   )r   futr   r   r   ro      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: )rc   ra   closerb   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)ra   rc   Zread_message	Exceptionr%   rR   r&   r3   rd   r   r/   Zgateway_retry_maxrandomrandintminZgateway_retry_intervalZgateway_retry_interval_maxrm   asynciosleepr   rp   spawn_callbackrt   )r   callbackrF   ejitterZretry_intervalrs   r   r   r   rf      sT   

z%GatewayWebSocketClient._read_messagesc                 K  s   t  }|| j|| dS )z2Web socket connection open against gateway server.N)r   rp   r   rt   )r   r3   r@   r8   rs   r   r   r   rB     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                   re   rY   )_write_messagerg   rF   r   r   r   rj     rk   z3GatewayWebSocketClient.on_message.<locals>.<lambda>)ra   r   rp   rq   rb   r   )r   rF   rs   r   r   r   rE   
  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: )rc   ra   rC   r~   r%   rR   )r   rF   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   rN     r    zGatewayWebSocketClient.on_close)rZ   r[   r\   r]   r`   rt   ro   r{   rf   rB   rE   r   rN   r_   r   r   r9   r   r.      s    	+r.   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)Zset_content_type)Zkernel_spec_managerZget_kernel_spec_resourcer%   r&   	mimetypes
guess_typefinish)r   Zkernel_namer-   Zinclude_bodymimetypeZksmZkernel_spec_resr   r   r   r5   "  s   
zGatewayResourceHandler.getN)T)rZ   r[   r\   r]   r   authenticatedr5   r   r   r   r   r     s    r   )_kernel_id_regex)kernel_name_regexz/api/kernels/%s/channelsz/kernelspecs/%s/(?P<path>.*))5r]   
__future__r   r   rK   r   osr   warningstypingr   r   r   Zjupyter_client.sessionr   tornador   Ztornado.concurrentr   Ztornado.escaper	   r
   r   Ztornado.httpclientr   Ztornado.ioloopr   r   Ztornado.websocketr   r   Ztraitlets.config.configurabler   Zbase.handlersr   r   utilsr   Zgateway_clientr   warnDeprecationWarningintgetenvr   r   r.   r   Zservices.kernels.handlersr   Zservices.kernelspecs.handlersr   Zdefault_handlersr   r   r   r   <module>   sF    u 

