Skip to content

Commit e07a615

Browse files
committed
Allow configuration via traitlets
1 parent 1ff6051 commit e07a615

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

docs/source/standalone.md

+23
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,29 @@ not trigger the login process when accessing the application.
5858
especially on multi-user systems.
5959
```
6060

61+
### Configuration via traitlets
62+
63+
Instead of using the commandline, a standalone proxy can also be configured via a `traitlets` configuration file.
64+
The configuration file can be loaded by running `jupyter standaloneproxy --config path/to/config.py`.
65+
66+
The options mentioned above can also be configured in the config file:
67+
68+
```python
69+
# Specify the command to execute
70+
c.StandaloneProxyServer.command = [
71+
"voila", "--no-browser", "--port={port}", "/path/to/some/Notebook.ipynb"
72+
]
73+
74+
# Specify address and port
75+
c.StandaloneProxyServer.address = "localhost"
76+
c.StandaloneProxyServer.port = 8000
77+
78+
# Disable authentication
79+
c.StandaloneProxyServer.skip_authentication = True
80+
```
81+
82+
A default config file can be emitted by running `jupyter standaloneproxy --generate-config`
83+
6184
## Usage with JupyterHub
6285

6386
To launch a standalone proxy with JupyterHub, you need to customize the `Spawner` inside the configuration

jupyter_server_proxy/standalone/app.py

+17-7
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,29 @@
77
from textwrap import dedent
88
from urllib.parse import urlparse
99

10+
from jupyter_core.application import JupyterApp
1011
from jupyterhub.services.auth import HubOAuthCallbackHandler
1112
from jupyterhub.utils import make_ssl_context
1213
from tornado import httpclient, httpserver, ioloop, web
1314
from tornado.web import RedirectHandler
14-
from traitlets.config import Application as TraitletsApplication
1515
from traitlets.traitlets import Bool, Int, Unicode, default, validate
1616

1717
from ..config import ServerProcess
1818
from .activity import start_activity_update
1919
from .proxy import make_standalone_proxy
2020

2121

22-
class StandaloneProxyServer(TraitletsApplication, ServerProcess):
22+
class StandaloneProxyServer(JupyterApp, ServerProcess):
2323
name = "jupyter-standalone-proxy"
2424
description = """
2525
Wrap an arbitrary web service so it can be used in place of 'jupyterhub-singleuser'
2626
in a JupyterHub setting.
2727
2828
Usage: jupyter standaloneproxy [options] -- <command>
2929
30-
The <command> will be executed to start the web service once the proxy receives the first request. The command can
31-
contain the placeholders '{{port}}', '{{unix_socket}}' and '{{base_url}}', which will be replaced with the
32-
appropriate values once the application starts.
33-
3430
For more details, see the jupyter-server-proxy documentation.
3531
"""
32+
examples = "jupyter standaloneproxy -- voila --port={port} --no-browser /path/to/notebook.ipynb"
3633

3734
base_url = Unicode(
3835
help="""
@@ -152,19 +149,21 @@ def __init__(self, **kwargs):
152149
# exeptions we do not need, for easier use of the CLI
153150
# We don't need "command" here, as we will take it from the extra_args
154151
ignore_traits = [
152+
"name",
155153
"launcher_entry",
156154
"new_browser_tab",
157155
"rewrite_response",
158156
"update_last_activity",
159157
"command",
160158
]
161159
server_process_aliases = {
162-
trait: f"ServerProcess.{trait}"
160+
trait: f"StandaloneProxyServer.{trait}"
163161
for trait in ServerProcess.class_traits(config=True)
164162
if trait not in ignore_traits and trait not in self.flags
165163
}
166164

167165
self.aliases = {
166+
**super().aliases,
168167
**server_process_aliases,
169168
"base_url": "StandaloneProxyServer.base_url",
170169
"address": "StandaloneProxyServer.address",
@@ -174,6 +173,17 @@ def __init__(self, **kwargs):
174173
"websocket_max_message_size": "StandaloneProxyServer.websocket_max_message_size",
175174
}
176175

176+
def emit_alias_help(self):
177+
yield from super().emit_alias_help()
178+
yield ""
179+
180+
# Manually yield the help for command, which we will get from extra_args
181+
command_help = StandaloneProxyServer.class_get_trait_help(
182+
ServerProcess.command
183+
).split("\n")
184+
yield command_help[0].replace("--StandaloneProxyServer.command", "command")
185+
yield from command_help[1:]
186+
177187
def get_proxy_base_class(self) -> tuple[type | None, dict]:
178188
cls, kwargs = super().get_proxy_base_class()
179189
if cls is None:

0 commit comments

Comments
 (0)