ó
ù2¢\c           @   st  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 m Z d
 d l m Z d
 d l m Z m Z d d l m Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d Z d Z  d e f d e e f d e e  f e f d e e f g Z! d S(   s®   Tornado handlers for kernels.

Preliminary documentation at https://github.com/ipython/ipython/wiki/IPEP-16%3A-Notebook-multi-directory-dashboard-and-URL-mapping#kernels-api
iÿÿÿÿN(   t   dedent(   t   gent   web(   t   Future(   t   IOLoop(   t   date_default(   t   cast_unicode(   t   url_path_joint
   url_escapei   (   t
   APIHandler(   t   AuthenticatedZMQStreamHandlert   deserialize_binary_message(   t   protocol_versiont   MainKernelHandlerc           B   s>   e  Z e j e j d  „  ƒ ƒ Z e j e j d „  ƒ ƒ Z RS(   c         c   s?   |  j  } t j | j ƒ  ƒ V} |  j t j | d t ƒƒ d  S(   Nt   default(   t   kernel_managerR   t   maybe_futuret   list_kernelst   finisht   jsont   dumpsR   (   t   selft   kmt   kernels(    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyt   get   s    	c         c   sÑ   |  j  } |  j ƒ  } | d  k r4 i | j d 6} n | j d | j ƒ t j | j d | d ƒ ƒ V} | j | ƒ } t	 |  j
 d d t | ƒ ƒ } |  j d | ƒ |  j d ƒ |  j t j | d t ƒƒ d  S(   Nt   namet   kernel_namet   apiR   t   LocationiÉ   R   (   R   t   get_json_bodyt   Nonet   default_kernel_namet
   setdefaultR   R   t   start_kernelt   kernel_modelR   t   base_urlR   t
   set_headert
   set_statusR   R   R   R   (   R   R   t   modelt	   kernel_idt   location(    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyt   post#   s    	 (   t   __name__t
   __module__R   t   authenticatedR   t	   coroutineR   R)   (    (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyR      s   t   KernelHandlerc           B   s5   e  Z e j d  „  ƒ Z e j e j d „  ƒ ƒ Z RS(   c         C   sE   |  j  } | j | ƒ | j | ƒ } |  j t j | d t ƒƒ d  S(   NR   (   R   t   _check_kernel_idR"   R   R   R   R   (   R   R'   R   R&   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyR   9   s    	c         c   s;   |  j  } t j | j | ƒ ƒ V|  j d ƒ |  j ƒ  d  S(   NiÌ   (   R   R   R   t   shutdown_kernelR%   R   (   R   R'   R   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyt   delete@   s    	(   R*   R+   R   R,   R   R   R-   R1   (    (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyR.   7   s   t   KernelActionHandlerc           B   s#   e  Z e j e j d  „  ƒ ƒ Z RS(   c         c   sÎ   |  j  } | d k r2 | j | ƒ |  j d ƒ n  | d k rÀ y t j | j | ƒ ƒ VWn6 t k
 r‘ } |  j j d d t	 ƒ|  j d ƒ qÀ X| j
 | ƒ } |  j t j | d t ƒƒ n  |  j ƒ  d  S(   Nt	   interruptiÌ   t   restarts   Exception restarting kernelt   exc_infoiô  R   (   R   t   interrupt_kernelR%   R   R   t   restart_kernelt	   Exceptiont   logt   errort   TrueR"   t   writeR   R   R   R   (   R   R'   t   actionR   t   eR&   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyR)   K   s    	(   R*   R+   R   R,   R   R-   R)   (    (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyR2   I   s   t   ZMQChannelsHandlerc           B   s  e  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 e j d „  ƒ Z e j d „  ƒ Z e j d „  ƒ Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   s]   There is one ZMQChannelsHandler per running kernel and it oversees all
    the sessions.
    c         C   s   |  j  j } |  j j d | ƒ S(   Nt   kernel_info_timeout(   R   R@   t   settingsR   (   R   t
   km_default(    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyR@   i   s    c         C   s   |  j  j d d ƒ S(   Nt   iopub_msg_rate_limiti    (   RA   R   (   R   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyRC   n   s    c         C   s   |  j  j d d ƒ S(   Nt   iopub_data_rate_limiti    (   RA   R   (   R   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyRD   r   s    c         C   s   |  j  j d d ƒ S(   Nt   rate_limit_windowg      ð?(   RA   R   (   R   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyRE   v   s    c         C   s    d |  j  j t |  d d ƒ f S(   Ns   %s(%s)R'   t   uninitialized(   t	   __class__R*   t   getattr(   R   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyt   __repr__z   s    c         C   sf   |  j  } |  j j } xJ d D]B } t | d | ƒ } | |  j d | ƒ|  j | <} | | _ q Wd  S(   Nt   shellt   iopubt   stdint   connect_t   identity(   RJ   RK   RL   (   R   t   sessiont   bsessionRH   R'   t   channelst   channel(   R   R   RN   RR   t   metht   stream(    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyt   create_stream}   s    	 c            sê   ˆ  j  } | j ˆ  j ƒ } y | j } Wnƒ t k
 r­ ˆ  j j d ˆ  j ƒ ˆ  j d k ru | j	 ˆ  j ƒ ˆ  _ n  ˆ  j j
 ˆ  j ƒ ˆ  j j ˆ  j d ƒ ˆ  j | _ n6 X| j ƒ  sÍ ˆ  j j d ƒ n  | j ‡  f d †  ƒ ˆ  j S(   s   send a request for kernel_infos   Requesting kernel info from %st   kernel_info_requests'   Waiting for pending kernel_info requestc            s   ˆ  j  |  j ƒ  ƒ S(   N(   t   _finish_kernel_infot   result(   t   f(   R   (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyt   <lambda>™   t    N(   R   t
   get_kernelR'   t   _kernel_info_futuret   AttributeErrorR9   t   debugt   kernel_info_channelR   t   connect_shellt   on_recvt   _handle_kernel_info_replyRO   t   sendt   donet   add_done_callback(   R   R   t   kernelt   future(    (   R   sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyt   request_kernel_info…   s    	c         C   sç   |  j  j | ƒ \ } } y |  j  j | ƒ } Wn. |  j j d d t ƒ|  j j i  ƒ d SX| d } |  j j d | ƒ | d d k s˜ d | k r´ |  j j d	 | ƒ i  } n  |  j	 | ƒ |  j
 rÚ |  j
 j ƒ  n  d |  _
 d S(
   sb   process the kernel_info_reply
        
        enabling msg spec adaptation, if necessary
        s   Bad kernel_info replyR5   Nt   contents   Received kernel info: %st   msg_typet   kernel_info_replyR   s/   Kernel info request failed, assuming current %s(   RO   t   feed_identitiest   deserializeR9   R:   R;   R]   t
   set_resultR_   RW   R`   t   closeR   (   R   t   msgt   identst   info(    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyRc   œ   s     
		c         C   s   | j  d t ƒ } | t k rY t | j d ƒ d ƒ |  j _ |  j j d | |  j ƒ n  |  j	 j
 ƒ  s{ |  j	 j | ƒ n  d S(   s“   Finish handling kernel_info reply
        
        Set up protocol adaptation, if needed,
        and signal that connection can continue.
        R   t   .i    s&   Adapting to protocol v%s for kernel %sN(   R   t   client_protocol_versiont   intt   splitRO   t   adapt_versionR9   Rs   R'   R]   Re   Ro   (   R   Rs   R   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyRW   µ   s    c         C   s‰   t  t |  ƒ j ƒ  d  |  _ i  |  _ d  |  _ d  |  _ t ƒ  |  _	 t ƒ  |  _
 d |  _ d |  _ d |  _ t |  _ t |  _ g  |  _ d  S(   NR[   i    (   t   superR?   t
   initializeR   t
   zmq_streamRQ   R'   R`   R   R]   t   _close_futuret   session_keyt   _iopub_window_msg_countt   _iopub_window_byte_countt   Falset   _iopub_msgs_exceededt   _iopub_data_exceededt   _iopub_window_byte_queue(   R   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyRz   Â   s    									c         #   s•   t  t ˆ ƒ j ƒ  ˆ j ƒ  Vˆ j j ˆ j ƒ } | j j ˆ j _ ˆ j	 ƒ  ‰  ‡  ‡ f d †  } t
 j ƒ  } | j | j ƒ  ˆ j | ƒ ˆ  Vd  S(   Nc              s7   ˆ  j  ƒ  r d Sˆ j j d ˆ j ƒ ˆ  j i  ƒ d S(   s*   Don't wait forever for the kernel to replyNs-   Timeout waiting for kernel_info reply from %s(   Re   R9   t   warningR'   Ro   (    (   Rh   R   (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyt   give_upã   s    (   Ry   R?   t   pre_gett   _register_sessionR   R\   R'   RO   t   keyRi   R   t   currentt   add_timeoutt   timeR@   (   R   Rg   R…   t   loop(    (   Rh   R   sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyR†   Ö   s    c         c   s0   t  | d ƒ |  _ t t |  ƒ j d | ƒ Vd  S(   Nt   asciiR'   (   R   R'   Ry   R?   R   (   R   R'   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyR   î   s    c         c   so   d |  j  |  j j f |  _ |  j j |  j ƒ } | r[ |  j j d |  j ƒ | j ƒ  Vn  |  |  j |  j <d S(   s+  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.
        s   %s:%ss   Replacing stale connection: %sN(   R'   RO   R}   t   _open_sessionsR   R9   R„   Rp   (   R   t   stale_handler(    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyR‡   ó   s    c   	      C   s¾  t  t |  ƒ j ƒ  |  j } | j | ƒ | j | |  j ƒ } | rÝ | d |  j k rÝ |  j j d |  j ƒ | d |  _	 | d } | r[|  j j d t
 | ƒ ƒ x4 | D]) \ } } |  j	 | } |  j | | ƒ qª Wq[n~ y |  j ƒ  Wnm t j k
 rZ} |  j j d | ƒ x6 |  j	 j ƒ  D]% \ } } | j ƒ  s#| j ƒ  q#q#W|  j ƒ  d  SX| j |  j |  j ƒ | j |  j |  j d ƒ x- |  j	 j ƒ  D] \ } } | j |  j ƒ qšWd  S(   NR}   s   Restoring connection for %sRQ   t   buffers   Replaying %s buffered messagess   Error opening stream: %st   dead(   Ry   R?   t   openR   t   notify_connectt
   get_bufferR}   R9   Rs   RQ   t   lent   _on_zmq_replyRU   R   t	   HTTPErrorR:   t   itemst   closedRp   t   add_restart_callbackR'   t   on_kernel_restartedt   on_restart_failedt   on_recv_stream(	   R   R'   R   t   buffer_infot   replay_bufferRR   t   msg_listRT   R>   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyR’     s4    	

c         C   sÑ   |  j  s  |  j j d | ƒ d  St | t ƒ r> t | ƒ } n t j | ƒ } | j d d  ƒ } | d  k r‡ |  j j
 d | ƒ d } n  | |  j  k r­ |  j j
 d | ƒ d  S|  j  | } |  j j | | ƒ d  S(   Ns'   Received message on closed websocket %rRR   s(   No channel specified, assuming shell: %sRJ   s   No such channel: %r(   RQ   R9   R_   t
   isinstancet   bytesR   R   t   loadst   popR   R„   RO   Rd   (   R   Rq   RR   RT   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyt
   on_message%  s    		c            s   ˆ 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 ˆ _ t	 ˆ _
 t	 ˆ _ n  | d k rƒ| d d d h k rƒt j ƒ  j ƒ  }	 xf t ˆ j ƒ d k rbˆ j d }
 |	 |
 d k r^ˆ j |
 d 8_ ˆ j d 8_ ˆ j d =qý Pqý Wˆ j d 7_ | d k r¦t g  | D] } t | ƒ ^ qˆƒ } n d } ˆ j | 7_ ˆ j j |	 ˆ j | f ƒ t ˆ j ƒ ˆ j } t ˆ j ƒ ˆ j } ˆ j d k r\| ˆ j k r\ˆ j
 s t ˆ _
 | t d j ˆ j ˆ j ƒ ƒ ƒ q nD ˆ j
 r | d ˆ j k  r t	 ˆ _
 ˆ j s ˆ j j d ƒ q n  ˆ j d k rø| ˆ j k røˆ j s<t ˆ _ | t d j ˆ j ˆ j ƒ ƒ ƒ q<nD ˆ j r<| d ˆ j k  r<t	 ˆ _ ˆ j
 s<ˆ j j d ƒ q<n  ˆ j
 sNˆ j rƒˆ j d 8_ ˆ j | 8_ ˆ j j d ƒ d  Sn  t t ˆ ƒ j | | ƒ d  S(   Nt   parent_headerc            sj   ˆ j  j |  ƒ ˆ j j d d i |  d d 6d d 6d ˆ  ƒ} d | d	 <ˆ j t j | d
 t ƒƒ d  S(   NRT   Rj   s   
t   textt   stderrR   t   parentRK   RR   R   (   R9   R„   RO   Rq   t   write_messageR   R   R   (   t   error_messageRq   (   R©   R   (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyt   write_stderr<  s    	
RR   t   headerRk   RK   t   statusRj   t   execution_statet   idlei    t	   comm_opent   execute_inputi   RT   s                      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={} (msgs/sec)
                    NotebookApp.rate_limit_window={} (secs)
                    gš™™™™™é?s   iopub messages resumeds                      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={} (bytes/sec)
                    NotebookApp.rate_limit_window={} (secs)
                    iÿÿÿÿ(   RO   Rm   Rn   RH   R   R   Rƒ   R~   R   R€   R   R‚   R   R‰   R‹   R•   t   sumt   appendRE   t   floatRC   R;   R    t   formatR9   R„   RD   R¤   Ry   R?   R–   (   R   RT   R    Rr   t   fed_msg_listRq   R¬   RR   Rk   t   nowt   queuedt   xt
   byte_countt   msg_ratet	   data_rate(    (   R©   R   sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyR–   8  sj    
1				!(		
"				
"		c         C   s   t  t |  ƒ j ƒ  |  j S(   N(   Ry   R?   Rp   R|   (   R   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyRp   ¥  s    c         C   sW  |  j  j d |  j ƒ |  j j |  j ƒ |  k rG |  j j |  j ƒ n  |  j } |  j | k rç | j |  j ƒ | j	 |  j |  j
 ƒ | j	 |  j |  j d ƒ | j |  j d k rç | j |  j |  j |  j ƒ |  j j d  ƒ d  Sn  xP |  j j ƒ  D]? \ } } | d  k	 r÷ | j ƒ  r÷ | j d  ƒ | j ƒ  q÷ q÷ Wi  |  _ |  j j d  ƒ d  S(   Ns   Websocket closed %sR‘   i    (   R9   R_   R}   RŽ   R   R¤   R   R'   t   notify_disconnectt   remove_restart_callbackR›   Rœ   t   _kernel_connectionst   start_bufferingRQ   R|   Ro   R   R˜   R™   Rb   Rp   (   R   R   RR   RT   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyt   on_close©  s(    		c         C   s{   |  j  j d d  ƒ } | r5 | j ƒ  r5 | j ƒ  n  |  j j d i | d 6ƒ } d | d <|  j t j	 | d t
 ƒƒ d  S(   NRK   R®   R¯   RR   R   (   RQ   R   R   R™   t   flushRO   Rq   Rª   R   R   R   (   R   R®   RK   Rq   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyt   _send_status_messageÊ  s    
c         C   s$   t  j d |  j ƒ |  j d ƒ d  S(   Ns   kernel %s restartedt
   restarting(   t   loggingt   warnR'   RÄ   (   R   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyR›   ×  s    c         C   s$   t  j d |  j ƒ |  j d ƒ d  S(   Ns   kernel %s restarted failed!R‘   (   RÆ   R:   R'   RÄ   (   R   (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyRœ   Û  s    (   R*   R+   t   __doc__RŽ   t   propertyR@   RC   RD   RE   RI   RU   Ri   Rc   RW   Rz   R   R-   R†   R   R‡   R’   R¥   R–   Rp   RÂ   RÄ   R›   Rœ   (    (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyR?   _   s.   							#		m		!		s"   (?P<kernel_id>\w+-\w+-\w+-\w+-\w+)s   (?P<action>restart|interrupt)s   /api/kernelss   /api/kernels/%ss   /api/kernels/%s/%ss   /api/kernels/%s/channels("   RÈ   R   RÆ   t   textwrapR    t   tornadoR   R   t   tornado.concurrentR   t   tornado.ioloopR   t   jupyter_client.jsonutilR   t   ipython_genutils.py3compatR   t   notebook.utilsR   R   t   base.handlersR	   t   base.zmqhandlersR
   R   t   jupyter_clientR   Ru   R   R.   R2   R?   t   _kernel_id_regext   _kernel_action_regext   default_handlers(    (    (    sA   lib/python2.7/site-packages/notebook/services/kernels/handlers.pyt   <module>   s.   ÿ ‡	