https://github.com/nteract/enchannel-zmq-backend
ZeroMQ backend implementation for enchannel
https://github.com/nteract/enchannel-zmq-backend
ipython jupyter nteract zeromq
Last synced: 3 days ago
JSON representation
ZeroMQ backend implementation for enchannel
- Host: GitHub
- URL: https://github.com/nteract/enchannel-zmq-backend
- Owner: nteract
- License: bsd-3-clause
- Created: 2016-01-12T04:39:56.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2023-03-06T02:28:51.000Z (about 2 years ago)
- Last Synced: 2025-03-30T21:02:21.884Z (24 days ago)
- Topics: ipython, jupyter, nteract, zeromq
- Language: TypeScript
- Homepage:
- Size: 3.47 MB
- Stars: 5
- Watchers: 4
- Forks: 17
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# enchannel-zmq-backend
[**Installation**](#installation) | [**Usage**](#usage) |
[**Contributors and developers**](#contributors-and-developers) |
[**Learn more about nteract**](#learn-more-about-nteract)**enchannel-zmq-backend** offers the ZeroMQ backend implementation for
[`enchannel`](https://github.com/nteract/enchannel).## Technical overview
As a refresher for the reader, [*enchannel*][] details nteract's
lightweight, implementation-flexible specification for communication
between a user frontend and a backend, such as a language kernel. The
*enchannel* specification offers a simple description of "what"
messages may be passed between frontends and backends, while leaving
a developer freedom in "how" to achieve message communication.**enchannel-zmq-backend** takes a classic design approach using ZeroMQ,
the foundation messaging protocol for the Jupyter project.
enchannel-zmq-backend implements backend support for the messaging
channels described in the [Jupyter messaging specification][]. This
spec explains how front end clients should communicate with
backend language kernels which implement the Jupyter messaging
specification.## Our backend
**enchannel-zmq-backend** implements the "how" to communicate messages
to and from a backend.We provide functions to create [RxJS](https://github.com/ReactiveX/RxJS)
[Subjects](http://reactivex.io/documentation/subject.html) (two way
[Observables](http://reactivex.io/documentation/observable.html) for
four of the channels described in the
[Jupyter messaging specification][]):* `shell`
* `control`
* `iopub`
* `stdin`That's it. Functions for four channels; *simplicity in action*.
## Installation
Prerequisite: [Node.js and npm](https://docs.npmjs.com/getting-started/installing-node)
You may use whichever package manager (`npm` or `yarn`) best suits your workflow. The `nteract` team internally uses `yarn`.
```bash
npm install enchannel-zmq-backend
# OR
yarn add enchannel-zmq-backend
```## Usage
### Creating messaging channels
To get access to all of the `channels` for messaging (`shell`, `control`,
`iopub`, and `stdin`), import and use the `createChannels` function:```javascript
import { createChannels } from 'enchannel-zmq-backend'
```The `createChannels` function accepts two things:
- an identity
You'll want to set up your identity, relying on the node `uuid` package:
```javascript
const uuidv4 = require('uuid/v4');
const identity = uuidv4();
```- a runtime object, such as a kernel (which matches the on-disk JSON).
Using [`spawnteract`](https://github.com/nteract/spawnteract) with
this project helps streamline spawning a kernel.```javascript
const runtimeConfig = {
stdin_port: 58786,
ip: '127.0.0.1',
control_port: 58787,
hb_port: 58788,
signature_scheme: 'hmac-sha256',
key: 'dddddddd-eeee-aaaa-dddd-dddddddddddd',
shell_port: 58784,
transport: 'tcp',
iopub_port: 58785
}
```To create the channels *object*:
```javascript
const channels = createChannels(identity, runtimeConfig)
const { shell, iopub, stdin, control } = channels;
````enchannel-zmq-backend` also gives access to all of the `channels` via a
single multipled channel exposed via `createMainChannel`.```javascript
import { createMainChannel } from 'enchannel-zmq-backend';
```Similar to the `createChannels` function, the `createMainChannel` function
accepts both an identity and a runtime object.```javascript
const channel = createMainChannel(identity, runtimeConfig);
```Messages that are sent via the mutliplexed channel need to define a `type`
property that outlines which channel they should be sent under.```javascript
const body = {
header: {
msg_id: `execute_9ed11a0f-707e-4f71-829c-a19b8ff8eed8`,
username: "rgbkrk",
session: "00000000-0000-0000-0000-000000000000",
msg_type: "execute_request",
version: "5.0"
},
content: {
code: 'print("woo")',
silent: false,
store_history: true,
user_expressions: {},
allow_stdin: false
}
};
const message = { type: "shell", body };
````enchannel-zmq-backend` also offers four convenience functions to
easily create the messaging channels for `control`, `stdin`, `iopub`,
and `shell` :```javascript
import {
createControlSubject,
createStdinSubject,
createIOPubSubject,
createShellSubject,
} from 'enchannel-zmq-backend';
```Creating a *subject* for the `shell` channel:
```javascript
const shell = createShellSubject(identity, runtimeConfig)
```### Subscribing to messages
Here's an example about how to subscribe to `iopub` messages:
```javascript
const iopub = createIOPubSubject(identity, runtimeConfig);
var subscription = iopub.subscribe(msg => {
console.log(msg);
}// later, run subscription.unsubscribe()
```Since these channels are RxJS Observables, you can use `filter`, `map`,
`scan` and many other RxJS operators:```javascript
iopub.filter(msg => msg.header.msg_type === 'execute_result')
.map(msg => msg.content.data)
.subscribe(x => { console.log(`DATA! ${util.inspect(x)}`)})
```### Sending messages to the kernel
Executing code will rely on sending an [`execute_request` to the `shell` channel][].
```javascript
var message = {
header: {
msg_id: `execute_9ed11a0f-707e-4f71-829c-a19b8ff8eed8`,
username: 'rgbkrk',
session: '00000000-0000-0000-0000-000000000000',
msg_type: 'execute_request',
version: '5.0',
},
content: {
code: 'print("woo")',
silent: false,
store_history: true,
user_expressions: {},
allow_stdin: false,
},
};
```Currently, you'll need to have at least one subscription activated
before you can send on a channel.```javascript
> shell.subscribe(console.log)
``````javascript
> shell.next(message)
> Message {
header:
{ username: 'rgbkrk',
msg_type: 'execute_reply',
msg_id: '0f6d37f3-56a2-41fd-b3ed-90cc189ac423',
version: '5.1',
session: '40472e70-e008-48d1-9537-55837a905c05',
date: '2016-01-12T00:39:44.686986' },
parent_header:
{ username: 'rgbkrk',
session: '00000000-0000-0000-0000-000000000000',
version: '5.0',
msg_id: 'execute_9ed11a0f-707e-4f71-829c-a19b8ff8eed8',
msg_type: 'execute_request' },
metadata:
{ dependencies_met: true,
engine: '34d73425-4f04-4b57-9bc7-b46e3100e1fd',
status: 'ok',
started: '2016-01-12T00:39:44.684534' },
content:
{ status: 'ok',
execution_count: 60,
user_expressions: {},
payload: [] } }
```## Contributors and developers
### ZeroMQ Dependency
If you plan to contribute to this project or extend it, you will need
to have [ZeroMQ](http://zeromq.org/intro:get-the-software) installed on
your system. The easiest way to do this is to install nteract's
[`zmq-prebuilt`][] binary for your operating system.### Install a local development environment
To set up a development environment, you'll need to install:
- [`npm`](https://docs.npmjs.com/getting-started/installing-node)
- [`zmq-prebuilt`][]Then, fork and clone this repo:
```bash
git clone https://github.com/nteract/enchannel-zmq-backend.git
cd enchannel-zmq-backend
yarn
```Develop! We welcome new and first time contributors.
## Learn more about nteract
- Visit our website https://nteract.io/.
- See our organization on GitHub https://github.com/nteract
- Join us on [Slack](https://slack.nteract.io/) if you need help or have
questions. If you have trouble creating an account, either
email [email protected] or post an issue on GitHub.
[Jupyter messaging specification]: http://jupyter-client.readthedocs.io/en/latest/messaging.html
[`execute_request` to the `shell` channel]: http://jupyter-client.readthedocs.org/en/latest/messaging.html#execute
[*enchannel*]: https://github.com/nteract/enchannel/blob/master/README.md
[`zmq-prebuilt`]: https://github.com/nteract/zmq-prebuilt