
    Ib_g                     Z   d Z ddlZddlZddlmZ ddlmZmZ ddlm	Z	 ddl
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  G d de      Z G d de      Z G d de      Z  G d de      Z!dZ"dZ#defde" efde" de# e fde" de!fgZ$y# e$ r	 dd	lmZ Y ww xY w)zTornado handlers for kernels.

Preliminary documentation at https://github.com/ipython/ipython/wiki/IPEP-16%3A-Notebook-multi-directory-dashboard-and-URL-mapping#kernels-api
    N)dedent)genweb)Future)IOLoop)protocol_version)json_default)date_default)cast_unicode)maybe_futureurl_path_join
url_escape   )
APIHandler)AuthenticatedZMQStreamHandlerdeserialize_binary_messagec                       e Zd Zej                  ej                  d               Zej                  ej                  d               Zy)MainKernelHandlerc              #      K   | j                   }t        |j                               }| j                  t	        j
                  |t                     y wNdefault)kernel_managerr   list_kernelsfinishjsondumpsr	   )selfkmkernelss      D/usr/lib/python3/dist-packages/notebook/services/kernels/handlers.pygetzMainKernelHandler.get    s>        $R__%677DJJw=>s   AAc              #     K   | j                   }| j                         }|d|j                  i}n|j                  d|j                         t	        |j                  |d               }t	        |j                  |            }t        | j                  ddt        |            }| j                  d|       | j                  d       | j                  t        j                  |t                     y w)Nname)kernel_nameapir    Location   r   )r   get_json_bodydefault_kernel_name
setdefaultr   start_kernelkernel_modelr   base_urlr   
set_header
set_statusr   r   r   r	   )r   r   model	kernel_idlocations        r!   postzMainKernelHandler.post'   s        ""$=..E VR%;%;<&r5='QRR	"2??9#=>> y*YBWX
H-DJJul;<s   C5C7N)	__name__
__module____qualname__r   authenticatedr   	coroutiner"   r4        r!   r   r      sL    ]]?  ?
 	]]=  =r;   r   c                       e Zd Zej                  ej                  d               Zej                  ej                  d               Zy)KernelHandlerc              #      K   | j                   }t        |j                  |            }| j                  t	        j
                  |t                     y wr   )r   r   r-   r   r   r   r	   )r   r2   r   r1   s       r!   r"   zKernelHandler.get=   s@        "2??9#=>>DJJul;<s   AAc              #      K   | j                   }t        |j                  |             | j                  d       | j	                          y w)N   )r   r   shutdown_kernelr0   r   )r   r2   r   s      r!   deletezKernelHandler.deleteD   s>        2--i899s   AAN)	r5   r6   r7   r   r8   r   r9   r"   rB   r:   r;   r!   r=   r=   ;   sL    ]]=  =
 	]]  r;   r=   c                   N    e Zd Zej                  ej                  d               Zy)KernelActionHandlerc              #      K   | j                   }|dk(  r-t        |j                  |             | j                  d       |dk(  rc	 t        |j	                  |             t        |j                  |            }| j                  t        j                  |t                     | j                          y # t        $ r8}| j                  j                  dd       | j                  d       Y d }~Md }~ww xY ww)	N	interruptr@   restartr   zException restarting kernelTexc_infoi  )r   r   interrupt_kernelr0   restart_kernelr-   writer   r   r	   	Exceptionlogerrorr   )r   r2   actionr   r1   es         r!   r4   zKernelActionHandler.postO   s        [ r229=>>OOC YD"2#4#4Y#?@@
 +2??9+EFF

4::e\BC  %<tL$$%s1   AC>B: #AC>:	C;.C61C>6C;;C>N)r5   r6   r7   r   r8   r   r9   r4   r:   r;   r!   rD   rD   M   s&    ]]  r;   rD   c                   :    e Zd ZdZi Zed        Zed        Zed        Zed        Z	d Z
d Zd Zd	 Zd
 Zd Z fdZej$                   fd       Zej$                   fd       Zej$                  d        Z fdZd Z fdZ fdZd Zd Zd Zd Z xZS )ZMQChannelsHandlerz]There is one ZMQChannelsHandler per running kernel and it oversees all
    the sessions.
    c                 f    | j                   j                  }| j                  j                  d|      S )Nkernel_info_timeout)r   rU   settingsr"   )r   
km_defaults     r!   rU   z&ZMQChannelsHandler.kernel_info_timeoutm   s+    ((<<
}}  !6
CCr;   c                 :    | j                   j                  dd      S )Niopub_msg_rate_limitr   rV   r"   r   s    r!   rY   z'ZMQChannelsHandler.iopub_msg_rate_limitr   s    }}  !7;;r;   c                 :    | j                   j                  dd      S )Niopub_data_rate_limitr   rZ   r[   s    r!   r]   z(ZMQChannelsHandler.iopub_data_rate_limitv   s    }}  !8!<<r;   c                 :    | j                   j                  dd      S )Nrate_limit_windowg      ?rZ   r[   s    r!   r_   z$ZMQChannelsHandler.rate_limit_windowz   s    }}  !4c::r;   c                 P    | j                   j                   dt        | dd       dS )N(r2   uninitialized))	__class__r5   getattrr[   s    r!   __repr__zZMQChannelsHandler.__repr__~   s+    ..))*!GD+,W+XXYZZr;   c                     | j                   }| j                  j                  }dD ];  }t        |d|z         } || j                  |      x| j
                  |<   }||_        = y )N)iopubshellcontrolstdinconnect_)identity)r   sessionbsessionre   r2   channelschannel)r   r   rm   rq   methstreams         r!   create_streamz ZMQChannelsHandler.create_stream   sa      <<((= 	%G2zG34D.24>>H.UUDMM'"V$FN	%r;   c                 z   	
  j                   j                   j                        }t        |d      dk(  rC j                  j                  d j                         t               }|j                  d       |S |j                         |j                         	 j                  d   t               t               t        j                  g      dfd	
d	fd	}j                  |        fd} fd	} fd
}j                  |       j                  |       	j                  |       t        j                          	
 fdj#                  dd      t        j$                  j'                          j(                  z         }|j                  
       |S )a  Nudge the zmq connections with kernel_info_requests

        Returns a Future that will resolve when we have received
        a shell or control reply and at least one iopub message,
        ensuring that zmq subscriptions are established,
        sockets are fully connected, and kernel is responsive.

        Keeps retrying kernel_info_request until these are both received.
        execution_statebusyz!Nudge: not nudging busy kernel %sNrh   c                 \    fD ]$  } | j                         r| j                  d       & y)zXEnsure all futures are resolved

            which in turn triggers cleanup
            N)done
set_result)finfo_futureiopub_futures    r!   r   z(ZMQChannelsHandler.nudge.<locals>.finish   s.    
 "<0 'vvxLL&'r;   c                     j                         j                          j                         sj                          j                         sj                          yy)zCommon cleanupN)remove_timeoutstop_on_recvclosedclose)r{   control_channeliopub_channelloopnudge_handleshell_channels    r!   cleanupz)ZMQChannelsHandler.nudge.<locals>.cleanup   sR    -&&( '')##%"))+%%' ,r;   c                     j                   j                  dj                         j                         s8j                   j                  dj                         j	                  d        y y )Nz$Nudge: shell info reply received: %sz!Nudge: resolving shell future: %srN   debugr2   ry   rz   msgr|   r   s    r!   on_shell_replyz0ZMQChannelsHandler.nudge.<locals>.on_shell_reply   sP    HHNNA4>>R##%BDNNS&&t, &r;   c                     j                   j                  dj                         j                         s8j                   j                  dj                         j	                  d        y y )Nz&Nudge: control info reply received: %sz#Nudge: resolving control future: %sr   r   s    r!   on_control_replyz2ZMQChannelsHandler.nudge.<locals>.on_control_reply   sP    HHNNCT^^T##%DdnnU&&t, &r;   c                    j                   j                  dj                         j                         sHj	                          j                   j                  dj                         j                  d        y y )NzNudge: IOPub received: %sz!Nudge: resolving iopub future: %s)rN   r   r2   ry   r   rz   )r   r   r}   r   s    r!   on_iopubz*ZMQChannelsHandler.nudge.<locals>.on_iopub   s\    HHNN6G$$&**,BDNNS''- 'r;   c                    | dz  } j                   j                   j                         r.j                  j                  dj                                  y j                  j
                  vr.j                  j                  dj                                  y 	j                         r.j                  j                  dj                                  y j                         r.j                  j                  dj                                  y j                         s| dz  dk(  rj                  j                  nj                  j                  } |d|  dj                          j                  j                  	d	       j                  j                  d	       j                  d
|       y y )N   z)Nudge: cancelling on closed websocket: %sz'Nudge: cancelling on stopped kernel: %sz*Nudge: cancelling on closed zmq socket: %s
   r   zNudge: attempt z on kernel kernel_info_requestg      ?)ws_connection
is_closingrN   r   r2   r   r   ry   warningrn   send
call_later)
countrN   	both_doner   r   r   nudger   r   r   s
     r!   r   z'ZMQChannelsHandler.nudge.<locals>.nudge   sk   QJE !!)T-?-?-J-J-L?  ~~T%8%88=t~~  ##%KT^^\ %%'@$.. >>#*/"*/dhh&&txx~~oeWK7GHI!!-1FG!!/3HI#sE5A $r;   r   )r   N)r   
get_kernelr2   re   rN   r   r   rz   connect_shellconnect_controlrp   r   multiadd_done_callbackon_recvr   currentr   with_timeouttimerU   )r   kernelr{   r   r   r   r   futurer   r   r   r|   r   r}   r   r   r   r   s   `       @@@@@@@@@@r!   r   zZMQChannelsHandler.nudge   sr    $$//? 6,-7HHNN>OALLH ,,. !002g.hxII{L9:		'	( 	( 	##G,	-	-	. 	h'n- 01~~(	B (	BT q%q9 !!$))+0H0H"H)T  (r;   c                      j                   }|j                   j                        }	 |j                  }|j	                         s j
                  j                  d       |j                   fd        j                  S # t        $ r  j
                  j                  d j                          j                   |j                   j                         _	         j                  j                   j                          j                  j                   j                  d        j                  |_        Y  j                  S w xY w)zsend a request for kernel_infoz'Waiting for pending kernel_info requestc                 B    j                  | j                               S r   )_finish_kernel_inforesult)r{   r   s    r!   <lambda>z8ZMQChannelsHandler.request_kernel_info.<locals>.<lambda>!  s    t/G/G
/S r;   zRequesting kernel info from %sr   )r   r   r2   _kernel_info_futurery   rN   r   r   AttributeErrorkernel_info_channelr   r   _handle_kernel_info_replyrn   r   )r   r   r   r   s   `   r!   request_kernel_infoz&ZMQChannelsHandler.request_kernel_info  s     t~~.	U//F ;;=HI$$%ST'''  		BHHNN;T^^L ''/+-+;+;DNN+K($$,,T-K-KLLLd668MN)-)A)AF&
 '''		Bs   B B7EEc                    | j                   j                  |      \  }}	 | j                   j                  |      }|d   }| j                  j	                  d|       |d   dk7  sd|vr| j                  j                  d|       i }| j                  |       | j                  r| j                  j                          d
| _	        y
#  | j                  j                  dd	       | j                  j                  i        Y y
xY w)zZprocess the kernel_info_reply

        enabling msg spec adaptation, if necessary
        contentzReceived kernel info: %smsg_typekernel_info_replyr   z/Kernel info request failed, assuming current %szBad kernel_info replyTrH   N)rn   feed_identitiesdeserializerN   r   rO   r   r   rz   r   r   )r   r   identsinfos       r!   r   z,ZMQChannelsHandler._handle_kernel_info_reply$  s    
 \\11#6
s	+,,**3/C y>DHHNN5t<:"559KSW9WPRVW$$T* ##$$**,#' 	HHNN2TNB$$//3s   C :Dc           	      l   |j                  dt              }|t        k7  r_t        |j                  d      d         | j                  _        | j                  j                  d| d| j                   dt         d       | j                  j                         s| j                  j                  |       yy)	zFinish handling kernel_info reply

        Set up protocol adaptation, if needed,
        and signal that connection can continue.
        r   .r   zAdapting from protocol version z	 (kernel z) to z
 (client).N)r"   client_protocol_versionintsplitrn   adapt_versionrN   r   r2   r   ry   rz   )r   r   r   s      r!   r   z&ZMQChannelsHandler._finish_kernel_info=  s      88$68OP66),-=-C-CC-H-K)LDLL&HHMM;<L;MYW[WeWeVffk  mD  lE  EO  P  Q'',,.$$//5 /r;   c                     t         |           d | _        i | _        d | _        d | _        t               | _        t               | _        d| _	        d| _
        d| _        d| _        d| _        g | _        y )N r   F)super
initialize
zmq_streamrp   r2   r   r   r   _close_futuresession_key_iopub_window_msg_count_iopub_window_byte_count_iopub_msgs_exceeded_iopub_data_exceeded_iopub_window_byte_queuer   rd   s    r!   r   zZMQChannelsHandler.initializeJ  ss    #' #)8 #X ()$()%$)!$)! )+%r;   c              #      K   t                     j                           j                  j	                   j
                        }|j                  j                   j                  _         j                          fd}t        j                         }|j                  |j                          j                  z   |        y w)Nc                       j                         ryj                  j                  dj                          j	                  i        y)z*Don't wait forever for the kernel to replyNz-Timeout waiting for kernel_info reply from %s)ry   rN   r   r2   rz   )r   r   s   r!   give_upz+ZMQChannelsHandler.pre_get.<locals>.give_upk  s6    {{}HHLdnn]b!r;   )r   pre_get_register_sessionr   r   r2   rn   keyr   r   r   add_timeoutr   rU   )r   r   r   r   r   rd   s   `   @r!   r   zZMQChannelsHandler.pre_get^  s      	$$&& $$//?!>>--))+	" ~~t'?'??Is   CCc              #   T   K   t        |d      | _        t        |   |       y w)Nascii)r2   )r   r2   r   r"   )r   r2   rd   s     r!   r"   zZMQChannelsHandler.getv  s&     %i9gkIk..s   %(c              #     K   | j                    d| j                  j                   | _        | j                  j	                  | j                        }|r8| j
                  j                  d| j                         |j                          | j                   | j                  v r| | j                  | j                  <   yyw)a#  Ensure we aren't creating a duplicate session.

        If a previous identical session is still open, close it to avoid collisions.
        This is likely due to a client reconnecting from a lost network connection,
        where the socket on our side has not been cleaned up yet.
        :zReplacing stale connection: %sN)	r2   rn   r   _open_sessionsr"   rN   r   r   r   )r   stale_handlers     r!   r   z$ZMQChannelsHandler._register_session{  s      #nn-Qt||/C/C.DE++//0@0@AHH=t?O?OP%%''>>T00048D 0 01 1s   B=B?c                    	 t         
            j                  }|j                  |       |j	                  | j
                        		rj	d    j
                  k(  rX j                  j                  d j
                         	d    _         j                         }	 fd}|j                  |       n!	  j                           j                         }|j%                   j&                   j(                         |j%                   j&                   j*                  d        fd}|j                  |       |S # t        j                  $ ry} j                  j                  d|        j                  j                         D ]&  \  }}|j!                         r|j#                          (  j#                          Y d }~y d }~ww xY w)Nr   zRestoring connection for %srp   c                     d   }|rQj                   j                  dt        |             |D ]&  \  }}j                  |   }j	                  ||       ( y y )NbufferzReplaying %s buffered messages)rN   r   lenrp   _on_zmq_reply)valuereplay_bufferrq   msg_listrs   buffer_infor   s        r!   replayz'ZMQChannelsHandler.open.<locals>.replay  s_     +H 5 HHMM"BCDVW-: =)!%w!7**68<= !r;   zError opening stream: %sdeadc                     j                   j                         D ]   \  }}|j                  j                         " y r   )rp   itemson_recv_streamr   )r   rq   rs   r   s      r!   	subscribez*ZMQChannelsHandler.open.<locals>.subscribe  s7    #'==#6#6#8 :%%d&8&89:r;   )r   openr   notify_connect
get_bufferr   rN   r   rp   r   r   rt   r   	HTTPErrorrO   r   r   r   add_restart_callbackr2   on_kernel_restartedon_restart_failed)r   r2   r   	connectedr   rQ   rq   rs   r   r   rd   s   `        @r!   r   zZMQChannelsHandler.open  sq     
)$ mmIt/?/?@;}59I9IIHHMM79I9IJ'
3DM

I= ''/""$ JJL	 	0H0HI
0F0FO	: 	##I.' == 91= (,}}':':'< 'OGV!==?' 

s   8 D= =G	AG"GG	c                 P   | j                   s| j                  j                  d|       y t        |t              rt        |      }nt        j                  |      }|j                  dd       }|| j                  j                  d|       d}|| j                   vr| j                  j                  d|       y | j                  j                  }|d   d   }|r$||vr | j                  j                  d| d	       y | j                   |   }| j                  j                  ||       y )
Nz'Received message on closed websocket %rrq   z(No channel specified, assuming shell: %sri   zNo such channel: %rheaderr   zReceived message of type "z"", which is not allowed. Ignoring.)rp   rN   r   
isinstancebytesr   r   loadspopr   r   allowed_message_typesrn   r   )r   r   rq   ammtrs   s         r!   
on_messagezZMQChannelsHandler.on_message  s    }}HHNNDcJc5!,S1C**S/C'')T*?HHGMG$--'HH2G<  66]:&"B,HH9"=_`a]]7+FLLfc*r;   c           	           j                   j                  |      \  }} j                   j                  |      }|d    fd}t        |dd       }|d   d   }|dk(  r?|dk(  r:|d   j	                  d	      d
k(  r#g  _        d _        d _        d _        d _	        |dk(  r|dvr
t        j                         j                         }	t         j
                        dkD  rl j
                  d   }
|	|
d   k\  r; xj                  |
d   z  c_         xj                  dz  c_         j
                  d= nnt         j
                        dkD  rl xj                  dz  c_        |dk(  rt        d |D              }nd} xj                  |z  c_         j
                  j                  |	 j                   z   |f       t#         j                         j                   z  }t#         j                         j                   z  } j$                  dkD  rO| j$                  kD  r@ j                  sd _         |t'        d j$                   d j                    d             nL j                  r@|d j$                  z  k  r.d _         j                  s j(                  j+                  d        j,                  dkD  rO| j,                  kD  r@ j                  sd _	         |t'        d j,                   d j                    d             nL j                  r@|d j,                  z  k  r.d _	         j                  s j(                  j+                  d        j                  s j                  rF xj                  dz  c_         xj                  |z  c_         j
                  j/                  d       y t0         e  ||       y )Nparent_headerc                     j                   j                  |        j                  j                  d| dz   dd      }d|d<   j	                  t        j                  |t                     y )	Nrs   
stderr)textr$   )r   parentrh   rq   r   )rN   r   rn   r   write_messager   r   r	   )error_messager   r  r   s     r!   write_stderrz6ZMQChannelsHandler._on_zmq_reply.<locals>.write_stderr  sd    HH]+,,""8!.!5xH # C %C	Ntzz#|DEr;   rq   r   r   rh   statusr   rv   idler   F>   r  	comm_openexecute_inputr   rs   c              3   2   K   | ]  }t        |        y wr   )r   ).0xs     r!   	<genexpr>z3ZMQChannelsHandler._on_zmq_reply.<locals>.<genexpr>  s      :AQ :s   Ta                      IOPub message rate exceeded.
                    The notebook server will temporarily stop sending output
                    to the client in order to avoid crashing it.
                    To change this limit, set the config variable
                    `--NotebookApp.iopub_msg_rate_limit`.

                    Current values:
                    NotebookApp.iopub_msg_rate_limit=z> (msgs/sec)
                    NotebookApp.rate_limit_window=z (secs)
                    g?ziopub messages resumeda                      IOPub data rate exceeded.
                    The notebook server will temporarily stop sending output
                    to the client in order to avoid crashing it.
                    To change this limit, set the config variable
                    `--NotebookApp.iopub_data_rate_limit`.

                    Current values:
                    NotebookApp.iopub_data_rate_limit=z? (bytes/sec)
                    NotebookApp.rate_limit_window=)rn   r   r   re   r"   r   r   r   r   r   r   r   r   r   sumappendr_   floatrY   r   rN   r   r]   r   r   r   )r   rs   r   r   fed_msg_listr   r  rq   r   nowqueued
byte_countmsg_rate	data_rater  rd   s   `             @r!   r   z ZMQChannelsHandler._on_zmq_reply  s   #||;;HEll&&|4_%	F &)T2x=,g(h"63y>;M;MN_;`dj;j -/D)+,D(,-D)(-D%(-D%g(2Z"Z .."'')Cd334q866q96!9$11VAY>100A5055a8  d334q8 ((A-(8#  : ::

))Z7) ))00#8N8N2NPZ1[\ T99:T=S=SSHd;;<t?U?UUI ((1,D<U<U1U0004D-  -6 7;6O6O5P Q3373I3I2J K
) 
" 
 ,,S4C\C\=\1]05D-44(()AB ))A-)d>X>X2X0004D-  -7 8<7Q7Q6R S3373I3I2J K
) 
" 
 ,,cDD^D^>^1_05D-44(()AB ((D,E,E,,1,--;---11"5fc*r;   c                 8    t         |           | j                  S r   )r   r   r   r   s    r!   r   zZMQChannelsHandler.close>  s    !!!r;   c                    | j                   j                  d| j                         | j                  j	                  | j                        | u r%| j                  j                  | j                         | j                  }| j                  |v r|j                  | j                         |j                  | j                  | j                         |j                  | j                  | j                  d       |j                  | j                     dk(  rM|j                  | j                  | j                  | j                         | j                  j!                  d        y | j                  j#                         D ]:  \  }}|	|j%                         r|j'                  d        |j)                          < i | _        | j                  j!                  d        y )NzWebsocket closed %sr   r   )rN   r   r   r   r"   r   r   r2   notify_disconnectremove_restart_callbackr   r   _kernel_connectionsstart_bufferingrp   r   rz   r   r   r   r   )r   r   rq   rs   s       r!   on_closezZMQChannelsHandler.on_closeB  sm   ,d.>.>?""4#3#34<##D$4$45  >>R  0&& 8 8 && 6 6
 %%dnn5:""4>>43C3CT]]S""--d3
  $}}224 	OGV!&--/t$	
 %%d+r;   c                    | j                   j                  dd       }|r |j                         s|j                          | j                  j                  dd|i      }d|d<   | j                  t        j                  |t                     y )Nrh   r  rv   rq   r   )
rp   r"   r   flushrn   r   r  r   r   r	   )r   r  rh   r   s       r!   _send_status_messagez'ZMQChannelsHandler._send_status_messagec  sp    !!'40 KKMllx'
 !I4::c<@Ar;   c                 f    t        j                  d| j                         | j                  d       y )Nzkernel %s restarted
restarting)loggingwarnr2   r#  r[   s    r!   r   z&ZMQChannelsHandler.on_kernel_restartedp  s#    *DNN;!!,/r;   c                 f    t        j                  d| j                         | j                  d       y )Nzkernel %s restarted failed!r   )r&  rO   r2   r#  r[   s    r!   r   z$ZMQChannelsHandler.on_restart_failedt  s#    3T^^D!!&)r;   )r5   r6   r7   __doc__r   propertyrU   rY   r]   r_   rf   rt   r   r   r   r   r   r   r9   r   r"   r   r   r   r   r   r   r#  r   r   __classcell__)rd   s   @r!   rS   rS   c   s     ND D < < = = ; ;[%BH(.(26+( 	]] . 	]]/ / 	]]9 9,\+0k+Z",BB0*r;   rS   z"(?P<kernel_id>\w+-\w+-\w+-\w+-\w+)z(?P<action>restart|interrupt)z/api/kernelsz/api/kernels//z	/channels)%r)  r   r&  textwrapr   tornador   r   tornado.concurrentr   tornado.ioloopr   jupyter_clientr   r   jupyter_client.jsonutilr	   ImportErrorr
   ipython_genutils.py3compatr   notebook.utilsr   r   r   base.handlersr   base.zmqhandlersr   r   r   r=   rD   rS   _kernel_id_regex_kernel_action_regexdefault_handlersr:   r;   r!   <module>r;     s        % ! F4
 4 B B ' Y=
 =:J $* ,S*6 S*v 9 7  '(&'(-8&'q)=(>?ATU&'y13EF	 [  s   B B*)B*