Show More
@@ -0,0 +1,152 | |||
|
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 | `Creating Language Kernels for IPython <http://andrew.gibiansky.com/blog/ipython/ipython-kernels/>`_ | |
|
76 | A blog post by the author of `IHaskell <https://github.com/gibiansky/IHaskell>`_, | |
|
77 | a Haskell kernel | |
|
78 | ||
|
79 | `simple_kernel <https://github.com/dsblank/simple_kernel>`_ | |
|
80 | A simple example implementation of the kernel machinery in Python | |
|
81 | ||
|
82 | ||
|
83 | .. _kernelspecs: | |
|
84 | ||
|
85 | Kernel specs | |
|
86 | ============ | |
|
87 | ||
|
88 | A kernel identifies itself to IPython by creating a directory, the name of which | |
|
89 | is used as an identifier for the kernel. These may be created in a number of | |
|
90 | locations: | |
|
91 | ||
|
92 | +--------+--------------------------------------+-----------------------------------+ | |
|
93 | | | Unix | Windows | | |
|
94 | +========+======================================+===================================+ | |
|
95 | | System | ``/usr/share/ipython/kernels`` | ``%PROGRAMDATA%\ipython\kernels`` | | |
|
96 | | | | | | |
|
97 | | | ``/usr/local/share/ipython/kernels`` | | | |
|
98 | +--------+--------------------------------------+-----------------------------------+ | |
|
99 | | User | ``~/.ipython/kernels`` | | |
|
100 | +--------+--------------------------------------+-----------------------------------+ | |
|
101 | ||
|
102 | The user location takes priority over the system locations, and the case of the | |
|
103 | names is ignored, so selecting kernels works the same way whether or not the | |
|
104 | filesystem is case sensitive. | |
|
105 | ||
|
106 | Inside the directory, the most important file is *kernel.json*. This should be a | |
|
107 | JSON serialised dictionary containing the following keys and values: | |
|
108 | ||
|
109 | - **argv**: A list of command line arguments used to start the kernel. The text | |
|
110 | ``{connection_file}`` in any argument will be replaced with the path to the | |
|
111 | connection file. | |
|
112 | - **display_name**: The kernel's name as it should be displayed in the UI. | |
|
113 | Unlike the kernel name used in the API, this can contain arbitrary unicode | |
|
114 | characters. | |
|
115 | - **language**: The programming language which this kernel runs. This will be | |
|
116 | stored in notebook metadata. This may be used by syntax highlighters to guess | |
|
117 | how to parse code in a notebook, and frontends may eventually use it to | |
|
118 | identify alternative kernels that can run some code. | |
|
119 | - **codemirror_mode** (optional): The `codemirror mode <http://codemirror.net/mode/index.html>`_ | |
|
120 | to use for code in this language. This can be a string or a dictionary, as | |
|
121 | passed to codemirror config. The string from *language* will be used if this is | |
|
122 | not provided. | |
|
123 | - **env** (optional): A dictionary of environment variables to set for the kernel. | |
|
124 | These will be added to the current environment variables before the kernel is | |
|
125 | started. | |
|
126 | - **help_links** (optional): A list of dictionaries, each with keys 'text' and | |
|
127 | 'url'. These will be displayed in the help menu in the notebook UI. | |
|
128 | ||
|
129 | For example, the kernel.json file for IPython looks like this:: | |
|
130 | ||
|
131 | { | |
|
132 | "argv": ["python3", "-c", "from IPython.kernel.zmq.kernelapp import main; main()", | |
|
133 | "-f", "{connection_file}"], | |
|
134 | "codemirror_mode": { | |
|
135 | "version": 3, | |
|
136 | "name": "ipython" | |
|
137 | }, | |
|
138 | "display_name": "IPython (Python 3)", | |
|
139 | "language": "python" | |
|
140 | } | |
|
141 | ||
|
142 | To see the available kernel specs, run:: | |
|
143 | ||
|
144 | ipython kernelspec list | |
|
145 | ||
|
146 | To start the terminal console or the Qt console with a specific kernel:: | |
|
147 | ||
|
148 | ipython console --kernel bash | |
|
149 | ipython qtconsole --kernel bash | |
|
150 | ||
|
151 | To use different kernels in the notebook, select a different kernel from the | |
|
152 | dropdown menu in the top-right of the UI. |
@@ -26,7 +26,7 within and between hosts. | |||
|
26 | 26 | IPython messaging protocol, and all developers are strongly encouraged to |
|
27 | 27 | keep it updated as the implementation evolves, so that we have a single |
|
28 | 28 | common reference for all protocol details. |
|
29 | ||
|
29 | ||
|
30 | 30 | The basic design is explained in the following diagram: |
|
31 | 31 | |
|
32 | 32 | .. image:: figs/frontend-kernel.png |
@@ -126,6 +126,8 A message is defined by the following four-dictionary structure:: | |||
|
126 | 126 | |
|
127 | 127 | ``version`` key added to the header. |
|
128 | 128 | |
|
129 | .. _wire_protocol: | |
|
130 | ||
|
129 | 131 | The Wire Protocol |
|
130 | 132 | ================= |
|
131 | 133 | |
@@ -971,6 +973,7 When ``password`` is True, the frontend should not echo the input as it is enter | |||
|
971 | 973 | transported over the zmq connection), raw ``stdin`` isn't expected to be |
|
972 | 974 | available. |
|
973 | 975 | |
|
976 | .. _kernel_heartbeat: | |
|
974 | 977 | |
|
975 | 978 | Heartbeat for kernels |
|
976 | 979 | ===================== |
@@ -10,6 +10,11 This is useful for languages that have Python bindings, such as `Octave | |||
|
10 | 10 | where the REPL can be controlled in a tty using `pexpect <http://pexpect.readthedocs.org/en/latest/>`_, |
|
11 | 11 | such as bash. |
|
12 | 12 | |
|
13 | .. seealso:: | |
|
14 | ||
|
15 | `bash_kernel <https://github.com/takluyver/bash_kernel>`_ | |
|
16 | A simple kernel for bash, written using this machinery | |
|
17 | ||
|
13 | 18 | Required steps |
|
14 | 19 | -------------- |
|
15 | 20 |
General Comments 0
You need to be logged in to leave comments.
Login now