Skip to content

Commit 0364664

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. Changes: - Override client_class and client_factory traits with config=True - Use correct default values matching parent class behavior - Add comprehensive unit tests for configuration via Config objects - Test default values, string configuration, and factory configuration - Import AsyncKernelClient directly instead of using import_item All tests pass and maintain backward compatibility while enabling the configurable functionality needed for jupyter-server-documents project.
1 parent 8f99062 commit 0364664

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

jupyter_server/services/kernels/kernelmanager.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from datetime import datetime, timedelta
1919
from functools import partial, wraps
2020

21+
from jupyter_client.asynchronous.client import AsyncKernelClient
2122
from jupyter_client.ioloop.manager import AsyncIOLoopKernelManager
2223
from jupyter_client.multikernelmanager import AsyncMultiKernelManager, MultiKernelManager
2324
from jupyter_client.session import Session
@@ -37,11 +38,13 @@
3738
Any,
3839
Bool,
3940
Dict,
41+
DottedObjectName,
4042
Float,
4143
Instance,
4244
Integer,
4345
List,
4446
TraitError,
47+
Type,
4548
Unicode,
4649
default,
4750
validate,
@@ -845,6 +848,30 @@ async def wrapped_method(self, *args, **kwargs):
845848
class ServerKernelManager(AsyncIOLoopKernelManager):
846849
"""A server-specific kernel manager."""
847850

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

tests/services/kernels/test_config.py

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

4-
from jupyter_server.services.kernels.kernelmanager import AsyncMappingKernelManager
4+
from jupyter_client.asynchronous.client import AsyncKernelClient
5+
from jupyter_client.blocking.client import BlockingKernelClient
6+
from jupyter_client.client import KernelClient
7+
from jupyter_server.services.kernels.kernelmanager import AsyncMappingKernelManager, ServerKernelManager
8+
from jupyter_server.utils import import_item
59

610

711
@pytest.fixture
@@ -29,3 +33,31 @@ def test_not_server_kernel_manager(jp_configurable_serverapp):
2933
]
3034
with pytest.warns(FutureWarning, match="is not a subclass of 'ServerKernelManager'"):
3135
jp_configurable_serverapp(argv=argv)
36+
37+
38+
def test_server_kernel_manager_client_traits_via_config():
39+
"""Test that ServerKernelManager client traits can be configured via Config object."""
40+
config = Config()
41+
config.ServerKernelManager.client_class = "jupyter_client.blocking.client.BlockingKernelClient"
42+
config.ServerKernelManager.client_factory = BlockingKernelClient
43+
44+
km = ServerKernelManager(config=config)
45+
assert km.client_class == "jupyter_client.blocking.client.BlockingKernelClient"
46+
assert km.client_factory == BlockingKernelClient
47+
48+
49+
def test_server_kernel_manager_client_traits_default_values():
50+
"""Test that ServerKernelManager client traits have correct default values."""
51+
km = ServerKernelManager()
52+
assert km.client_class == "jupyter_client.asynchronous.AsyncKernelClient"
53+
# Default client_factory should be the AsyncKernelClient class
54+
assert km.client_factory == AsyncKernelClient
55+
56+
57+
def test_server_kernel_manager_client_class_string_configuration():
58+
"""Test that client_class can be configured with different string values."""
59+
config = Config()
60+
config.ServerKernelManager.client_class = "jupyter_client.client.KernelClient"
61+
62+
km = ServerKernelManager(config=config)
63+
assert km.client_class == "jupyter_client.client.KernelClient"

0 commit comments

Comments
 (0)