o
    i(                     @   sF  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
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mZ d dlmZ d dlmZ d dlmZ ddl m!Z! 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l(m)Z) ddl*m+Z+ de) de%fde+ de'fgZ,dS )    N   )
APIHandlerIPythonHandler)url_path_join)genweb)Future)IOLoopPeriodicCallback)WebSocketHandlerwebsocket_connect)HTTPRequest)
url_escapejson_decodeutf8)cast_unicode)Session)LoggingConfigurable   )GatewayClientGATEWAY_WS_PING_INTERVAL_SECS   c                       s   e 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ej 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 )WebSocketChannelsHandlerNc                 C   s   t | |S N)r   check_origin)selforigin r   T/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/notebook/gateway/handlers.pyr   $   s   z%WebSocketChannelsHandler.check_originc                 C   s   dS )zVUndo the set_default_headers in IPythonHandler which doesn't make sense for websocketsNr   r   r   r   r   set_default_headers'      z,WebSocketChannelsHandler.set_default_headersc                 C   s   i S r   r   r   r   r   r   get_compression_options+   r!   z0WebSocketChannelsHandler.get_compression_optionsc                 C   sT   |   du r| jd td| ddr"t| 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_idFzNo session ID specified)get_current_userlogwarningr   	HTTPErrorget_argumentr   sessionr   r   r   r   authenticate/   s   
z%WebSocketChannelsHandler.authenticatec                 C   s6   | j d| jj t| jd| _tt	 j
d| _d S )Nz$Initializing websocket connection %s)config)gateway_url)r%   debugrequestpathr   r+   r)   GatewayWebSocketClientr   instanceurlgatewayr   r   r   r   
initialize?   s   z#WebSocketChannelsHandler.initializec                 /   s2    |    t|d| _t j|d|i|V  d S )Nascii	kernel_id)r*   r   r6   supergetr   r6   argskwargs	__class__r   r   r8   D   s   zWebSocketChannelsHandler.getc                 C   s0   | j d u r| jd ur| j  d S | d d S )N    )ws_connectionping_callbackstoppingr   r   r   r   	send_pingJ   s   
z"WebSocketChannelsHandler.send_pingc                 O   s8   t | jtd | _| j  | jj|| j|  d dS )z`Handle web socket connection open to notebook server and delegate to gateway web socket handler i  )r6   message_callbackcompression_optionsN)	r
   rC   r   r@   startr3   on_openwrite_messager"   r9   r   r   r   openQ   s   

zWebSocketChannelsHandler.openc                 C   s   | j | dS )z.Forward message to gateway web socket handler.N)r3   
on_message)r   messager   r   r   rJ   \   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bytesr7   rH   r%   isEnabledForloggingDEBUGr   _get_message_summaryr   r   r-   )r   rK   rL   msg_summaryr<   r   r   rH   `   s   
z&WebSocketChannelsHandler.write_messagec                    s*   | j d| jj | j  t   d S )NzClosing websocket connection %s)r%   r-   r.   r/   r3   on_closer7   r   r<   r   r   rT   j   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
| d d   n| d d|S )Nmsg_typeztype: statusz	, state: contentexecution_stateerrorz, ename:evalue	tracebackz, ... )appendjoin)rK   summarymessage_typer   r   r   rR   o   s   



z-WebSocketChannelsHandler._get_message_summaryr   )F)__name__
__module____qualname__r)   r3   r6   r@   r   r    r"   r*   r4   r   	coroutiner8   rC   rI   rJ   rH   rT   staticmethodrR   __classcell__r   r   r<   r   r      s&    

r   c                       sl   e Zd ZdZ fddZejdd Zdd Zdd	 Z	ejd
d Z
dd Zdd Zdd Zdd Z  ZS )r0   z;Proxy web socket connection to a kernel/enterprise gateway.c                    s6   t  jdi | d | _d | _t | _d| _d| _d S )NFr   r   )r7   __init__r6   wsr   	ws_futuredisconnectedretry)r   r;   r<   r   r   ri      s   
zGatewayWebSocketClient.__init__c                 C   s   d | _ || _tt jt jt|d}| j	d|  i }t j
di |}t|fi |}t|| _| j| j d S )NchannelszConnecting to r   )rj   r6   r   r   r1   ws_urlkernels_endpointr   r%   infoload_connection_argsr   r   rk   add_done_callback_connection_done)r   r6   ro   r;   r.   r   r   r   _connect   s   
zGatewayWebSocketClient._connectc                 C   sZ   | j s| d u r| | _d| _| jd| j  d S | jd| j	t
 j d S )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: {})rl   	exceptionresultrj   rm   r%   r-   r&   formatr6   r   r1   r2   )r   futr   r   r   rt      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 )NTz-_disconnect: future cancelled, disconnected: )rl   rj   closerk   donecancelr%   r-   r   r   r   r   _disconnect   s   


z"GatewayWebSocketClient._disconnectc              
   #   sR   j durLd}jsFzj  V }W n ty. } zjd|  W Y d}~nd}~ww |du rAjs@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|V  j t }|j fd
d 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): %sc                    
     S r   _read_messagesfuturecallbackr   r   r   <lambda>      
 z7GatewayWebSocketClient._read_messages.<locals>.<lambda>)rj   rl   read_message	Exceptionr%   rY   r&   r6   rm   r   r1   gateway_retry_maxrandomrandintmingateway_retry_intervalgateway_retry_interval_maxrq   r   sleepru   r	   current
add_futurerk   )r   r   rK   ejitterretry_intervalloopr   r   r   r      sB   


z%GatewayWebSocketClient._read_messagesc                    s.    | t }|j fdd dS )z2Web socket connection open against gateway server.c                    r   r   r   r   rD   r   r   r   r      r   z0GatewayWebSocketClient.on_open.<locals>.<lambda>N)ru   r	   r   r   rk   )r   r6   rD   r;   r   r   r   r   rG      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                    r   r   )_write_messager   rK   r   r   r   r      r   z3GatewayWebSocketClient.on_message.<locals>.<lambda>)rj   r	   r   r   rk   r   )r   rK   r   r   r   r   rJ      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: )rl   rj   rH   r   r%   rY   )r   rK   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   rT      s   zGatewayWebSocketClient.on_close)rc   rd   re   __doc__ri   r   rf   ru   rt   r}   r   rG   rJ   r   rT   rh   r   r   r<   r   r0      s    



	r0   c                   @   s&   e Zd ZdZejejdddZdS )GatewayResourceHandlerzWRetrieves resources for specific kernelspec definitions from kernel/enterprise gateway.Tc                 c   s^    | j }|||V }|d u r| jd| d| d n| dt|d  | | d S )NzKernelspec resource 'z' for 'z7' not found.  Gateway may not support resource serving.zContent-Typer   )kernel_spec_managerget_kernel_spec_resourcer%   r&   
set_header	mimetypes
guess_typefinish)r   kernel_namer/   include_bodyksmkernel_spec_resr   r   r   r8      s   zGatewayResourceHandler.getN)T)	rc   rd   re   r   r   authenticatedr   rf   r8   r   r   r   r   r      s
    r   )_kernel_id_regex)kernel_name_regexz/api/kernels/z	/channelsz/kernelspecs/z/(?P<path>.*))-osrP   r   r   base.handlersr   r   utilsr   tornador   r   tornado.concurrentr   tornado.ioloopr	   r
   tornado.websocketr   r   tornado.httpclientr   tornado.escaper   r   r   ipython_genutils.py3compatr   jupyter_client.sessionr   traitlets.config.configurabler   managersr   intgetenvr   r   r0   r   services.kernels.handlersr   services.kernelspecs.handlersr   default_handlersr   r   r   r   <module>   s2   fp