mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-17 15:03:02 +00:00
add command traitlet
allows specifying commands as either strings or list. This enables adding arguments to JupyterHub.proxy_cmd without breaking backward-compatibility.
This commit is contained in:
@@ -50,7 +50,7 @@ from .handlers.static import CacheControlStaticFilesHandler
|
|||||||
from . import orm
|
from . import orm
|
||||||
from ._data import DATA_FILES_PATH
|
from ._data import DATA_FILES_PATH
|
||||||
from .log import CoroutineLogFormatter, log_request
|
from .log import CoroutineLogFormatter, log_request
|
||||||
from .traitlets import URLPrefix
|
from .traitlets import URLPrefix, Command
|
||||||
from .utils import (
|
from .utils import (
|
||||||
url_path_join,
|
url_path_join,
|
||||||
ISO8601_ms, ISO8601_s,
|
ISO8601_ms, ISO8601_s,
|
||||||
@@ -237,7 +237,7 @@ class JupyterHub(Application):
|
|||||||
help="Supply extra arguments that will be passed to Jinja environment."
|
help="Supply extra arguments that will be passed to Jinja environment."
|
||||||
)
|
)
|
||||||
|
|
||||||
proxy_cmd = Unicode('configurable-http-proxy', config=True,
|
proxy_cmd = Command('configurable-http-proxy', config=True,
|
||||||
help="""The command to start the http proxy.
|
help="""The command to start the http proxy.
|
||||||
|
|
||||||
Only override if configurable-http-proxy is not on your PATH
|
Only override if configurable-http-proxy is not on your PATH
|
||||||
@@ -742,7 +742,7 @@ class JupyterHub(Application):
|
|||||||
|
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
env['CONFIGPROXY_AUTH_TOKEN'] = self.proxy.auth_token
|
env['CONFIGPROXY_AUTH_TOKEN'] = self.proxy.auth_token
|
||||||
cmd = [self.proxy_cmd,
|
cmd = self.proxy_cmd + [
|
||||||
'--ip', self.proxy.public_server.ip,
|
'--ip', self.proxy.public_server.ip,
|
||||||
'--port', str(self.proxy.public_server.port),
|
'--port', str(self.proxy.public_server.port),
|
||||||
'--api-ip', self.proxy.api_server.ip,
|
'--api-ip', self.proxy.api_server.ip,
|
||||||
|
@@ -21,6 +21,7 @@ from IPython.utils.traitlets import (
|
|||||||
Any, Bool, Dict, Enum, Instance, Integer, Float, List, Unicode,
|
Any, Bool, Dict, Enum, Instance, Integer, Float, List, Unicode,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from .traitlets import Command
|
||||||
from .utils import random_port
|
from .utils import random_port
|
||||||
|
|
||||||
NUM_PAT = re.compile(r'\d+')
|
NUM_PAT = re.compile(r'\d+')
|
||||||
@@ -93,7 +94,7 @@ class Spawner(LoggingConfigurable):
|
|||||||
env['JPY_API_TOKEN'] = self.api_token
|
env['JPY_API_TOKEN'] = self.api_token
|
||||||
return env
|
return env
|
||||||
|
|
||||||
cmd = List(Unicode, default_value=['jupyterhub-singleuser'], config=True,
|
cmd = Command(['jupyterhub-singleuser'], config=True,
|
||||||
help="""The command used for starting notebooks."""
|
help="""The command used for starting notebooks."""
|
||||||
)
|
)
|
||||||
args = List(Unicode, config=True,
|
args = List(Unicode, config=True,
|
||||||
|
26
jupyterhub/tests/test_traitlets.py
Normal file
26
jupyterhub/tests/test_traitlets.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
from traitlets import HasTraits
|
||||||
|
from jupyterhub.traitlets import URLPrefix, Command
|
||||||
|
|
||||||
|
def test_url_prefix():
|
||||||
|
class C(HasTraits):
|
||||||
|
url = URLPrefix()
|
||||||
|
|
||||||
|
c = C()
|
||||||
|
c.url = '/a/b/c/'
|
||||||
|
assert c.url == '/a/b/c/'
|
||||||
|
c.url = '/a/b'
|
||||||
|
assert c.url == '/a/b/'
|
||||||
|
c.url = 'a/b/c/d'
|
||||||
|
assert c.url == '/a/b/c/d/'
|
||||||
|
|
||||||
|
def test_command():
|
||||||
|
class C(HasTraits):
|
||||||
|
cmd = Command('default command')
|
||||||
|
cmd2 = Command(['default_cmd'])
|
||||||
|
|
||||||
|
c = C()
|
||||||
|
assert c.cmd == ['default command']
|
||||||
|
assert c.cmd2 == ['default_cmd']
|
||||||
|
c.cmd = 'foo bar'
|
||||||
|
assert c.cmd == ['foo bar']
|
||||||
|
|
@@ -2,7 +2,7 @@
|
|||||||
# Copyright (c) Jupyter Development Team.
|
# Copyright (c) Jupyter Development Team.
|
||||||
# Distributed under the terms of the Modified BSD License.
|
# Distributed under the terms of the Modified BSD License.
|
||||||
|
|
||||||
from IPython.utils.traitlets import Unicode
|
from IPython.utils.traitlets import List, Unicode
|
||||||
|
|
||||||
class URLPrefix(Unicode):
|
class URLPrefix(Unicode):
|
||||||
def validate(self, obj, value):
|
def validate(self, obj, value):
|
||||||
@@ -12,3 +12,18 @@ class URLPrefix(Unicode):
|
|||||||
if not u.endswith('/'):
|
if not u.endswith('/'):
|
||||||
u = u + '/'
|
u = u + '/'
|
||||||
return u
|
return u
|
||||||
|
|
||||||
|
class Command(List):
|
||||||
|
"""Traitlet for a command that should be a list of strings,
|
||||||
|
but allows it to be specified as a single string.
|
||||||
|
"""
|
||||||
|
def __init__(self, default_value=None, **kwargs):
|
||||||
|
kwargs.setdefault('minlen', 1)
|
||||||
|
if isinstance(default_value, str):
|
||||||
|
default_value = [default_value]
|
||||||
|
super().__init__(Unicode, default_value, **kwargs)
|
||||||
|
|
||||||
|
def validate(self, obj, value):
|
||||||
|
if isinstance(value, str):
|
||||||
|
value = [value]
|
||||||
|
return super().validate(obj, value)
|
||||||
|
Reference in New Issue
Block a user