Skip to content

Commit 59eb011

Browse files
committed
Make ServerKernelManager client traits configurable
Add config=True to client_class and client_factory traits in ServerKernelManager to enable configuration of kernel client classes through configuration files and command line arguments. This enables custom kernel clients to be used for intercepting and routing messages, which is required for server-side document handling. - Override client_class and client_factory traits with config=True - Add comprehensive unit tests for configuration via command line and Config object - Move all imports to top of test file for better organization
1 parent 8f99062 commit 59eb011

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

jupyter_server/services/kernels/kernelmanager.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@
3737
Any,
3838
Bool,
3939
Dict,
40+
DottedObjectName,
4041
Float,
4142
Instance,
4243
Integer,
4344
List,
4445
TraitError,
46+
Type,
4547
Unicode,
4648
default,
4749
validate,
@@ -845,6 +847,29 @@ async def wrapped_method(self, *args, **kwargs):
845847
class ServerKernelManager(AsyncIOLoopKernelManager):
846848
"""A server-specific kernel manager."""
847849

850+
# Override parent traits to make them configurable
851+
client_class = DottedObjectName(
852+
"jupyter_client.asynchronous.AsyncKernelClient",
853+
config=True,
854+
help="""The kernel client class to use for communicating with kernels.
855+
856+
This should be a subclass of KernelClient, and it should accept the
857+
following arguments:
858+
- kernel_manager
859+
- blocking
860+
- loop
861+
"""
862+
)
863+
864+
client_factory = Type(
865+
klass="jupyter_client.KernelClient",
866+
config=True,
867+
help="""The kernel client factory class to use for creating client instances.
868+
869+
This should be a subclass of KernelClient.
870+
"""
871+
)
872+
848873
# Define activity-related attributes:
849874
execution_state = Unicode(
850875
None, allow_none=True, help="The current execution state of the kernel"

tests/services/kernels/test_config.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import pytest
22
from traitlets.config import Config
33

4-
from jupyter_server.services.kernels.kernelmanager import AsyncMappingKernelManager
4+
from jupyter_client.blocking.client import BlockingKernelClient
5+
from jupyter_server.services.kernels.kernelmanager import AsyncMappingKernelManager, ServerKernelManager
6+
from jupyter_server.utils import import_item
57

68

79
@pytest.fixture
@@ -29,3 +31,40 @@ def test_not_server_kernel_manager(jp_configurable_serverapp):
2931
]
3032
with pytest.warns(FutureWarning, match="is not a subclass of 'ServerKernelManager'"):
3133
jp_configurable_serverapp(argv=argv)
34+
35+
36+
def test_server_kernel_manager_client_class_configurable(jp_configurable_serverapp):
37+
"""Test that ServerKernelManager client_class trait is configurable."""
38+
argv = [
39+
"--AsyncMappingKernelManager.client_class=jupyter_client.asynchronous.AsyncKernelClient"
40+
]
41+
app = jp_configurable_serverapp(argv=argv)
42+
# Get a kernel manager instance to check the configuration
43+
kernel_manager_class = app.kernel_manager.kernel_manager_class
44+
km_class = import_item(kernel_manager_class)
45+
km_instance = km_class()
46+
assert km_instance.client_class == "jupyter_client.asynchronous.AsyncKernelClient"
47+
48+
49+
def test_server_kernel_manager_client_factory_configurable(jp_configurable_serverapp):
50+
"""Test that ServerKernelManager client_factory trait is configurable."""
51+
argv = [
52+
"--AsyncMappingKernelManager.client_factory=jupyter_client.blocking.client.BlockingKernelClient"
53+
]
54+
app = jp_configurable_serverapp(argv=argv)
55+
# Get a kernel manager instance to check the configuration
56+
kernel_manager_class = app.kernel_manager.kernel_manager_class
57+
km_class = import_item(kernel_manager_class)
58+
km_instance = km_class()
59+
assert km_instance.client_factory == BlockingKernelClient
60+
61+
62+
def test_server_kernel_manager_client_traits_via_config():
63+
"""Test that ServerKernelManager client traits can be configured via Config object."""
64+
config = Config()
65+
config.ServerKernelManager.client_class = "jupyter_client.blocking.client.BlockingKernelClient"
66+
config.ServerKernelManager.client_factory = BlockingKernelClient
67+
68+
km = ServerKernelManager(config=config)
69+
assert km.client_class == "jupyter_client.blocking.client.BlockingKernelClient"
70+
assert km.client_factory == BlockingKernelClient

0 commit comments

Comments
 (0)