
    Ib(                     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
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 jF                  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*m+Z+ de) de%fde+ de'fgZ,y)    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                        e Zd ZdZdZdZdZddZd Zd Z	d Z
d Zej                   fd       Zd Zd	 Zd
 Zd fd	Z fdZed        Z xZS )WebSocketChannelsHandlerNc                 .    t        j                  | |      S N)r   check_origin)selforigins     ;/usr/lib/python3/dist-packages/notebook/gateway/handlers.pyr   z%WebSocketChannelsHandler.check_origin$   s    **488    c                      y)zVUndo the set_default_headers in IPythonHandler which doesn't make sense for websocketsN r   s    r    set_default_headersz,WebSocketChannelsHandler.set_default_headers'   s    r!   c                     i S r   r#   r$   s    r    get_compression_optionsz0WebSocketChannelsHandler.get_compression_options+   s    	r!   c                 2   | j                         0| j                  j                  d       t        j                  d      | j                  dd      r*t        | j                  d            | j                  _        y| j                  j                  d       y)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$   s    r    authenticatez%WebSocketChannelsHandler.authenticate/   st       "*HHIJ--$$\51#/0A0A,0O#PDLL HH67r!   c                     | j                   j                  d| j                  j                         t	        | j
                        | _        t        t        j                         j                        | _        y )Nz$Initializing websocket connection %s)config)gateway_url)r+   debugrequestpathr   r2   r/   GatewayWebSocketClientr   instanceurlgatewayr$   s    r    
initializez#WebSocketChannelsHandler.initialize?   sJ    =t||?P?PQdkk2--:P:P:R:V:VWr!   c              /   v   K   | j                          t        |d      | _        t        |   |d|i| y w)Nascii	kernel_id)r0   r   r>   superget)r   r>   argskwargs	__class__s       r    r@   zWebSocketChannelsHandler.getD   s:     %i9gk?I???s   69c                     | j                   '| j                  | j                  j                          y | j                  d       y )Nr!   )ws_connectionping_callbackstoppingr$   s    r    	send_pingz"WebSocketChannelsHandler.send_pingJ   s9    %$*<*<*H##%		#r!   c                     t        | j                  t        dz        | _        | j                  j	                          | j
                  j                  || j                  | j                                y)z`Handle web socket connection open to notebook server and delegate to gateway web socket handler i  )r>   message_callbackcompression_optionsN)	r   rI   r   rF   startr:   on_openwrite_messager'   )r   r>   rA   rB   s       r    openzWebSocketChannelsHandler.openQ   s]    -dnn>[^b>bc  "!// $ < < > 	 	
r!   c                 :    | j                   j                  |       y)z.Forward message to gateway web socket handler.N)r:   
on_message)r   messages     r    rR   z#WebSocketChannelsHandler.on_message\   s    (r!   c                 D   | j                   r$t        |t              rd}t        |   ||       y| j
                  j                  t        j                        rFt        j                  t        t        |                  }| j
                  j                  d|        yy)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)rE   
isinstancebytesr?   rO   r+   isEnabledForloggingDEBUGr   _get_message_summaryr   r   r4   )r   rS   rU   msg_summaryrC   s       r    rO   z&WebSocketChannelsHandler.write_message`   s~    '5)G!'&!9XX""7==12GGTXY`TaHbcKHHNN\]h\ijk 2r!   c                     | j                   j                  d| j                  j                         | j                  j                          t        |           y )NzClosing websocket connection %s)r+   r4   r5   r6   r:   on_closer?   )r   rC   s    r    r^   z!WebSocketChannelsHandler.on_closej   s;    8$,,:K:KLr!   c           	          g }| d   }|j                  d|        |dk(  r|j                  d| d   d           nC|dk(  r-|j                  d| d   d	    d
| d   d    d
| d   d           n|j                  d       dj                  |      S )Nmsg_typeztype: statusz	, state: contentexecution_stateerrorz, ename:evalue	tracebackz, ... )appendjoin)rS   summarymessage_types      r    r[   z-WebSocketChannelsHandler._get_message_summaryo   s    z*~./8#NNYwy'9:K'L&MNOW$NNWY'019%h/09%k235 NN7#wwwr!   r   )F)__name__
__module____qualname__r/   r:   r>   rF   r   r%   r'   r0   r;   r   	coroutiner@   rI   rP   rR   rO   r^   staticmethodr[   __classcell__rC   s   @r    r   r      sy    GGIM98 X
 	]]@ @
	
)l
    r!   r   c                        e Zd ZdZ fdZej                  d        Zd Zd Z	ej                  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                 z    t        |   di | d | _        d | _        t	               | _        d| _        d| _        y )NFr   r#   )r?   __init__r>   wsr	   	ws_futuredisconnectedretry)r   rB   rC   s     r    rw   zGatewayWebSocketClient.__init__   s9    "6"!
r!   c                    d | _         || _        t        t        j                         j
                  t        j                         j                  t        |      d      }| j                  j                  d|        i } t        j                         j                  di |}t        |fi |}t        |      | _        | j                  j                  | j                         y )NchannelszConnecting to r#   )rx   r>   r   r   r8   ws_urlkernels_endpointr   r+   infoload_connection_argsr   r   ry   add_done_callback_connection_done)r   r>   r~   rB   r5   s        r    _connectzGatewayWebSocketClient._connect   s     """$++""$55z)7Lj
 	vh/0>'')>>HHf//*73(()>)>?r!   c                 h   | j                   sU|j                         E|j                         | _        d| _        | j
                  j                  d| j                          y | j
                  j                  dj                  | j                  t        j                         j                               y )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,   formatr>   r   r8   r9   )r   futs     r    r   z'GatewayWebSocketClient._connection_done   s~      S]]_%<jjlDGDJHHNN6twwi@AHH ^#VDNNM4J4J4L4P4PQSr!   c                    d| _         | j                  | j                  j                          y | j                  j	                         sC| j                  j                          | j                  j                  d| j                           y y )NTz-_disconnect: future cancelled, disconnected: )rz   rx   closery   donecancelr+   r4   r$   s    r    _disconnectz"GatewayWebSocketClient._disconnect   se     77GGMMO$$&NN!!#HHNNJ4K\K\J]^_ 'r!   c              #   n   K    j                   yd} j                  s]	  j                   j                         }|5 j                  s( j                  j                  d j                          n |       nn j                   y j                  sh 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                  j#                  d	| j                  t        j                         j                   j                         t%        j&                  |        j)                   j                         t+        j,                         }|j/                   j0                   fd
       yyy# t        $ r)} j                  j                  d|        Y d}~d}~ww xY ww)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                 &    j                        S r   _read_messages)futurecallbackr   s    r    <lambda>z7GatewayWebSocketClient._read_messages.<locals>.<lambda>   s    4;N;Nx;X r!   )rx   rz   read_message	Exceptionr+   rd   r,   r>   r{   r   r8   gateway_retry_maxrandomrandintmingateway_retry_intervalgateway_retry_interval_maxr   r   sleepr   r
   current
add_futurery   )r   r   rS   ejitterretry_intervalloops   ``     r    r   z%GatewayWebSocketClient._read_messages   s     gg!G$$U$(GG$8$8$::G ?,,((+GGW)XY! gg!    TZZ-2H2H2J2\2\%\^^B,t3F !7!7!9!P!PTUY]YcYcTc!d!.!7!7!9!T!TVX^_NJJ!OJHHMMg($**m6L6L6N6`6`bfbpbpr))N++MM$..)>>#DOODNN,XY &]  ! UHHNN%OPQs#STTUs5   H5H  AH5
E6H5 	H2	H-'H5-H22H5c                       j                  |       t        j                         }|j                   j                   fd       y)z2Web socket connection open against gateway server.c                 &    j                        S r   r   )r   rK   r   s    r    r   z0GatewayWebSocketClient.on_open.<locals>.<lambda>   s    4../?@ r!   N)r   r
   r   r   ry   )r   r>   rK   rB   r   s   ` `  r    rN   zGatewayWebSocketClient.on_open   s1    i ~~NN@	
r!   c                       j                   5t        j                         }|j                   j                   fd       y j                         y)Send message to gateway server.Nc                 &    j                        S r   )_write_message)r   rS   r   s    r    r   z3GatewayWebSocketClient.on_message.<locals>.<lambda>   s    t227; r!   )rx   r
   r   r   ry   r   )r   rS   r   s   `` r    rR   z!GatewayWebSocketClient.on_message   s>    77?>>#DOO;
 (r!   c                     	 | j                   s)| j                  | j                  j                  |       yyy# t        $ r(}| j                  j                  d|        Y d}~yd}~ww xY w)r   Nz(Exception writing message to websocket: )rz   rx   rO   r   r+   rd   )r   rS   r   s      r    r   z%GatewayWebSocketClient._write_message   sa    	K$$)<%%g. *=$ 	KHHNNEaSIJJ	Ks   38 	A)A$$A)c                 $    | j                          y)zWeb socket closed event.N)r   r$   s    r    r^   zGatewayWebSocketClient.on_close   s    r!   )rn   ro   rp   __doc__rw   r   rq   r   r   r   r   rN   rR   r   r^   rs   rt   s   @r    r7   r7      s`    E 	]]@ @ S` 	]]Z Z<
	)Kr!   r7   c                   T    e Zd ZdZej
                  ej                  dd              Zy)GatewayResourceHandlerzWRetrieves resources for specific kernelspec definitions from kernel/enterprise gateway.c              #     K   | j                   }|j                  ||      }|#| j                  j                  d| d| d       n(| j	                  dt        j                  |      d          | j                  |       y w)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_namer6   include_bodyksmkernel_spec_ress         r    r@   zGatewayResourceHandler.get   s      && # < <[$ OO"HH'vW[M B< =
 OONI,@,@,Fq,IJO$s   B BN)T)	rn   ro   rp   r   r   authenticatedr   rq   r@   r#   r!   r    r   r      s)    a]]
%  
%r!   r   )_kernel_id_regex)kernel_name_regexz/api/kernels/z	/channelsz/kernelspecs/z/(?P<path>.*))-osrY   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   r7   r   services.kernels.handlersr   services.kernelspecs.handlersr   default_handlersr#   r!   r    <module>r      s    
    6 !  % 3 A * 8 8 3 * = # !$IBII.Mr$R S c / c Lm0 m`%Z %$ 9 = 	&'y13KL'(68NO r!   