-
Notifications
You must be signed in to change notification settings - Fork 287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrap setting of kernel_id with method that can then be overridden in … #353
Wrap setting of kernel_id with method that can then be overridden in … #353
Conversation
…subclasses. A recent requirement for Jupyter Enterprise Gateway is for clients to be able to specify the kernel_id for new kernels. Although `jupyter_client.start_kernel()` will honor client-provided kernel_ids, Notebook's override of `start_kernel()` changes the semantics of a non-null kernel_id in the argument list to mean an existing (persisted) kernel should be _started_. As a result, applications that derive from the kernel management infrastructure beyond Notebook cannot influence the derivation of the kernel's id via the existing argument list behavior. By introducing the `determine_kernel_id()` method, subclasses are able to derive the kernel's id however they wish. With the ability to know the kernel's id prior to its invocation, a number of things can be done that wouldn't be possible otherwise. For example, this provides the ability to setup a shared filesystem location possibly pre-populated with data relative to what the request (i.e., kernel) is going to need.
jupyter_client/multikernelmanager.py
Outdated
@@ -315,3 +315,13 @@ def connect_hb(self, kernel_id, identity=None): | |||
======= | |||
stream : zmq Socket or ZMQStream | |||
""" | |||
|
|||
def determine_kernel_id(self, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe simpler verb 'new_kernel_id'?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm okay with changing the verb in the method name - please see next comment.
jupyter_client/multikernelmanager.py
Outdated
@@ -90,7 +90,7 @@ def start_kernel(self, kernel_name=None, **kwargs): | |||
|
|||
The kernel ID for the newly started kernel is returned. | |||
""" | |||
kernel_id = kwargs.pop('kernel_id', unicode_type(uuid.uuid4())) | |||
kernel_id = self.determine_kernel_id(**kwargs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should determine_kernel_id
be called if kernel_id is specified? It seems like it should only be called if kernel_id is not specified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@minrk - thank you for taking a look at this.
I was originally thinking that the override should be called unconditionally with the base implementation honoring the existence of the parameter, but that probably leaves too much room for mistakes, so I'd be okay with calling the method only when kernel_id is None
.
Not sure if its my Java background (very new to python), but I don't like using new
as a verb. Does something like init_kernel_id(**kwargs)
sound any better?
Would you mind suggesting the appropriate python way for constructing the conditional call based on the pop
result?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would write it like this:
if 'kernel_id' in kwargs:
kernel_id = kwargs.pop('kernel_id')
else:
kernel_id = self.new_kernel_id()
By Python (or maybe just Jupyter) convention, I like new
better than init
, because init
implies a stateful change. I would expect .init_kernel_id()
to set self.kernel_id
, not return a value I'm free to use. The verb I would use for a stateless callable that returns a new kernel id is 'new'. 'generate' works, too, but it's more verbose than I would like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation on new
vs. init
- that makes sense. Regarding the example (and a better understanding of python args), I figured things would be more compact and something like the original would have been suggested:
kernel_id = kwargs.pop('kernel_id', self.new_kernel_id(**kwargs))
I'd prefer to push this version, but would be happy to submit the expanded form if you feel strongly about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't make much of a difference here, but I find clarity is typically preferable to compactness. The if/else
is also ever-so-slightly more efficient, since new_kernel_id
is only called if needed, rather than this PR, where it's called unconditionally, even if the result is just discarded.
Per review comments, the name of the method to generate a kernel_id was changed to `new_kernel_id()`. In addition, the method is now only called if `kernel_id` is not represented in the keyword arguments (`**kwargs`).
…subclasses.
A recent requirement for Jupyter Enterprise Gateway is for clients to be able to
specify the kernel_id for new kernels. Although
jupyter_client.start_kernel()
willhonor client-provided kernel_ids, Notebook's override of
start_kernel()
changesthe semantics of a non-null kernel_id in the argument list to mean an existing
(persisted) kernel should be started. As a result, applications that derive
from the kernel management infrastructure beyond Notebook cannot influence the
derivation of the kernel's id via the existing argument list behavior.
By introducing the
determine_kernel_id()
method, subclasses are able to derivethe kernel's id however they wish.
With the ability to know the kernel's id prior to its invocation, a number of
things can be done that wouldn't be possible otherwise. For example, this
provides the ability to setup a shared filesystem location possibly pre-populated
with data relative to what the request (i.e., kernel) is going to need.