Skip to content

Commit 5bc2793

Browse files
committed
Enable kernel message filtering
1 parent bdf256c commit 5bc2793

File tree

2 files changed

+28
-13
lines changed

2 files changed

+28
-13
lines changed

jupyter_server/services/kernels/handlers.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ def pre_get(self):
224224
kernel = self.kernel_manager.get_kernel(self.kernel_id)
225225
self.session.key = kernel.session.key
226226
future = self.request_kernel_info()
227-
227+
228228
def give_up():
229229
"""Don't wait forever for the kernel to reply"""
230230
if future.done():
@@ -307,8 +307,13 @@ def on_message(self, msg):
307307
if channel not in self.channels:
308308
self.log.warning("No such channel: %r", channel)
309309
return
310-
stream = self.channels[channel]
311-
self.session.send(stream, msg)
310+
am = self.kernel_manager.allowed_message_types
311+
mt = msg['header']['msg_type']
312+
if am and mt not in am:
313+
self.log.warning('Received message of type "%s", which is not allowed. Ignoring.' % mt)
314+
else:
315+
stream = self.channels[channel]
316+
self.session.send(stream, msg)
312317

313318
def _on_zmq_reply(self, stream, msg_list):
314319
idents, fed_msg_list = self.session.feed_identities(msg_list)

jupyter_server/services/kernels/kernelmanager.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@
2828

2929

3030
class MappingKernelManager(MultiKernelManager):
31-
"""A KernelManager that handles file mapping and HTTP error handling"""
31+
"""A KernelManager that handles
32+
- File mapping
33+
- HTTP error handling
34+
- Kernel message filtering
35+
"""
3236

3337
@default('kernel_manager_class')
3438
def _default_kernel_manager_class(self):
@@ -93,15 +97,15 @@ def _update_root_dir(self, proposal):
9397
no frontends are connected.
9498
"""
9599
)
96-
100+
97101
kernel_info_timeout = Float(60, config=True,
98102
help="""Timeout for giving up on a kernel (in seconds).
99103
100104
On starting and restarting kernels, we check whether the
101105
kernel is running and responsive by sending kernel_info_requests.
102106
This sets the timeout in seconds for how long the kernel can take
103-
before being presumed dead.
104-
This affects the MappingKernelManager (which handles kernel restarts)
107+
before being presumed dead.
108+
This affects the MappingKernelManager (which handles kernel restarts)
105109
and the ZMQChannelsHandler (which handles the startup).
106110
"""
107111
)
@@ -118,6 +122,12 @@ def __init__(self, **kwargs):
118122
super(MappingKernelManager, self).__init__(**kwargs)
119123
self.last_kernel_activity = utcnow()
120124

125+
allowed_message_types = List(trait=Unicode(), config=True,
126+
help="""White list of allowed kernel message types.
127+
When the list is empty, all message types are allowed.
128+
"""
129+
)
130+
121131
#-------------------------------------------------------------------------
122132
# Methods for managing kernels and sessions
123133
#-------------------------------------------------------------------------
@@ -287,32 +297,32 @@ def restart_kernel(self, kernel_id):
287297
# return a Future that will resolve when the kernel has successfully restarted
288298
channel = kernel.connect_shell()
289299
future = Future()
290-
300+
291301
def finish():
292302
"""Common cleanup when restart finishes/fails for any reason."""
293303
if not channel.closed():
294304
channel.close()
295305
loop.remove_timeout(timeout)
296306
kernel.remove_restart_callback(on_restart_failed, 'dead')
297-
307+
298308
def on_reply(msg):
299309
self.log.debug("Kernel info reply received: %s", kernel_id)
300310
finish()
301311
if not future.done():
302312
future.set_result(msg)
303-
313+
304314
def on_timeout():
305315
self.log.warning("Timeout waiting for kernel_info_reply: %s", kernel_id)
306316
finish()
307317
if not future.done():
308318
future.set_exception(gen.TimeoutError("Timeout waiting for restart"))
309-
319+
310320
def on_restart_failed():
311321
self.log.warning("Restarting kernel failed: %s", kernel_id)
312322
finish()
313323
if not future.done():
314324
future.set_exception(RuntimeError("Restart failed"))
315-
325+
316326
kernel.add_restart_callback(on_restart_failed, 'dead')
317327
kernel.session.send(channel, "kernel_info_request")
318328
channel.on_recv(on_reply)
@@ -366,7 +376,7 @@ def _check_kernel_id(self, kernel_id):
366376

367377
def start_watching_activity(self, kernel_id):
368378
"""Start watching IOPub messages on a kernel for activity.
369-
379+
370380
- update last_activity on every message
371381
- record execution_state from status messages
372382
"""

0 commit comments

Comments
 (0)