2018-01-22 18:36:16 -06:00
|
|
|
;;; jupyter-connection.el --- Some form of connection to a Jupyter kernel -*- lexical-binding: t -*-
|
|
|
|
|
|
|
|
;; Copyright (C) 2018 Nathaniel Nicandro
|
|
|
|
|
|
|
|
;; Author: Nathaniel Nicandro <nathanielnicandro@gmail.com>
|
|
|
|
;; Created: 20 Jan 2018
|
|
|
|
;; Version: 0.0.1
|
|
|
|
|
|
|
|
;; This program is free software; you can redistribute it and/or
|
|
|
|
;; modify it under the terms of the GNU General Public License as
|
|
|
|
;; published by the Free Software Foundation; either version 2, or (at
|
|
|
|
;; your option) any later version.
|
|
|
|
|
|
|
|
;; This program is distributed in the hope that it will be useful, but
|
|
|
|
;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
;; General Public License for more details.
|
|
|
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
|
|
|
;; along with GNU Emacs; see the file COPYING. If not, write to the
|
|
|
|
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
;; Boston, MA 02111-1307, USA.
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
|
|
(defgroup jupyter-connection nil
|
|
|
|
"Some form of connection to a Jupyter kernel"
|
|
|
|
:group 'jupyter)
|
|
|
|
|
2018-01-04 23:03:18 -06:00
|
|
|
(require 'jupyter-base)
|
2018-01-07 14:48:11 -06:00
|
|
|
(require 'eieio-base)
|
2018-01-04 23:03:18 -06:00
|
|
|
|
2018-01-07 14:48:11 -06:00
|
|
|
(defclass jupyter-connection (eieio-instance-inheritor)
|
2018-01-04 23:03:18 -06:00
|
|
|
((session
|
|
|
|
:type jupyter-session
|
|
|
|
:initarg :session
|
|
|
|
:documentation "The `jupyter-session' object which holds the
|
|
|
|
key for authenticating messages.")
|
|
|
|
(conn-info
|
|
|
|
:type json-plist
|
|
|
|
:initarg :conn-info
|
|
|
|
:documentation "The connection plist which holds the channel
|
|
|
|
ports and other information required for connecting to a kernel.
|
|
|
|
See
|
2018-01-18 21:14:27 -06:00
|
|
|
http://jupyter-client.readthedocs.io/en/latest/kernels.html#connection-files")
|
|
|
|
(kernel-info
|
|
|
|
:type json-plist
|
|
|
|
:initarg :kernel-info
|
|
|
|
:documentation "The kernel info plist of the kernel."))
|
2018-01-22 18:33:52 -06:00
|
|
|
:abstract t
|
|
|
|
:documentation "A Jupyter connection encapsulates the necessary
|
|
|
|
information of a connection to a Jupyter kernel. The necessary
|
|
|
|
information of a connection are the following:
|
|
|
|
|
|
|
|
1. A `jupyter-session' used to authenticate messages sent and
|
|
|
|
received to a kernel.
|
|
|
|
|
|
|
|
2. The connection info plist used to initialize a connection to a
|
|
|
|
kernel.
|
|
|
|
|
|
|
|
3. The kernel info plist after opening a connection to a
|
|
|
|
kernel.")
|
2018-01-04 23:03:18 -06:00
|
|
|
|
|
|
|
(cl-defun jupyter-create-connection-info (&key
|
|
|
|
(kernel-name "python")
|
|
|
|
(transport "tcp")
|
|
|
|
(ip "127.0.0.1")
|
|
|
|
(signature-scheme "hmac-sha256")
|
|
|
|
(key (jupyter-new-uuid))
|
|
|
|
(hb-port 0)
|
|
|
|
(stdin-port 0)
|
|
|
|
(control-port 0)
|
|
|
|
(shell-port 0)
|
|
|
|
(iopub-port 0))
|
2018-01-22 18:33:52 -06:00
|
|
|
"Create a connection info plist used to connect to a kernel.
|
2018-01-04 23:03:18 -06:00
|
|
|
|
|
|
|
The plist has the standard keys found in the jupyter spec. See
|
2018-01-22 18:33:52 -06:00
|
|
|
http://jupyter-client.readthedocs.io/en/latest/kernels.html#connection-files.
|
|
|
|
A port number of 0 for a channel means to use a randomly assigned
|
|
|
|
port for that channel."
|
2018-01-04 23:03:18 -06:00
|
|
|
(unless (or (= (length key) 0)
|
|
|
|
(equal signature-scheme "hmac-sha256"))
|
2018-01-22 18:33:52 -06:00
|
|
|
(error "Only hmac-sha256 signing is currently supported"))
|
2018-01-04 23:03:18 -06:00
|
|
|
(append
|
|
|
|
(list :kernel_name kernel-name
|
|
|
|
:transport transport
|
|
|
|
:ip ip)
|
|
|
|
(when (> (length key) 0)
|
|
|
|
(list :signature_scheme signature-scheme
|
|
|
|
:key key))
|
|
|
|
(cl-loop
|
2018-01-07 14:45:20 -06:00
|
|
|
with sock = (zmq-socket (zmq-current-context) zmq-REP)
|
2018-01-04 23:03:18 -06:00
|
|
|
with addr = (concat transport "://" ip)
|
|
|
|
for (channel . port) in (list (cons :hb_port hb-port)
|
|
|
|
(cons :stdin_port stdin-port)
|
|
|
|
(cons :control_port control-port)
|
|
|
|
(cons :shell_port shell-port)
|
|
|
|
(cons :iopub_port iopub-port))
|
|
|
|
collect channel and
|
|
|
|
if (= port 0) do (setq port (zmq-bind-to-random-port sock addr))
|
|
|
|
and collect port and
|
2018-01-20 21:39:20 -06:00
|
|
|
do (zmq-unbind sock (zmq-socket-get sock zmq-LAST-ENDPOINT)) else
|
2018-01-04 23:03:18 -06:00
|
|
|
collect port
|
|
|
|
finally (zmq-close sock))))
|
|
|
|
|
|
|
|
(defun jupyter-connect-endpoint (type endpoint &optional identity)
|
|
|
|
"Create socket with type TYPE and connect it to ENDPOINT.
|
2018-01-20 21:39:20 -06:00
|
|
|
If IDENTITY is non-nil, it will be set as the ROUTING-ID of the
|
2018-01-04 23:03:18 -06:00
|
|
|
socket. The return value is the socket created."
|
2018-01-07 14:45:20 -06:00
|
|
|
(let ((sock (zmq-socket (zmq-current-context) type)))
|
2018-01-04 23:03:18 -06:00
|
|
|
(zmq-socket-set sock zmq-LINGER 1000)
|
|
|
|
(when identity
|
2018-01-20 21:39:20 -06:00
|
|
|
(zmq-socket-set sock zmq-ROUTING-ID identity))
|
2018-01-04 23:03:18 -06:00
|
|
|
(zmq-connect sock endpoint)
|
|
|
|
sock))
|
|
|
|
|
|
|
|
(defun jupyter-connect-channel (ctype endpoint &optional identity)
|
|
|
|
"Create a socket based on a Jupyter channel type.
|
|
|
|
CTYPE will be mapped to a ZMQ socket type based on the plist
|
|
|
|
`jupyter-socket-types'. ENDPOINT is the endpoint the socket will
|
|
|
|
connect to and if IDENTITY is non-nil it will be set as the
|
2018-01-20 21:39:20 -06:00
|
|
|
ROUTING-ID of the socket. The return value is the socket
|
2018-01-04 23:03:18 -06:00
|
|
|
created."
|
|
|
|
(let ((sock-type (plist-get jupyter-socket-types ctype)))
|
|
|
|
(unless sock-type
|
|
|
|
(error "Invalid channel type (%s)" ctype))
|
|
|
|
(jupyter-connect-endpoint sock-type endpoint identity)))
|
|
|
|
|
|
|
|
(provide 'jupyter-connection)
|
2018-01-22 18:36:16 -06:00
|
|
|
|
|
|
|
;;; jupyter-connection.el ends here
|