| Copyright | (c) Andrew Gibiansky, 2016 |
|---|---|
| License | MIT |
| Maintainer | andrew.gibiansky@gmail.com |
| Stability | stable |
| Portability | POSIX |
| Safe Haskell | None |
| Language | Haskell2010 |
Jupyter.Client
Description
This module provides an easy API for writing Jupyter clients. Jupyter clients (also commonly called frontends) are programs which communicate with Jupyter kernels, possibly starting them and then sending them requests over the ZeroMQ-based messaging protocol. Examples of Jupyter clients include the Jupyter console, the QtConsole, and the http://jupyter.org/.
Communication with clients is done in the Client monad, which is a thin wrapper over IO which
maintains a small bit of required state to identify a running kernel and the sockets on which to
communicate with it. The initial state and connection information is supplied when you use runClient,
which requires connection information and the Client action to run.
The runClient function also requires a set of ClientHandlers, which are callbacks that get called
when the kernel sends any sort of message to the client (KernelRequests, KernelOutputs, and Comms).
These functions can be used quite succinctly to communicate with external clients. For example, the
following code connects to an installed Python kernel (the ipykernel package must be installed):
import Control.Monad.IO.Class (MonadIO(liftIO)) import System.Process (spawnProcess) import Jupyter.Client import Jupyter.Messages main :: IO () main =runClientNothing Nothing handlers $ profile -> do -- Theprofileprovided is a generatedKernelProfile-- that the client will connect to. Start an IPython kernel -- that listens on that profile. liftIO $ dowriteProfileprofile "profile.json"spawnProcess"python" ["-m", "ipykernel", "-f", "profile.json"] -- Find out info about the kernel by sending it a kernel info request. connection <-connectKernelreply <-sendClientRequestconnectionKernelInfoRequestliftIO $ print reply handlers :: ClientHandlers handlers = ClientHandlers { -- Do nothing on comm messagescommHandler=defaultClientCommHandler, -- Return a fake stdin string if asked for stdinkernelRequestHandler= _ req -> case req ofInputRequest{} -> return $InputReply"Fake Stdin", -- Do nothing on kernel outputskernelOutputHandler= _ _ -> return () }
A more detailed example is provided in the
examples/client-kernel-info
directory, and more information about the client and kernel interfaces can be found on the jupyter
README.
- data Client a
- runClient :: Maybe KernelProfile -> Maybe Username -> ClientHandlers -> (KernelProfile -> Client a) -> IO a
- connectKernel :: Client KernelConnection
- sendClientRequest :: KernelConnection -> ClientRequest -> Client KernelReply
- sendClientComm :: KernelConnection -> Comm -> Client ()
- data ClientHandlers = ClientHandlers {
- kernelRequestHandler :: (Comm -> IO ()) -> KernelRequest -> IO ClientReply
- commHandler :: (Comm -> IO ()) -> Comm -> IO ()
- kernelOutputHandler :: (Comm -> IO ()) -> KernelOutput -> IO ()
- defaultClientCommHandler :: (Comm -> IO ()) -> Comm -> IO ()
- data KernelConnection
- writeProfile :: KernelProfile -> FilePath -> IO ()
- data Kernelspec = Kernelspec {}
- findKernel :: Text -> IO (Maybe Kernelspec)
- findKernels :: IO [Kernelspec]
Communicating with Clients
A client action, representing a computation in which communication happens with a Jupyter client.
Use sendClientRequest and sendClientComm to construct Client values, the Monad interface to
manipulate them, and runClient to supply all needed connection info and run the action.
Arguments
| :: Maybe KernelProfile | Optionally, a |
| -> Maybe Username | Optionally, a username to use when sending messages to the client. If no username is provided, a default one is used. |
| -> ClientHandlers | A record containing handlers for messages the kernel sends to the client. |
| -> (KernelProfile -> Client a) | Provided with the |
| -> IO a |
This function sets up ZeroMQ sockets on which it can connect to a kernel; if no KernelProfile
is provided, it generates a fresh KernelProfile which contains information about the ports and
transport protocols which it expects the kernel to connect with. It guarantees that the ports it
chooses are open – that is, that no kernel is currently connected to those ports.
The generated KernelProfile is passed to the user-provided
callback, which may use functions such as KernelProfile -> Client asendClientRequest to communicate with the kernel. If
the kernel sends messages to the client, they are handled with the callbacks provided in the
ClientHandlers record.
Most clients follow a simple pattern:
- Invoke
runClient, passingNothingfor theKernelProfile. This allowsrunClientto set up and choose its own ports. - Write the connection file containing the chosen ports to a JSON file using
writeProfile. Make sure to write it to a temporary directory, to avoid clobbering user directories with connection files. - If you do not know the command used to invoke the target kernel, use
findKernelto find theKernelspecfor the kernel you wish to launch. Then, use thekernelspecCommandfield to generate the kernel command invocation. - Launch the kernel using
spawnProcessor a similar function, providing the connection file you wrote out as a command-line parameter. - Wait for the kernel to connect to the client using
connectKernel. - Use the output
KernelConnectionfromconnectClientto communicate with the kernel usingsendClientRequest(and maybesendClientComm).
A full example is provided in the examples/client-kernel-info directory.
If any of the client handlers in the provided ClientHandlers throw an exception, the client is
gracefully shutdown and the exception is reraised on the main runClient thread.
connectKernel :: Client KernelConnection Source
Wait for a kernel to connect to this client, and return a KernelConnection once the kernel
has connected.
This KernelConnection must be passed to sendClientRequest and sendClientComm to communicate
with the connected kernel.
Arguments
| :: KernelConnection | A kernel connection, produced by |
| -> ClientRequest | The request to send to the connected kernel. |
| -> Client KernelReply |
Send a ClientRequest to the kernel. Wait for the kernel to reply with a KernelReply,
blocking until it does so.
Arguments
| :: KernelConnection | A kernel connection, produced by |
| -> Comm | The |
| -> Client () |
Send a Comm message to the kernel. The kernel is not obligated to respond in any way, so do
not block, but return immediately upon sending the message.
data ClientHandlers Source
A set of callbacks for the client. These callbacks get called when the client receives any message from the kernel.
One callback exists per message type that the clients can receive. Each callbacks can also send
Comm messages to kernel, and receive a function of type that sends a single
Comm -> IO ()Comm message to the kernel.
Constructors
| ClientHandlers | |
Fields
| |
defaultClientCommHandler :: (Comm -> IO ()) -> Comm -> IO () Source
A default client Comm handlers, which, upon receiving a Comm message, does nothing.
For use with the ClientHandlers commHandler field.
data KernelConnection Source
A connection to a kernel from a client.
A connection can be obtained with connectKernel, and must be provided to
sendClientRequest and sendClientComm to communicate with a kernel.
Instances
Writing Connection Files
writeProfile :: KernelProfile -> FilePath -> IO () Source
Write a KernelProfile to a JSON file, which can be passed as the connection file to a
starting kernel.
Locating kernels
data Kernelspec Source
A kernelspec is a description of a kernel which tells the Jupyter command-line application how to install the kernel and tells the frontends how to invoke the kernel (command line flags, environment, etc).
More documentation about kernelspecs is located in the official documentation.
Constructors
| Kernelspec | |
Fields
| |
findKernel :: Text -> IO (Maybe Kernelspec) Source
Find the kernelspec for a kernel with a given language name.
If no such kernel exists, then Nothing is returned. If an error occurs
while searching for Jupyter kernels, a JupyterKernelspecException is thrown.
findKernels :: IO [Kernelspec] Source
Find all kernelspecs that the Jupyter installation is aware of,
using the jupyter kernelspec list command.
If an error occurs while searching for Jupyter kernels, a JupyterKernelspecException is thrown.