Skip to content

Commit d0ee6c9

Browse files
committed
Lay foundation to pass notebook names to kernel at startup.
This has been a controversial topic from some time: jupyter/notebook#1000 https://forums.databricks.com/questions/21390/is-there-any-way-to-get-the-current-notebook-name.html https://stackoverflow.com/questions/12544056/how-do-i-get-the-current-ipython-jupyter-notebook-name https://ask.sagemath.org/question/36873/access-notebook-filename-from-jupyter-with-sagemath-kernel/ This is also sometime critical to linter, and tab completion to know current name. Of course current answer is that the question is ill-defined, there might not be a file associated with the current kernel, there might be multiple files, files might not be on the same system, it could change through the execution and many other gotchas. This suggest to add an JPY_KERNEL_SESSION_NAME env variable which is not too visible, but give an escape hatch which should mostly be correct unless the notebook is renamed or kernel attached to a new one. Do do so this handles the new associated_file parameters in a few function of the kernel manager. On jupyter_server this one line change make the notebook name available using typical local installs: ```diff diff --git a/notebook/services/sessions/sessionmanager.py b/notebook/services/sessions/sessionmanager.py index 92b2a7345..f7b4011ce 100644 --- a/notebook/services/sessions/sessionmanager.py +++ b/notebook/services/sessions/sessionmanager.py @@ -108,7 +108,9 @@ class SessionManager(LoggingConfigurable): # allow contents manager to specify kernels cwd kernel_path = self.contents_manager.get_kernel_path(path=path) kernel_id = yield maybe_future( - self.kernel_manager.start_kernel(path=kernel_path, kernel_name=kernel_name) + self.kernel_manager.start_kernel( + path=kernel_path, kernel_name=kernel_name, session_name=path + ) ) # py2-compat raise gen.Return(kernel_id) ```diff Of course only launchers that will pass forward this value will allow the env variable to be set. I'm thinking that various kernels may use this and expose it in different ways. like __notebook_name__ if it ends with `.ipynb` in ipykernel.
1 parent 7b5a95c commit d0ee6c9

File tree

4 files changed

+28
-2
lines changed

4 files changed

+28
-2
lines changed

jupyter_client/manager.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@
3434
from jupyter_client import kernelspec
3535

3636

37+
# Name of the env variable that contains the name of the current session associated
38+
# with the kernel we are launching.
39+
# Frontends can decide to set this session name to the name of the file when
40+
# when the kernel is started.
41+
# This is useful in notebook context to find which notebook we are working with
42+
# though we might not be working with a notebook, we could be working with a
43+
# markdown file, or python file.
44+
# as with other Jupyter Related Env variable with use the JPY prefix.
45+
JPY_KERNEL_SESSION_NAME = 'JPY_SESSION_NAME'
46+
47+
3748
class _ShutdownStatus(Enum):
3849
"""
3950
@@ -332,6 +343,7 @@ async def _async_start_kernel(self, **kw):
332343

333344
# launch the kernel subprocess
334345
self.log.debug("Starting kernel: %s", kernel_cmd)
346+
kw.pop('session_name', None)
335347
await ensure_async(self._launch_kernel(kernel_cmd, **kw))
336348
await ensure_async(self.post_start_kernel(**kw))
337349

jupyter_client/multikernelmanager.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ def pre_start_kernel(
151151
constructor_kwargs = {}
152152
if self.kernel_spec_manager:
153153
constructor_kwargs["kernel_spec_manager"] = self.kernel_spec_manager
154+
155+
if 'session_name' in kwargs:
156+
constructor_kwargs['session_name'] = kwargs.copy().pop('session_name')
154157
km = self.kernel_manager_factory(
155158
connection_file=os.path.join(self.connection_dir, "kernel-%s.json" % kernel_id),
156159
parent=self,

jupyter_client/provisioning/local_provisioner.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ async def pre_launch(self, **kwargs: Any) -> Dict[str, Any]:
139139

140140
# This should be considered temporary until a better division of labor can be defined.
141141
km = self.parent
142+
extra_arguments = kwargs.pop('extra_arguments', [])
142143
if km:
143144
if km.transport == 'tcp' and not is_local_ip(km.ip):
144145
raise RuntimeError(
@@ -149,7 +150,6 @@ async def pre_launch(self, **kwargs: Any) -> Dict[str, Any]:
149150
"Currently valid addresses are: %s" % (km.ip, local_ips())
150151
)
151152
# build the Popen cmd
152-
extra_arguments = kwargs.pop('extra_arguments', [])
153153

154154
# write connection file / get default ports
155155
# TODO - change when handshake pattern is adopted
@@ -169,7 +169,6 @@ async def pre_launch(self, **kwargs: Any) -> Dict[str, Any]:
169169
extra_arguments=extra_arguments
170170
) # This needs to remain here for b/c
171171
else:
172-
extra_arguments = kwargs.pop('extra_arguments', [])
173172
kernel_cmd = self.kernel_spec.argv + extra_arguments
174173

175174
return await super().pre_launch(cmd=kernel_cmd, **kwargs)

jupyter_client/provisioning/provisioner_base.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@
1616

1717
from ..connect import KernelConnectionInfo
1818

19+
# Name of the env variable that contains the name of the current session associated
20+
# with the kernel we are launching.
21+
# Frontends can decide to set this session name to the name of the file when
22+
# when the kernel is started.
23+
# This is useful in notebook context to find which notebook we are working with
24+
# though we might not be working with a notebook, we could be working with a
25+
# markdown file, or python file.
26+
# as with other Jupyter Related Env variable with use the JPY prefix.
27+
JPY_SESSION_NAME = 'JPY_SESSION_NAME'
28+
1929

2030
class KernelProvisionerMeta(ABCMeta, type(LoggingConfigurable)): # type: ignore
2131
pass
@@ -160,6 +170,8 @@ async def pre_launch(self, **kwargs: Any) -> Dict[str, Any]:
160170
:meth:`launch_kernel()`.
161171
"""
162172
env = kwargs.pop('env', os.environ).copy()
173+
if 'session_name' in kwargs:
174+
env.update({JPY_SESSION_NAME: kwargs['session_name']})
163175
env.update(self.__apply_env_substitutions(env))
164176
self._finalize_env(env)
165177
kwargs['env'] = env

0 commit comments

Comments
 (0)