Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 81db036

Browse files
committed
Add docs on writing kernels
1 parent d6d4f53 commit 81db036

2 files changed

Lines changed: 149 additions & 1 deletion

File tree

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
==========================
2+
Making kernels for IPython
3+
==========================
4+
5+
A 'kernel' is a program that runs and introspects the user's code. IPython
6+
includes a kernel for Python code, and people have written kernels for
7+
`several other languages <https://github.com/ipython/ipython/wiki/Projects-using-IPython#list-of-some-ipython-compatible-kernels>`_.
8+
9+
When IPython starts a kernel, it passes it a connection file. This specifies
10+
how to set up communications with the frontend.
11+
12+
There are two options for writing a kernel:
13+
14+
1. You can reuse the IPython kernel machinery to handle the communications, and
15+
just describe how to execute your code. This is much simpler if the target
16+
language can be driven from Python. See :doc:`wrapperkernels` for details.
17+
2. You can implement the kernel machinery in your target language. This is more
18+
work initially, but the people using your kernel might be more likely to
19+
contribute to it if it's in the language they know.
20+
21+
Connection files
22+
================
23+
24+
Your kernel will be given the path to a connection file when it starts (see
25+
:ref:`kernelspecs` for how to specify the command line arguments for your kernel).
26+
This file, which is accessible only to the current user, will contain a JSON
27+
dictionary looking something like this::
28+
29+
{
30+
"control_port": 50160,
31+
"shell_port": 57503,
32+
"transport": "tcp",
33+
"signature_scheme": "hmac-sha256",
34+
"stdin_port": 52597,
35+
"hb_port": 42540,
36+
"ip": "127.0.0.1",
37+
"iopub_port": 40885,
38+
"key": "a0436f6c-1916-498b-8eb9-e81ab9368e84"
39+
}
40+
41+
The ``transport``, ``ip`` and five ``_port`` fields specify five ports which the
42+
kernel should bind to using `ZeroMQ <http://zeromq.org/>`_. For instance, the
43+
address of the shell socket in the example above would be::
44+
45+
tcp://127.0.0.1:57503
46+
47+
New ports are chosen at random for each kernel started.
48+
49+
``signature_scheme`` and ``key`` are used to cryptographically sign messages, so
50+
that other users on the system can't send code to run in this kernel. See
51+
:ref:`wire_protocol` for the details of how this signature is calculated.
52+
53+
Handling messages
54+
=================
55+
56+
After reading the connection file and binding to the necessary sockets, the
57+
kernel should go into an event loop, listening on the hb (heartbeat), control
58+
and shell sockets.
59+
60+
:ref:`Heartbeat <kernel_heartbeat>` messages should be echoed back immediately
61+
on the same socket - the frontend uses this to check that the kernel is still
62+
alive.
63+
64+
Messages on the control and shell sockets should be parsed, and their signature
65+
validated. See :ref:`wire_protocol` for how to do this.
66+
67+
The kernel will send messages on the iopub socket to display output, and on the
68+
stdin socket to prompt the user for textual input.
69+
70+
.. seealso::
71+
72+
:doc:`messaging`
73+
Details of the different sockets and the messages that come over them.
74+
75+
76+
.. _kernelspecs:
77+
78+
Kernel specs
79+
============
80+
81+
A kernel identifies itself to IPython by creating a directory, the name of which
82+
is used as an identifier for the kernel. These may be created in a number of
83+
locations:
84+
85+
+--------+--------------------------------------+-----------------------------------+
86+
| | Unix | Windows |
87+
+========+======================================+===================================+
88+
| System | ``/usr/share/ipython/kernels`` | ``%PROGRAMDATA%\ipython\kernels`` |
89+
| | | |
90+
| | ``/usr/local/share/ipython/kernels`` | |
91+
+--------+--------------------------------------+-----------------------------------+
92+
| User | ``~/.ipython/kernels`` |
93+
+--------+--------------------------------------+-----------------------------------+
94+
95+
The user location takes priority over the system locations, and the case of the
96+
names is ignored, so selecting kernels works the same way whether or not the
97+
filesystem is case sensitive.
98+
99+
Inside the directory, the most important file is *kernel.json*. This should be a
100+
JSON serialised dictionary containing the following keys and values:
101+
102+
- **argv**: A list of command line arguments used to start the kernel. The text
103+
``{connection_file}`` in any argument will be replaced with the path to the
104+
connection file.
105+
- **display_name**: The kernel's name as it should be displayed in the UI.
106+
Unlike the kernel name used in the API, this can contain arbitrary unicode
107+
characters.
108+
- **language**: The programming language which this kernel runs. This will be
109+
stored in notebook metadata. This may be used by syntax highlighters to guess
110+
how to parse code in a notebook, and frontends may eventually use it to
111+
identify alternative kernels that can run some code.
112+
- **codemirror_mode** (optional): The `codemirror mode <http://codemirror.net/mode/index.html>`_
113+
to use for code in this language. This can be a string or a dictionary, as
114+
passed to codemirror config. The string from *language* will be used if this is
115+
not provided.
116+
- **env** (optional): A dictionary of environment variables to set for the kernel.
117+
These will be added to the current environment variables before the kernel is
118+
started.
119+
- **help_links** (optional): A list of dictionaries, each with keys 'text' and
120+
'url'. These will be displayed in the help menu in the notebook UI.
121+
122+
For example, the kernel.json file for IPython looks like this::
123+
124+
{
125+
"argv": ["python3", "-c", "from IPython.kernel.zmq.kernelapp import main; main()",
126+
"-f", "{connection_file}"],
127+
"codemirror_mode": {
128+
"version": 3,
129+
"name": "ipython"
130+
},
131+
"display_name": "IPython (Python 3)",
132+
"language": "python"
133+
}
134+
135+
To see the available kernel specs, run::
136+
137+
ipython kernelspec list
138+
139+
To start the terminal console or the Qt console with a specific kernel::
140+
141+
ipython console --kernel bash
142+
ipython qtconsole --kernel bash
143+
144+
To use different kernels in the notebook, select a different kernel from the
145+
dropdown menu in the top-right of the UI.

docs/source/development/messaging.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ within and between hosts.
2626
IPython messaging protocol, and all developers are strongly encouraged to
2727
keep it updated as the implementation evolves, so that we have a single
2828
common reference for all protocol details.
29-
29+
3030
The basic design is explained in the following diagram:
3131

3232
.. image:: figs/frontend-kernel.png
@@ -126,6 +126,8 @@ A message is defined by the following four-dictionary structure::
126126

127127
``version`` key added to the header.
128128

129+
.. _wire_protocol:
130+
129131
The Wire Protocol
130132
=================
131133

@@ -971,6 +973,7 @@ When ``password`` is True, the frontend should not echo the input as it is enter
971973
transported over the zmq connection), raw ``stdin`` isn't expected to be
972974
available.
973975

976+
.. _kernel_heartbeat:
974977

975978
Heartbeat for kernels
976979
=====================

0 commit comments

Comments
 (0)