jupyter-0.9.0: A library for creating and using Jupyter kernels.

Copyright(c) Andrew Gibiansky, 2016
LicenseMIT
Maintainerandrew.gibiansky@gmail.com
Stabilitystable
PortabilityPOSIX
Safe HaskellNone
LanguageHaskell2010

Jupyter.Kernel

Contents

Description

The Kernel module provides an API for quickly and easily creating Jupyter kernels.

Jupyter kernels are programs which communicate using the Jupyter messaging spec; most kernels are language backends that allow using a particular programming language with Jupyter frontends such as the notebook or QtConsole.

To run a kernel, call the serve function, which provides a type-safe implementation of the Jupyter messaging spec.

More information about the client and kernel interfaces can be found on the jupyter README, and several example kernels may be found in the examples directory.

Synopsis

Serving kernels

serve Source

Arguments

:: KernelProfile

The kernel profile specifies how to listen for client messages (ports, transport mechanism, message signing, etc).

-> CommHandler

The Comm handler is called when Comm messages are received from a frontend.

-> ClientRequestHandler

The request handler is called when ClientRequest messages are received from a frontend.

-> IO () 

Indefinitely serve a kernel on the provided ports. If the ports are not open, fails with an exception.

This starts several threads which listen and write to ZeroMQ sockets on the ports indicated in the KernelProfile. If an exception is raised and any of the threads die, the exception is re-raised on the main thread.

Using this function generally requires a bit of setup. The most common pattern for use is as follows:

  1. In your kernel Main.hs, parse command line arguments. Some combination of arguments should include a path to a connection file; this file can be read and parsed into a KernelProfile with readProfile. (Often, the same executable will have a different mode that installs the kernel using installKernelspec).
  2. Set up any state your kernel may need, storing it in an MVar or IORef.
  3. Define your CommHandler and ClientRequestHandler handlers, which read from the state and reply with any necessary messages. (These handlers may be called concurrently from different threads!)
  4. Provide the kernel profile and handlers to the serve function, which blocks indefinitely.

Example kernels may be found in the examples directory.

serveDynamic Source

Arguments

:: (KernelProfile -> IO ())

This function is called with the dynamically-generated kernel profile that the kernel will serve on, so that clients may be notified of which ports to use to connect to this kernel. The callback is called after sockets are bound but before the kernel begins listening for messages, so if the callback fails with an exception the kernel threads are never started.

-> CommHandler

The Comm handler is called when Comm messages are received from a frontend.

-> ClientRequestHandler

The request handler is called when ClientRequest messages are received from a frontend.

-> IO () 

Indefinitely serve a kernel on some ports. Ports are allocated dynamically and so, unlike serve, serveDynamic may be used when you do not know which ports are open or closed.

The ports allocated by serveDynamic are passed to the provided callback in the KernelProfile so that clients may connect to the served kernel.

After the callback is run, several threads are started which listen and write to ZeroMQ sockets on the allocated ports. If an exception is raised and any of the threads die, the exception is re-raised on the main thread. Otherwise, this listens on the kernels indefinitely after running the callback.

This function serves as a form of inverting control over the allocated ports: usually, clients will choose what ports to listen on, and provide the kernel with the ports with a connection file path in the kernel command-line arguments. With this function, you can instead first start the kernel, and then connect a client to the ports that the kernel chooses to bind to.

data KernelCallbacks Source

The KernelCallbacks data type contains callbacks that the kernel may use to communicate with the client. Specifically, it can send KernelOutput and Comm messages using sendKernelOutput and sendComm, respectively, which are often sent to frontends in response to ExecuteRequest messsages.

In addition, sentKernelRequest can be used to send a KernelRequest to the client, and synchronously wait and receive a ClientReply.

Constructors

KernelCallbacks 

Fields

sendKernelOutput :: KernelOutput -> IO ()

Publish an output to all connected frontends. This is the primary mechanism by which a kernel shows output to the user.

sendComm :: Comm -> IO ()

Publish a Comm message to the frontends. This allows for entirely freeform back-and-forth communication between frontends and kernels, avoiding the structure of the Jupyter messaging protocol. This can be used for implementing custom features such as support for the Jupyter notebook widgets.

sendKernelRequest :: KernelRequest -> IO ClientReply

Send a KernelRequest to the client that send the first message and wait for it to reply with a ClientReply.

Defining a kernel

simpleKernelInfo Source

Arguments

:: Text

Kernel name, used for kernelImplementation and languageName.

-> KernelInfo 

Create the simplest possible KernelInfo.

Defaults version numbers to "0.0", mimetype to "text/plain", empty banner, and a ".txt" file extension.

Mostly intended for use in tutorials and demonstrations; if publishing production kernels, make sure to use the full KernelInfo constructor.

>>> let kernelInfo = simpleKernelInfo "python3"

type ClientRequestHandler = KernelCallbacks -> ClientRequest -> IO KernelReply Source

When calling serve, the caller must provide a ClientRequestHandler.

The handler is used when the kernel receives a ClientRequest message from a frontend; the ClientRequest message is passed to the handler, along with a set of callbacks the handler may use to send messages to the client.

The handler must return a KernelReply to be sent in response to this request. ClientRequest and KernelReply constructors come in pairs, and the output reply constructor must match the input request constructor.

Note: When the request is a ExecuteRequest with the executeSilent option set to True, the KernelReply will not be sent.

defaultClientRequestHandler Source

Arguments

:: KernelProfile

The profile this kernel is running on. Used to respond to ConnectRequests.

-> KernelInfo

Information about this kernel. Used to respond to KernelInfoRequests.

-> ClientRequestHandler 

Handler which responds to all ClientRequest messages with a default, empty reply.

type CommHandler = KernelCallbacks -> Comm -> IO () Source

When calling serve, the caller must provide a CommHandler.

The handler is used when the kernel receives a Comm message from a frontend; the Comm message is passed to the handler, along with a set of callbacks the handler may use to send messages to the client.

Since Comms are used for free-form communication outside the messaging spec, kernels should ignore Comm messages they do not expect.

The defaultCommHandler handler is provided for use with kernels that wish to ignore all Comm messages.

defaultCommHandler :: CommHandler Source

Handler which ignores all Comm messages sent to the kernel (and does nothing).

Reading Kernel Profiles

data KernelProfile Source

A kernel profile, specifying how the kernel communicates.

The kernel profile is usually obtained by a kernel by parsing the connection file passed to it as an argument as indicated by the kernelspec.

The profileTransport, profileIp and five profile Port fields specify the ports which the kernel should bind to. These ports are usually generated fresh for every client or server started.

profileSignatureKey is used to cryptographically sign messages, so that other users on the system can’t send code to run in this kernel. See the wire protocol documentation for the details of how this signature is calculated.

More info on the fields of the connection file and the KernelProfile is available in the respective Jupyter documentation.

Constructors

KernelProfile 

Fields

profileIp :: IP

The IP on which to listen.

profileTransport :: Transport

The transport mechanism.

profileStdinPort :: Port

The stdin channel port.

profileControlPort :: Port

The control channel port.

profileHeartbeatPort :: Port

The heartbeat channel port.

profileShellPort :: Port

The shell command port.

profileIopubPort :: Port

The IOPub port.

profileSignatureKey :: ByteString

The HMAC encryption key.

Instances

Eq KernelProfile Source 
Ord KernelProfile Source 
Read KernelProfile Source 
Show KernelProfile Source 
ToJSON KernelProfile Source

Instance to decode a KernelProfile from connection file contents.

FromJSON KernelProfile Source

Decode a KernelProfile from a JSON object.

This object is passed to kernels in the connection file.

readProfile :: FilePath -> IO (Maybe KernelProfile) Source

Read a KernelProfile from a file. This file (the connection file) should contain a JSON-encoded object with all necessary fields, as described in the connection files section of the Jupyter documentation.

If the file contents cannot be parsed, Nothing is returned.