Making simple Python wrapper kernels#

You can reuse IPython’s kernel machinery to easily make new kernels.This is useful for languages that have Python bindings, such asHy (seeCalysto Hy), or languageswhere the REPL can be controlled in a tty usingpexpect,such as bash.

See also

bash_kernel

A simple kernel for bash, written using this machinery

TheMetakernel library makes it easier towrite a wrapper kernel that includes a base set of line and cell magics. Italso has aProcessKernel subclass that makes it easy to write kernels thatusepexpect.SeeOctave Kernel as an example.

If releasing a wrapper kernel as a Python package, see the steps inPackaging.

Required steps#

Subclassipykernel.kernelbase.Kernel, and implement thefollowing methods and attributes:

classMyKernel#
implementation#
implementation_version#
banner#

Information forKernel info replies. ‘Implementation’ refersto the kernel (e.g. IPython), rather than the language (e.g. Python).The ‘banner’ is displayed to the user in consoleUIs before the first prompt. All of these values are strings.

language_info#

Language information forKernel info replies, in a dictionary.This should contain the keymimetype with the mimetype of code in thetarget language (e.g.'text/x-python'), thename of the languagebeing implemented (e.g.'python'), andfile_extension (e.g.'.py').It may also contain keyscodemirror_mode andpygments_lexer if theyneed to differ fromlanguage.

Other keys may be added to this later.

do_execute(code,silent,store_history=True,user_expressions=None,allow_stdin=False)#

Execute user code.

Parameters:
  • code (str) – The code to be executed.

  • silent (bool) – Whether to display output.

  • store_history (bool) – Whether to record this code in history andincrease the execution count. If silent is True, this is implicitlyFalse.

  • user_expressions (dict) – Mapping of names to expressions to evaluateafter the code has run. You can ignore this if you need to.

  • allow_stdin (bool) – Whether the frontend can provide input on request(e.g. for Python’sraw_input()).

Your method should return a dict containing the fields described inExecution results. To display output, it can send messagesusingsend_response(). If an erroroccurs during execution, an message of typeerror should be sentthroughsend_response()in addition to anExecution results with anstatus oferror.SeeMessaging in Jupyter for details of the different message types.

Kernel.send_response(stream,msg_or_type,content=None,ident=None,buffers=None,track=False,header=None,metadata=None,channel=None)#

Send a response to the message we’re currently processing.

This accepts all the parameters ofjupyter_client.session.Session.send()exceptparent.

This relies onset_parent() having been called for the currentmessage.

To launch your kernel, add this at the end of your module:

if__name__=='__main__':fromipykernel.kernelappimportIPKernelAppIPKernelApp.launch_instance(kernel_class=MyKernel)

Now create aJSON kernel spec file and install it usingjupyterkernelspecinstall</path/to/kernel>. Place your kernel module anywhere Python can import it (try current directory for testing). Finally, you can run your kernel usingjupyterconsole--kernel<mykernelname>. Note that<mykernelname> in the below example isecho.

Example#

See also

echo_kernel

A packaged, installable version of the condensed example below.

echokernel.py will simply echo any input it’s given to stdout:

fromipykernel.kernelbaseimportKernelclassEchoKernel(Kernel):implementation='Echo'implementation_version='1.0'language='no-op'language_version='0.1'language_info={'name':'Any text','mimetype':'text/plain','file_extension':'.txt',}banner="Echo kernel - as useful as a parrot"defdo_execute(self,code,silent,store_history=True,user_expressions=None,allow_stdin=False):ifnotsilent:stream_content={'name':'stdout','text':code}self.send_response(self.iopub_socket,'stream',stream_content)return{'status':'ok',# The base class increments the execution count'execution_count':self.execution_count,'payload':[],'user_expressions':{},}if__name__=='__main__':fromipykernel.kernelappimportIPKernelAppIPKernelApp.launch_instance(kernel_class=EchoKernel)

Here’s the Kernel speckernel.json file for this:

{"argv":["python","-m","echokernel","-f","{connection_file}"],"display_name":"Echo"}

Optional steps#

You can override a number of other methods to improve the functionality of yourkernel. All of these methods should return a dictionary as described in therelevant section of themessaging spec.

classMyCustomKernel#
do_complete(code,cursor_pos)#

Code completion

Parameters:
  • code (str) – The code already present

  • cursor_pos (int) – The position in the code where completion is requested

See also

Completion messages

do_inspect(code,cursor_pos,detail_level=0)#

Object introspection

Parameters:
  • code (str) – The code

  • cursor_pos (int) – The position in the code where introspection is requested

  • detail_level (int) – 0 or 1 for more or less detail. In IPython, 1 getsthe source code.

See also

Introspection messages

do_history(hist_access_type,output,raw,session=None,start=None,stop=None,n=None,pattern=None,unique=False)#

History access. Only the relevant parameters for the type of historyrequest concerned will be passed, so your method definition must have defaultsfor all the arguments shown with defaults here.

See also

History messages

do_is_complete(code)#

Is code entered in a console-like interface complete and ready to execute,or should a continuation prompt be shown?

Parameters:

code (str) – The code entered so far - possibly multiple lines

See also

Code completeness messages

do_shutdown(restart)#

Shutdown the kernel. You only need to handle your own clean up - the kernelmachinery will take care of cleaning up its own things before stopping.

Parameters:

restart (bool) – Whether the kernel will be started again afterwards

See also

Kernel shutdown messages