1919 Callable ,
2020 Dict ,
2121 Float ,
22+ HasTraits ,
2223 Instance ,
2324 Int ,
2425 List ,
3536from .rawsocket import RawSocketHandler , SuperviseAndRawSocketHandler
3637
3738
38- class LauncherEntry (Configurable ):
39+ class LauncherEntry (HasTraits ):
3940 enabled = Bool (
4041 True ,
4142 help = """
@@ -76,7 +77,7 @@ class LauncherEntry(Configurable):
7677
7778
7879class ServerProcess (Configurable ):
79- name = Unicode (help = "Name of the server" ). tag ( config = True )
80+ name = Unicode (help = "Name of the server" )
8081
8182 command = Union (
8283 [List (Unicode ()), Callable ()],
@@ -92,7 +93,7 @@ class ServerProcess(Configurable):
9293 process is assumed to be started ahead of time and already available
9394 to be proxied to.
9495 """ ,
95- ). tag ( config = True )
96+ )
9697
9798 environment = Union (
9899 [Dict (Unicode ()), Callable ()],
@@ -115,14 +116,14 @@ class ServerProcess(Configurable):
115116 Proxy requests default to being rewritten to ``/``. If this is True,
116117 the absolute URL will be sent to the backend instead.
117118 """ ,
118- ). tag ( config = True )
119+ )
119120
120121 port = Int (
121122 0 ,
122123 help = """
123124 Set the port that the service will listen on. The default is to automatically select an unused port.
124125 """ ,
125- ). tag ( config = True )
126+ )
126127
127128 unix_socket = Union (
128129 [Bool (False ), Unicode ()],
@@ -135,7 +136,7 @@ class ServerProcess(Configurable):
135136
136137 Proxying websockets over a Unix socket requires Tornado >= 6.3.
137138 """ ,
138- ). tag ( config = True )
139+ )
139140
140141 mappath = Union (
141142 [Dict (Unicode ()), Callable ()],
@@ -145,15 +146,15 @@ class ServerProcess(Configurable):
145146 Either a dictionary of request paths to proxied paths,
146147 or a callable that takes parameter ``path`` and returns the proxied path.
147148 """ ,
148- ). tag ( config = True )
149+ )
149150
150151 launcher_entry = Union (
151152 [Instance (LauncherEntry ), Dict ()],
152153 allow_none = False ,
153154 help = """
154- A dictionary of various options for entries in classic notebook / jupyterlab launchers.
155+ Specify various options for entries in classic notebook / jupyterlab launchers.
155156
156- Keys recognized are :
157+ Must be an instance of ``LauncherEntry`` or a dictionary with the following keys :
157158
158159 ``enabled``
159160 Set to True (default) to make an entry in the launchers. Set to False to have no
@@ -174,13 +175,18 @@ class ServerProcess(Configurable):
174175 The category for the launcher item. Currently only used by the JupyterLab launcher.
175176 By default it is "Notebook".
176177 """ ,
177- ). tag ( config = True )
178+ )
178179
179180 @validate ("launcher_entry" )
180181 def _validate_launcher_entry (self , proposal ):
181- kwargs = {"title" : self .name , "path_info" : self .name + "/" }
182- kwargs .update (proposal ["value" ])
183- return LauncherEntry (** kwargs )
182+ if isinstance (proposal ["value" ], LauncherEntry ):
183+ proposal ["value" ].title = self .name
184+ proposal ["value" ].path_info = self .name + "/"
185+ return proposal ["value" ]
186+ else :
187+ kwargs = {"title" : self .name , "path_info" : self .name + "/" }
188+ kwargs .update (proposal ["value" ])
189+ return LauncherEntry (** kwargs )
184190
185191 @default ("launcher_entry" )
186192 def _default_launcher_entry (self ):
@@ -201,7 +207,7 @@ def _default_launcher_entry(self):
201207 A dictionary of additional HTTP headers for the proxy request. As with
202208 the command traitlet, ``{port}``, ``{unix_socket}`` and ``{base_url}`` will be substituted.
203209 """ ,
204- ). tag ( config = True )
210+ )
205211
206212 rewrite_response = Union (
207213 [Callable (), List (Callable ())],
@@ -250,7 +256,7 @@ def cats_only(response, path):
250256
251257 update_last_activity = Bool (
252258 True , help = "Will cause the proxy to report activity back to jupyter server."
253- ). tag ( config = True )
259+ )
254260
255261 raw_socket_proxy = Bool (
256262 False ,
@@ -260,7 +266,7 @@ def cats_only(response, path):
260266 similar to running a websockify layer (https://github.com/novnc/websockify).
261267 All other HTTP requests return 405 (and thus this will also bypass rewrite_response).
262268 """ ,
263- ). tag ( config = True )
269+ )
264270
265271 def get_proxy_base_class (self ) -> tuple [type | None , dict ]:
266272 """
@@ -341,17 +347,17 @@ def get_timeout(self):
341347 return _Proxy , proxy_kwargs
342348
343349
344- def get_entrypoint_server_processes (serverproxy_config ):
345- sps = []
350+ def get_entrypoint_server_processes ():
351+ processes = []
346352 for entry_point in entry_points (group = "jupyter_serverproxy_servers" ):
347353 name = entry_point .name
348354 try :
349355 server_process_config = entry_point .load ()()
350356 except Exception as e :
351357 warn (f"entry_point { name } was unable to be loaded: { str (e )} " )
352358 continue
353- sps .append (make_server_process (name , server_process_config , serverproxy_config ))
354- return sps
359+ processes .append (ServerProcess (name = name , ** server_process_config ))
360+ return processes
355361
356362
357363def make_handlers (base_url : str , server_processes : list [ServerProcess ]):
@@ -384,20 +390,36 @@ def _serverproxy_servers_help():
384390
385391class ServerProxy (Configurable ):
386392 servers = Dict (
387- {},
393+ key_trait = Unicode (),
394+ value_trait = Union ([Dict (), Instance (ServerProcess )]),
388395 help = """
389396 Dictionary of processes to supervise & proxy.
390397
391398 Key should be the name of the process. This is also used by default as
392399 the URL prefix, and all requests matching this prefix are routed to this process.
393400
394- Value should be a dictionary with the following keys:
401+ Value should be an instance of ``ServerProcess`` or a dictionary with the following keys:
395402
396403 """
397404 + indent (_serverproxy_servers_help (), " " ),
398405 config = True ,
399406 )
400407
408+ @validate ("servers" )
409+ def _validate_servers (self , proposal ):
410+ servers = {}
411+
412+ for name , server_process in proposal ["value" ].items ():
413+ if isinstance (server_process , ServerProcess ):
414+ server_process .name = server_process .name or name
415+ servers [name ] = server_process
416+ else :
417+ kwargs = {"name" : name }
418+ kwargs .update (** server_process )
419+ servers [name ] = ServerProcess (** kwargs )
420+
421+ return servers
422+
401423 non_service_rewrite_response = Union (
402424 default_value = tuple (),
403425 trait_types = [List (), Tuple (), Callable ()],
0 commit comments