33""" 
44
55import  sys 
6+ from  textwrap  import  dedent , indent 
67from  warnings  import  warn 
78
89if  sys .version_info  <  (3 , 10 ):  # pragma: no cover 
@@ -344,6 +345,16 @@ def make_server_process(name, server_process_config, serverproxy_config):
344345    return  ServerProcess (name = name , ** server_process_config )
345346
346347
348+ def  _serverproxy_servers_help ():
349+     serverprocess_help  =  "" 
350+     for  k , v  in  ServerProcess .class_traits ().items ():
351+         help  =  v .metadata .get ("help" , "" ).lstrip ("\n " ).rstrip ()
352+         if  help :
353+             help  =  indent (dedent (help ), "    " )
354+             serverprocess_help  +=  f"{ k } \n { help } \n \n " 
355+     return  serverprocess_help 
356+ 
357+ 
347358class  ServerProxy (Configurable ):
348359    servers  =  Dict (
349360        {},
@@ -354,123 +365,9 @@ class ServerProxy(Configurable):
354365        the URL prefix, and all requests matching this prefix are routed to this process. 
355366
356367        Value should be a dictionary with the following keys: 
357-           command 
358-             An optional list of strings that should be the full command to be executed. 
359-             The optional template arguments {{port}}, {{unix_socket}} and {{base_url}} 
360-             will be substituted with the port or Unix socket path the process should 
361-             listen on and the base-url of the notebook. 
362- 
363-             Could also be a callable. It should return a list. 
364- 
365-             If the command is not specified or is an empty list, the server 
366-             process is assumed to be started ahead of time and already available 
367-             to be proxied to. 
368- 
369-           environment 
370-             A dictionary of environment variable mappings. As with the command 
371-             traitlet, {{port}}, {{unix_socket}} and {{base_url}} will be substituted. 
372- 
373-             Could also be a callable. It should return a dictionary. 
374- 
375-           timeout 
376-             Timeout in seconds for the process to become ready, default 5s. 
377- 
378-           absolute_url 
379-             Proxy requests default to being rewritten to '/'. If this is True, 
380-             the absolute URL will be sent to the backend instead. 
381- 
382-           port 
383-             Set the port that the service will listen on. The default is to automatically select an unused port. 
384- 
385-           unix_socket 
386-             If set, the service will listen on a Unix socket instead of a TCP port. 
387-             Set to True to use a socket in a new temporary folder, or a string 
388-             path to a socket. This overrides port. 
389- 
390-             Proxying websockets over a Unix socket requires Tornado >= 6.3. 
391- 
392-           mappath 
393-             Map request paths to proxied paths. 
394-             Either a dictionary of request paths to proxied paths, 
395-             or a callable that takes parameter ``path`` and returns the proxied path. 
396- 
397-           launcher_entry 
398-             A dictionary of various options for entries in classic notebook / jupyterlab launchers. 
399- 
400-             Keys recognized are: 
401- 
402-               enabled 
403-                 Set to True (default) to make an entry in the launchers. Set to False to have no 
404-                 explicit entry. 
405- 
406-               icon_path 
407-                 Full path to an svg icon that could be used with a launcher. Currently only used by the 
408-                 JupyterLab launcher 
409368
410-               title 
411-                 Title to be used for the launcher entry. Defaults to the name of the server if missing. 
412- 
413-               path_info 
414-                 The trailing path that is appended to the user's server URL to access the proxied server. 
415-                 By default it is the name of the server followed by a trailing slash. 
416- 
417-               category 
418-                 The category for the launcher item. Currently only used by the JupyterLab launcher. 
419-                 By default it is "Notebook". 
420- 
421-           new_browser_tab 
422-             Set to True (default) to make the proxied server interface opened as a new browser tab. Set to False 
423-             to have it open a new JupyterLab tab. This has no effect in classic notebook. 
424- 
425-           request_headers_override 
426-             A dictionary of additional HTTP headers for the proxy request. As with 
427-             the command traitlet, {{port}}, {{unix_socket}} and {{base_url}} will be substituted. 
428- 
429-           rewrite_response 
430-             An optional function to rewrite the response for the given service. 
431-             Input is a RewritableResponse object which is an argument that MUST be named 
432-             ``response``. The function should modify one or more of the attributes 
433-             ``.body``, ``.headers``, ``.code``, or ``.reason`` of the ``response`` 
434-             argument. For example: 
435- 
436-                 def dog_to_cat(response): 
437-                     response.headers["I-Like"] = "tacos" 
438-                     response.body = response.body.replace(b'dog', b'cat') 
439- 
440-                 c.ServerProxy.servers['my_server']['rewrite_response'] = dog_to_cat 
441- 
442-             The ``rewrite_response`` function can also accept several optional 
443-             positional arguments. Arguments named ``host``, ``port``, and ``path`` will 
444-             receive values corresponding to the URL ``/proxy/<host>:<port><path>``. In 
445-             addition, the original Tornado ``HTTPRequest`` and ``HTTPResponse`` objects 
446-             are available as arguments named ``request`` and ``orig_response``. (These 
447-             objects should not be modified.) 
448- 
449-             A list or tuple of functions can also be specified for chaining multiple 
450-             rewrites. For example: 
451- 
452-                 def cats_only(response, path): 
453-                     if path.startswith("/cat-club"): 
454-                         response.code = 403 
455-                         response.body = b"dogs not allowed" 
456- 
457-                 c.ServerProxy.servers['my_server']['rewrite_response'] = [dog_to_cat, cats_only] 
458- 
459-             Note that if the order is reversed to ``[cats_only, dog_to_cat]``, then accessing 
460-             ``/cat-club`` will produce a "403 Forbidden" response with body "cats not allowed" 
461-             instead of "dogs not allowed". 
462- 
463-             Defaults to the empty tuple ``tuple()``. 
464-   
465-           update_last_activity 
466-             Will cause the proxy to report activity back to jupyter server. 
467- 
468-           raw_socket_proxy 
469-             Proxy websocket requests as a raw TCP (or unix socket) stream. 
470-             In this mode, only websockets are handled, and messages are sent to the backend, 
471-             similar to running a websockify layer (https://github.com/novnc/websockify). 
472-             All other HTTP requests return 405 (and thus this will also bypass rewrite_response). 
473-         """ ,
369+         """ 
370+         +  indent (_serverproxy_servers_help (), "        " ),
474371        config = True ,
475372    )
476373
0 commit comments