fsleyes.actions.notebook

This module provides the NotebookAction class, an action which starts an IPython kernel and a Jupyter notebook server, allowing the user to interact with FSLeyes via a jupyter notebook.

class fsleyes.actions.notebook.NotebookAction(overlayList, displayCtx, frame)[source]

Bases: fsleyes.actions.base.Action

The NotebookAction is an Action which (if necessary) starts an embedded IPython kernel and a jupyter notebook server, and opens the server home page in a web browser allowing the user to interact with FSLeyes via notebooks.

__init__(overlayList, displayCtx, frame)[source]

Create a NotebookAction.

Parameters
__openNotebooks(nbfile=None)

Called when this NotebookAction is invoked. Starts the server and kernel if necessary.

If the server/kernel have not yet been started and nbfile is provided, the server will be started with nbfile opened.

__bounce(secs, progdlg)

Used by __startKernel() and __startServer(). Blocks for secs, bouncing the Progress dialog ten times per second, and yielding to the wx main loop.

__startKernel(progdlg)

Attempts to create and start a BackgroundIPythonKernel.

Returns

the kernel if it was started.

Raises

A RuntimeError if the kernel did not start.

__startServer(progdlg, nbfile=None)

Attempts to create and start a NotebookServer.

Returns

the server if it was started.

Raises

A RuntimeError if the serer did not start.

__annotations__ = {}
__module__ = 'fsleyes.actions.notebook'
class fsleyes.actions.notebook.BackgroundIPythonKernel(overlayList, displayCtx, frame)[source]

Bases: object

The BackgroundIPythonKernel creates an IPython jupyter kernel and makes it accessible over tcp (on the local machine only).

Before FSLeyes 0.28.0, this class derived from threading.Thread, and ran its own IOLoop which was used to run the IPython kernel. But now the IPython kernel is run on the main thread, by repeatedly scheduling calls to IPythonKernel.do_one_iteration on idle.idle().

This update was necessary due to changes in ipykernel from version 4 to version 5, namely that ipykernel 5 uses asyncio co-routines, making it difficult to transfer execution between threads.

Because the BackgroundIPythonKernel used to be a thread, it is still necessary to call its start() method to start the kernel loop.

The Jupyter/IPython documentation is quite fragmented at this point in time; this github issue was useful in figuring out the implementation details.

__init__(overlayList, displayCtx, frame)[source]

Set up the kernel and zmq ports. A jupyter connection file containing the information needed to connect to the kernel is saved to a temporary file - its path is accessed as an attribute called connfile().

Parameters
is_alive()[source]

Returns True if the kernel loop appears to be running, False otherwise

property kernel

The IPythonKernel object.

property env

The namespace passed to the kernel.

property connfile

The jupyter connection file containing information to connect to the IPython kernel.

property error

If an error occurs on the kernel loop causing it to crash, a reference to the Exception is stored here.

__screenshot(view)

Insert a screenshot of the given view into the notebook.

start()[source]

Start the IPython kernel loop. This method returns immediately - the kernel loop is driven on idle.idle().

__eventloop()

Event loop used for the IPython kernel. Calls __kernelDispatch(), then schedules a future call to __eventloop via idle.idle() loop.

__kernelDispatch()

Execute one kernel iteration, by scheduling a call to IPythonKernel.do_one_iteration on the kernel’s io loop.

__dict__ = mappingproxy({'__module__': 'fsleyes.actions.notebook', '__doc__': 'The BackgroundIPythonKernel creates an IPython jupyter kernel and makes\n    it accessible over tcp (on the local machine only).\n\n    Before FSLeyes 0.28.0, this class derived from ``threading.Thread``, and\n    ran its own ``IOLoop`` which was used to run the IPython kernel.  But now\n    the IPython kernel is run on the main thread, by repeatedly scheduling\n    calls to ``IPythonKernel.do_one_iteration`` on :func:`.idle.idle`.\n\n    This update was necessary due to changes in ``ipykernel`` from version 4\n    to version 5, namely that ipykernel 5 uses ``asyncio`` co-routines, making\n    it difficult to transfer execution between threads.\n\n    Because the ``BackgroundIPythonKernel`` used to be a thread, it is still\n    necessary to call its :meth:`start` method to start the kernel loop.\n\n    The Jupyter/IPython documentation is quite fragmented at this point in\n    time; `this github issue <https://github.com/ipython/ipython/issues/8097>`_\n    was useful in figuring out the implementation details.\n    ', '__init__': <function BackgroundIPythonKernel.__init__>, 'is_alive': <function BackgroundIPythonKernel.is_alive>, 'kernel': <property object>, 'env': <property object>, 'connfile': <property object>, 'error': <property object>, '_BackgroundIPythonKernel__screenshot': <function BackgroundIPythonKernel.__screenshot>, 'start': <function BackgroundIPythonKernel.start>, '_BackgroundIPythonKernel__eventloop': <function BackgroundIPythonKernel.__eventloop>, '_BackgroundIPythonKernel__kernelDispatch': <function BackgroundIPythonKernel.__kernelDispatch>, '__dict__': <attribute '__dict__' of 'BackgroundIPythonKernel' objects>, '__weakref__': <attribute '__weakref__' of 'BackgroundIPythonKernel' objects>, '__annotations__': {}})
__module__ = 'fsleyes.actions.notebook'
__weakref__

list of weak references to the object (if defined)

class fsleyes.actions.notebook.FSLeyesIPythonKernel(stdout, stderr, *args, **kwargs)[source]

Bases: fsleyes.actions.notebook.mock

Custom IPython kernel used by FSLeyes. All this class does is ensure that the sys.stdout and sys.stderr streams are set appropriately when the kernel is executing code.

__init__(stdout, stderr, *args, **kwargs)[source]

Initialize self. See help(type(self)) for accurate signature.

__patch_streams()
execute_request(*args, **kwargs)[source]
dispatch_control(*args, **kwargs)[source]
dispatch_shell(*args, **kwargs)[source]
__module__ = 'fsleyes.actions.notebook'
class fsleyes.actions.notebook.FSLeyesIPythonShell[source]

Bases: fsleyes.actions.notebook.mock

Custom IPython shell class used by FSLeyes.

enable_gui(gui)[source]

Overrides ipykernel.zmqshell.ZMQInteractiveShell.enable_gui.

The default implementation will attempt to change the IPython GUI integration event loop, which will conflict with our own event loop in the BackgroundIPythonKernel. So this implementation does nothing.

__annotations__ = {}
__module__ = 'fsleyes.actions.notebook'
class fsleyes.actions.notebook.NotebookServer(connfile, nbfile=None)[source]

Bases: threading.Thread

Thread which starts a jupyter notebook server, and waits until it dies or is killed.

The server is configured such that all notebooks will connect to the same kernel, specified by the kernelFile parameter to __init__().

__init__(connfile, nbfile=None)[source]

Create a NotebookServer thread.

Parameters
  • connfile – Connection file of the IPython kernel to connect to.

  • nbfile – Path to a notebook file which should be opened on startup.

property port

Returns the TCP port that the notebook server is listening on. Will return None before the server has started.

__readPort()
property ready

Returns True if the server is running and ready, False otherwise.

property token

Returns an authentication token to use for connectng to the notebook server.

property url

Returns the URL to use to connect to this server.

property stdout

After the server has died, returns its standard output. While the server is still running, returns None.

property stderr

After the server has died, returns its standard error. While the server is still running, returns None.

run()[source]

Sets up a server configuration file, and then calls jupyer-notebook via subprocess.Popen. Waits until the notebook process dies.

__initConfigDir(cfgdir)

Creates a copy of the FSLeyes /assets/jupyter/ configuration directory in $TMPDIR, and customises its settings accordingly.

__module__ = 'fsleyes.actions.notebook'
class fsleyes.actions.notebook.mock[source]

Bases: object

__annotations__ = {}
__dict__ = mappingproxy({'__module__': 'fsleyes.actions.notebook', '__dict__': <attribute '__dict__' of 'mock' objects>, '__weakref__': <attribute '__weakref__' of 'mock' objects>, '__doc__': None, '__annotations__': {}})
__module__ = 'fsleyes.actions.notebook'
__weakref__

list of weak references to the object (if defined)

fsleyes.actions.notebook.nbmain(argv)[source]

Wrapper around a Jupyter Notebook server entry point. Invoked by the NotebookServer, via a hook in fsleyes.main.main().