base_frontend_mixin.py
121 lines
| 4.9 KiB
| text/x-python
|
PythonLexer
epatters
|
r2770 | """ Defines a convenient mix-in class for implementing Qt frontends. | ||
""" | ||||
class BaseFrontendMixin(object): | ||||
""" A mix-in class for implementing Qt frontends. | ||||
To handle messages of a particular type, frontends need only define an | ||||
appropriate handler method. For example, to handle 'stream' messaged, define | ||||
a '_handle_stream(msg)' method. | ||||
""" | ||||
#--------------------------------------------------------------------------- | ||||
# 'BaseFrontendMixin' concrete interface | ||||
#--------------------------------------------------------------------------- | ||||
Bernardo B. Marques
|
r4872 | |||
epatters
|
r2770 | def _get_kernel_manager(self): | ||
""" Returns the current kernel manager. | ||||
""" | ||||
return self._kernel_manager | ||||
def _set_kernel_manager(self, kernel_manager): | ||||
""" Disconnect from the current kernel manager (if any) and set a new | ||||
kernel manager. | ||||
""" | ||||
# Disconnect the old kernel manager, if necessary. | ||||
old_manager = self._kernel_manager | ||||
if old_manager is not None: | ||||
MinRK
|
r7079 | old_manager.started_kernel.disconnect(self._started_kernel) | ||
epatters
|
r2770 | old_manager.started_channels.disconnect(self._started_channels) | ||
old_manager.stopped_channels.disconnect(self._stopped_channels) | ||||
# Disconnect the old kernel manager's channels. | ||||
Brian Granger
|
r9120 | old_manager.iopub_channel.message_received.disconnect(self._dispatch) | ||
MinRK
|
r3974 | old_manager.shell_channel.message_received.disconnect(self._dispatch) | ||
old_manager.stdin_channel.message_received.disconnect(self._dispatch) | ||||
epatters
|
r2913 | old_manager.hb_channel.kernel_died.disconnect( | ||
self._handle_kernel_died) | ||||
Bernardo B. Marques
|
r4872 | |||
epatters
|
r2770 | # Handle the case where the old kernel manager is still listening. | ||
if old_manager.channels_running: | ||||
self._stopped_channels() | ||||
# Set the new kernel manager. | ||||
self._kernel_manager = kernel_manager | ||||
if kernel_manager is None: | ||||
return | ||||
# Connect the new kernel manager. | ||||
MinRK
|
r7079 | kernel_manager.started_kernel.connect(self._started_kernel) | ||
epatters
|
r2770 | kernel_manager.started_channels.connect(self._started_channels) | ||
kernel_manager.stopped_channels.connect(self._stopped_channels) | ||||
# Connect the new kernel manager's channels. | ||||
Brian Granger
|
r9120 | kernel_manager.iopub_channel.message_received.connect(self._dispatch) | ||
MinRK
|
r3974 | kernel_manager.shell_channel.message_received.connect(self._dispatch) | ||
kernel_manager.stdin_channel.message_received.connect(self._dispatch) | ||||
Brian Granger
|
r2910 | kernel_manager.hb_channel.kernel_died.connect(self._handle_kernel_died) | ||
epatters
|
r2770 | # Handle the case where the kernel manager started channels before | ||
# we connected. | ||||
if kernel_manager.channels_running: | ||||
self._started_channels() | ||||
kernel_manager = property(_get_kernel_manager, _set_kernel_manager) | ||||
#--------------------------------------------------------------------------- | ||||
# 'BaseFrontendMixin' abstract interface | ||||
#--------------------------------------------------------------------------- | ||||
epatters
|
r2913 | |||
def _handle_kernel_died(self, since_last_heartbeat): | ||||
""" This is called when the ``kernel_died`` signal is emitted. | ||||
This method is called when the kernel heartbeat has not been | ||||
active for a certain amount of time. The typical action will be to | ||||
give the user the option of restarting the kernel. | ||||
Parameters | ||||
---------- | ||||
since_last_heartbeat : float | ||||
The time since the heartbeat was last received. | ||||
""" | ||||
Bernardo B. Marques
|
r4872 | |||
MinRK
|
r7079 | def _started_kernel(self): | ||
"""Called when the KernelManager starts (or restarts) the kernel subprocess. | ||||
Channels may or may not be running at this point. | ||||
""" | ||||
epatters
|
r2770 | def _started_channels(self): | ||
Bernardo B. Marques
|
r4872 | """ Called when the KernelManager channels have started listening or | ||
epatters
|
r2770 | when the frontend is assigned an already listening KernelManager. | ||
""" | ||||
def _stopped_channels(self): | ||||
""" Called when the KernelManager channels have stopped listening or | ||||
when a listening KernelManager is removed from the frontend. | ||||
""" | ||||
#--------------------------------------------------------------------------- | ||||
epatters
|
r2824 | # 'BaseFrontendMixin' protected interface | ||
epatters
|
r2770 | #--------------------------------------------------------------------------- | ||
def _dispatch(self, msg): | ||||
Bernardo B. Marques
|
r4872 | """ Calls the frontend handler associated with the message type of the | ||
epatters
|
r2824 | given message. | ||
epatters
|
r2770 | """ | ||
Brian E. Granger
|
r4230 | msg_type = msg['header']['msg_type'] | ||
epatters
|
r2770 | handler = getattr(self, '_handle_' + msg_type, None) | ||
if handler: | ||||
handler(msg) | ||||
epatters
|
r2824 | |||
def _is_from_this_session(self, msg): | ||||
""" Returns whether a reply from the kernel originated from a request | ||||
from this frontend. | ||||
""" | ||||
session = self._kernel_manager.session.session | ||||
MinRK
|
r5362 | parent = msg['parent_header'] | ||
if not parent: | ||||
# if the message has no parent, assume it is meant for all frontends | ||||
return True | ||||
else: | ||||
return parent.get('session') == session | ||||