19
19
Callable ,
20
20
Dict ,
21
21
Float ,
22
+ HasTraits ,
22
23
Instance ,
23
24
Int ,
24
25
List ,
35
36
from .rawsocket import RawSocketHandler , SuperviseAndRawSocketHandler
36
37
37
38
38
- class LauncherEntry (Configurable ):
39
+ class LauncherEntry (HasTraits ):
39
40
enabled = Bool (
40
41
True ,
41
42
help = """
@@ -76,7 +77,7 @@ class LauncherEntry(Configurable):
76
77
77
78
78
79
class ServerProcess (Configurable ):
79
- name = Unicode (help = "Name of the server" ). tag ( config = True )
80
+ name = Unicode (help = "Name of the server" )
80
81
81
82
command = Union (
82
83
[List (Unicode ()), Callable ()],
@@ -92,7 +93,7 @@ class ServerProcess(Configurable):
92
93
process is assumed to be started ahead of time and already available
93
94
to be proxied to.
94
95
""" ,
95
- ). tag ( config = True )
96
+ )
96
97
97
98
environment = Union (
98
99
[Dict (Unicode ()), Callable ()],
@@ -115,14 +116,14 @@ class ServerProcess(Configurable):
115
116
Proxy requests default to being rewritten to ``/``. If this is True,
116
117
the absolute URL will be sent to the backend instead.
117
118
""" ,
118
- ). tag ( config = True )
119
+ )
119
120
120
121
port = Int (
121
122
0 ,
122
123
help = """
123
124
Set the port that the service will listen on. The default is to automatically select an unused port.
124
125
""" ,
125
- ). tag ( config = True )
126
+ )
126
127
127
128
unix_socket = Union (
128
129
[Bool (False ), Unicode ()],
@@ -135,7 +136,7 @@ class ServerProcess(Configurable):
135
136
136
137
Proxying websockets over a Unix socket requires Tornado >= 6.3.
137
138
""" ,
138
- ). tag ( config = True )
139
+ )
139
140
140
141
mappath = Union (
141
142
[Dict (Unicode ()), Callable ()],
@@ -145,15 +146,15 @@ class ServerProcess(Configurable):
145
146
Either a dictionary of request paths to proxied paths,
146
147
or a callable that takes parameter ``path`` and returns the proxied path.
147
148
""" ,
148
- ). tag ( config = True )
149
+ )
149
150
150
151
launcher_entry = Union (
151
152
[Instance (LauncherEntry ), Dict ()],
152
153
allow_none = False ,
153
154
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.
155
156
156
- Keys recognized are :
157
+ Must be an instance of ``LauncherEntry`` or a dictionary with the following keys :
157
158
158
159
``enabled``
159
160
Set to True (default) to make an entry in the launchers. Set to False to have no
@@ -174,13 +175,18 @@ class ServerProcess(Configurable):
174
175
The category for the launcher item. Currently only used by the JupyterLab launcher.
175
176
By default it is "Notebook".
176
177
""" ,
177
- ). tag ( config = True )
178
+ )
178
179
179
180
@validate ("launcher_entry" )
180
181
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 )
184
190
185
191
@default ("launcher_entry" )
186
192
def _default_launcher_entry (self ):
@@ -201,7 +207,7 @@ def _default_launcher_entry(self):
201
207
A dictionary of additional HTTP headers for the proxy request. As with
202
208
the command traitlet, ``{port}``, ``{unix_socket}`` and ``{base_url}`` will be substituted.
203
209
""" ,
204
- ). tag ( config = True )
210
+ )
205
211
206
212
rewrite_response = Union (
207
213
[Callable (), List (Callable ())],
@@ -250,7 +256,7 @@ def cats_only(response, path):
250
256
251
257
update_last_activity = Bool (
252
258
True , help = "Will cause the proxy to report activity back to jupyter server."
253
- ). tag ( config = True )
259
+ )
254
260
255
261
raw_socket_proxy = Bool (
256
262
False ,
@@ -260,7 +266,7 @@ def cats_only(response, path):
260
266
similar to running a websockify layer (https://github.com/novnc/websockify).
261
267
All other HTTP requests return 405 (and thus this will also bypass rewrite_response).
262
268
""" ,
263
- ). tag ( config = True )
269
+ )
264
270
265
271
def get_proxy_base_class (self ) -> tuple [type | None , dict ]:
266
272
"""
@@ -341,17 +347,17 @@ def get_timeout(self):
341
347
return _Proxy , proxy_kwargs
342
348
343
349
344
- def get_entrypoint_server_processes (serverproxy_config ):
345
- sps = []
350
+ def get_entrypoint_server_processes ():
351
+ processes = []
346
352
for entry_point in entry_points (group = "jupyter_serverproxy_servers" ):
347
353
name = entry_point .name
348
354
try :
349
355
server_process_config = entry_point .load ()()
350
356
except Exception as e :
351
357
warn (f"entry_point { name } was unable to be loaded: { str (e )} " )
352
358
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
355
361
356
362
357
363
def make_handlers (base_url : str , server_processes : list [ServerProcess ]):
@@ -384,20 +390,36 @@ def _serverproxy_servers_help():
384
390
385
391
class ServerProxy (Configurable ):
386
392
servers = Dict (
387
- {},
393
+ key_trait = Unicode (),
394
+ value_trait = Union ([Dict (), Instance (ServerProcess )]),
388
395
help = """
389
396
Dictionary of processes to supervise & proxy.
390
397
391
398
Key should be the name of the process. This is also used by default as
392
399
the URL prefix, and all requests matching this prefix are routed to this process.
393
400
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:
395
402
396
403
"""
397
404
+ indent (_serverproxy_servers_help (), " " ),
398
405
config = True ,
399
406
)
400
407
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
+
401
423
non_service_rewrite_response = Union (
402
424
default_value = tuple (),
403
425
trait_types = [List (), Tuple (), Callable ()],
0 commit comments