{"diffoscope-json-version": 1, "source1": "/srv/reproducible-results/rbuild-debian/r-b-build.Fe8T220W/b1/jupyterhub_5.2.1+ds1-4_amd64.changes", "source2": "/srv/reproducible-results/rbuild-debian/r-b-build.Fe8T220W/b2/jupyterhub_5.2.1+ds1-4_amd64.changes", "unified_diff": null, "details": [{"source1": "Files", "source2": "Files", "unified_diff": "@@ -1,2 +1,2 @@\n \n- ad17678dc07a20c6f72edba3214a67b0 2021932 python optional jupyterhub_5.2.1+ds1-4_all.deb\n+ 2eeaf96bdbe8d65c739320510a5eb956 2022496 python optional jupyterhub_5.2.1+ds1-4_all.deb\n"}, {"source1": "jupyterhub_5.2.1+ds1-4_all.deb", "source2": "jupyterhub_5.2.1+ds1-4_all.deb", "unified_diff": null, "details": [{"source1": "file list", "source2": "file list", "unified_diff": "@@ -1,3 +1,3 @@\n -rw-r--r-- 0 0 0 4 2025-05-28 09:40:25.000000 debian-binary\n--rw-r--r-- 0 0 0 59492 2025-05-28 09:40:25.000000 control.tar.xz\n--rw-r--r-- 0 0 0 1962248 2025-05-28 09:40:25.000000 data.tar.xz\n+-rw-r--r-- 0 0 0 59496 2025-05-28 09:40:25.000000 control.tar.xz\n+-rw-r--r-- 0 0 0 1962808 2025-05-28 09:40:25.000000 data.tar.xz\n"}, {"source1": "control.tar.xz", "source2": "control.tar.xz", "unified_diff": null, "details": [{"source1": "control.tar", "source2": "control.tar", "unified_diff": null, "details": [{"source1": "./md5sums", "source2": "./md5sums", "unified_diff": null, "details": [{"source1": "./md5sums", "source2": "./md5sums", "comments": ["Files differ"], "unified_diff": null}]}]}]}, {"source1": "data.tar.xz", "source2": "data.tar.xz", "unified_diff": null, "details": [{"source1": "data.tar", "source2": "data.tar", "unified_diff": null, "details": [{"source1": "./usr/share/jupyterhub/jupyterhub_config.py", "source2": "./usr/share/jupyterhub/jupyterhub_config.py", "unified_diff": "@@ -997,14 +997,842 @@\n # \n # It should return the new URL to redirect to, or None to preserve current\n # behavior.\n # Default: None\n # c.JupyterHub.user_redirect_hook = None\n \n #------------------------------------------------------------------------------\n+# Spawner(LoggingConfigurable) configuration\n+#------------------------------------------------------------------------------\n+## Base class for spawning single-user notebook servers.\n+# \n+# Subclass this, and override the following methods:\n+# \n+# - load_state - get_state - start - stop - poll\n+# \n+# As JupyterHub supports multiple users, an instance of the Spawner subclass is\n+# created for each user. If there are 20 JupyterHub users, there will be 20\n+# instances of the subclass.\n+\n+## Extra arguments to be passed to the single-user server.\n+# \n+# Some spawners allow shell-style expansion here, allowing you to use\n+# environment variables here. Most, including the default, do not. Consult the\n+# documentation for your spawner to verify!\n+# Default: []\n+# c.Spawner.args = []\n+\n+## An optional hook function that you can implement to pass `auth_state` to the\n+# spawner after it has been initialized but before it starts. The `auth_state`\n+# dictionary may be set by the `.authenticate()` method of the authenticator.\n+# This hook enables you to pass some or all of that information to your spawner.\n+# \n+# Example::\n+# \n+# def userdata_hook(spawner, auth_state):\n+# spawner.userdata = auth_state[\"userdata\"]\n+# \n+# c.Spawner.auth_state_hook = userdata_hook\n+# Default: None\n+# c.Spawner.auth_state_hook = None\n+\n+## The command used for starting the single-user server.\n+# \n+# Provide either a string or a list containing the path to the startup script\n+# command. Extra arguments, other than this path, should be provided via `args`.\n+# \n+# This is usually set if you want to start the single-user server in a different\n+# python environment (with virtualenv/conda) than JupyterHub itself.\n+# \n+# Some spawners allow shell-style expansion here, allowing you to use\n+# environment variables. Most, including the default, do not. Consult the\n+# documentation for your spawner to verify!\n+# Default: ['jupyterhub-singleuser']\n+# c.Spawner.cmd = ['jupyterhub-singleuser']\n+\n+## Maximum number of consecutive failures to allow before shutting down\n+# JupyterHub.\n+# \n+# This helps JupyterHub recover from a certain class of problem preventing\n+# launch in contexts where the Hub is automatically restarted (e.g. systemd,\n+# docker, kubernetes).\n+# \n+# A limit of 0 means no limit and consecutive failures will not be tracked.\n+# Default: 0\n+# c.Spawner.consecutive_failure_limit = 0\n+\n+## Minimum number of cpu-cores a single-user notebook server is guaranteed to\n+# have available.\n+# \n+# If this value is set to 0.5, allows use of 50% of one CPU. If this value is\n+# set to 2, allows use of up to 2 CPUs.\n+# \n+# **This is a configuration setting. Your spawner must implement support for the\n+# limit to work.** The default spawner, `LocalProcessSpawner`, does **not**\n+# implement this support. A custom spawner **must** add support for this setting\n+# for it to be enforced.\n+# Default: None\n+# c.Spawner.cpu_guarantee = None\n+\n+## Maximum number of cpu-cores a single-user notebook server is allowed to use.\n+# \n+# If this value is set to 0.5, allows use of 50% of one CPU. If this value is\n+# set to 2, allows use of up to 2 CPUs.\n+# \n+# The single-user notebook server will never be scheduled by the kernel to use\n+# more cpu-cores than this. There is no guarantee that it can access this many\n+# cpu-cores.\n+# \n+# **This is a configuration setting. Your spawner must implement support for the\n+# limit to work.** The default spawner, `LocalProcessSpawner`, does **not**\n+# implement this support. A custom spawner **must** add support for this setting\n+# for it to be enforced.\n+# Default: None\n+# c.Spawner.cpu_limit = None\n+\n+## Enable debug-logging of the single-user server\n+# Default: False\n+# c.Spawner.debug = False\n+\n+## The URL the single-user server should start in.\n+# \n+# `{username}` will be expanded to the user's username\n+# \n+# Example uses:\n+# \n+# - You can set `notebook_dir` to `/` and `default_url` to `/tree/home/{username}` to allow people to\n+# navigate the whole filesystem from their notebook server, but still start in their home directory.\n+# - Start with `/notebooks` instead of `/tree` if `default_url` points to a notebook instead of a directory.\n+# - You can set this to `/lab` to have JupyterLab start by default, rather than Jupyter Notebook.\n+# Default: ''\n+# c.Spawner.default_url = ''\n+\n+## Disable per-user configuration of single-user servers.\n+# \n+# When starting the user's single-user server, any config file found in the\n+# user's $HOME directory will be ignored.\n+# \n+# Note: a user could circumvent this if the user modifies their Python\n+# environment, such as when they have their own conda environments / virtualenvs\n+# / containers.\n+# Default: False\n+# c.Spawner.disable_user_config = False\n+\n+## List of environment variables for the single-user server to inherit from the\n+# JupyterHub process.\n+# \n+# This list is used to ensure that sensitive information in the JupyterHub\n+# process's environment (such as `CONFIGPROXY_AUTH_TOKEN`) is not passed to the\n+# single-user server's process.\n+# Default: ['JUPYTERHUB_SINGLEUSER_APP']\n+# c.Spawner.env_keep = ['JUPYTERHUB_SINGLEUSER_APP']\n+\n+## Extra environment variables to set for the single-user server's process.\n+# \n+# Environment variables that end up in the single-user server's process come from 3 sources:\n+# - This `environment` configurable\n+# - The JupyterHub process' environment variables that are listed in `env_keep`\n+# - Variables to establish contact between the single-user notebook and the hub (such as JUPYTERHUB_API_TOKEN)\n+# \n+# The `environment` configurable should be set by JupyterHub administrators to\n+# add installation specific environment variables. It is a dict where the key is\n+# the name of the environment variable, and the value can be a string or a\n+# callable. If it is a callable, it will be called with one parameter (the\n+# spawner instance), and should return a string fairly quickly (no blocking\n+# operations please!).\n+# \n+# Note that the spawner class' interface is not guaranteed to be exactly same\n+# across upgrades, so if you are using the callable take care to verify it\n+# continues to work after upgrades!\n+# \n+# .. versionchanged:: 1.2\n+# environment from this configuration has highest priority,\n+# allowing override of 'default' env variables,\n+# such as JUPYTERHUB_API_URL.\n+# Default: {}\n+# c.Spawner.environment = {}\n+\n+## Override specific traitlets based on group membership of the user.\n+# \n+# This can be a dict, or a callable that returns a dict. The keys of the dict\n+# are *only* used for lexicographical sorting, to guarantee consistent ordering\n+# of the overrides. If it is a callable, it may be async, and will be passed one\n+# parameter - the spawner instance. It should return a dictionary.\n+# \n+# The values of the dict are dicts with the following keys:\n+# \n+# - `\"groups\"` - If the user belongs to *any* of these groups, these overrides are\n+# applied to their server before spawning.\n+# - `\"spawner_override\"` - a dictionary with overrides to apply to the Spawner\n+# settings. Each value can be either the final value to change or a callable that\n+# take the `Spawner` instance as parameter and returns the final value.\n+# If the traitlet being overriden is a *dictionary*, the dictionary\n+# will be *recursively updated*, rather than overriden. If you want to\n+# remove a key, set its value to `None`.\n+# \n+# Example:\n+# \n+# The following example config will:\n+# \n+# 1. Add the environment variable \"AM_I_GROUP_ALPHA\" to everyone in the \"group-alpha\" group\n+# 2. Add the environment variable \"AM_I_GROUP_BETA\" to everyone in the \"group-beta\" group.\n+# If a user is part of both \"group-beta\" and \"group-alpha\", they will get *both* these env\n+# vars, due to the dictionary merging functionality.\n+# 3. Add a higher memory limit for everyone in the \"group-beta\" group.\n+# \n+# ::\n+# \n+# c.Spawner.group_overrides = {\n+# \"01-group-alpha-env-add\": {\n+# \"groups\": [\"group-alpha\"],\n+# \"spawner_override\": {\"environment\": {\"AM_I_GROUP_ALPHA\": \"yes\"}},\n+# },\n+# \"02-group-beta-env-add\": {\n+# \"groups\": [\"group-beta\"],\n+# \"spawner_override\": {\"environment\": {\"AM_I_GROUP_BETA\": \"yes\"}},\n+# },\n+# \"03-group-beta-mem-limit\": {\n+# \"groups\": [\"group-beta\"],\n+# \"spawner_override\": {\"mem_limit\": \"2G\"}\n+# }\n+# }\n+# Default: traitlets.Undefined\n+# c.Spawner.group_overrides = traitlets.Undefined\n+\n+## Timeout (in seconds) before giving up on a spawned HTTP server\n+# \n+# Once a server has successfully been spawned, this is the amount of time we\n+# wait before assuming that the server is unable to accept connections.\n+# Default: 30\n+# c.Spawner.http_timeout = 30\n+\n+## The URL the single-user server should connect to the Hub.\n+# \n+# If the Hub URL set in your JupyterHub config is not reachable from spawned\n+# notebooks, you can set differnt URL by this config.\n+# \n+# Is None if you don't need to change the URL.\n+# Default: None\n+# c.Spawner.hub_connect_url = None\n+\n+## The IP address (or hostname) the single-user server should listen on.\n+# \n+# Usually either '127.0.0.1' (default) or '0.0.0.0'.\n+# \n+# The JupyterHub proxy implementation should be able to send packets to this\n+# interface.\n+# \n+# Subclasses which launch remotely or in containers should override the default\n+# to '0.0.0.0'.\n+# \n+# .. versionchanged:: 2.0\n+# Default changed to '127.0.0.1', from ''.\n+# In most cases, this does not result in a change in behavior,\n+# as '' was interpreted as 'unspecified',\n+# which used the subprocesses' own default, itself usually '127.0.0.1'.\n+# Default: '127.0.0.1'\n+# c.Spawner.ip = '127.0.0.1'\n+\n+## Minimum number of bytes a single-user notebook server is guaranteed to have\n+# available.\n+# \n+# Allows the following suffixes:\n+# - K -> Kilobytes\n+# - M -> Megabytes\n+# - G -> Gigabytes\n+# - T -> Terabytes\n+# \n+# **This is a configuration setting. Your spawner must implement support for the\n+# limit to work.** The default spawner, `LocalProcessSpawner`, does **not**\n+# implement this support. A custom spawner **must** add support for this setting\n+# for it to be enforced.\n+# Default: None\n+# c.Spawner.mem_guarantee = None\n+\n+## Maximum number of bytes a single-user notebook server is allowed to use.\n+# \n+# Allows the following suffixes:\n+# - K -> Kilobytes\n+# - M -> Megabytes\n+# - G -> Gigabytes\n+# - T -> Terabytes\n+# \n+# If the single user server tries to allocate more memory than this, it will\n+# fail. There is no guarantee that the single-user notebook server will be able\n+# to allocate this much memory - only that it can not allocate more than this.\n+# \n+# **This is a configuration setting. Your spawner must implement support for the\n+# limit to work.** The default spawner, `LocalProcessSpawner`, does **not**\n+# implement this support. A custom spawner **must** add support for this setting\n+# for it to be enforced.\n+# Default: None\n+# c.Spawner.mem_limit = None\n+\n+## Path to the notebook directory for the single-user server.\n+# \n+# The user sees a file listing of this directory when the notebook interface is\n+# started. The current interface does not easily allow browsing beyond the\n+# subdirectories in this directory's tree.\n+# \n+# `~` will be expanded to the home directory of the user, and {username} will be\n+# replaced with the name of the user.\n+# \n+# Note that this does *not* prevent users from accessing files outside of this\n+# path! They can do so with many other means.\n+# Default: ''\n+# c.Spawner.notebook_dir = ''\n+\n+## Allowed scopes for oauth tokens issued by this server's oauth client.\n+# \n+# This sets the maximum and default scopes\n+# assigned to oauth tokens issued by a single-user server's\n+# oauth client (i.e. tokens stored in browsers after authenticating with the server),\n+# defining what actions the server can take on behalf of logged-in users.\n+# \n+# Default is an empty list, meaning minimal permissions to identify users,\n+# no actions can be taken on their behalf.\n+# \n+# If callable, will be called with the Spawner as a single argument.\n+# Callables may be async.\n+# Default: traitlets.Undefined\n+# c.Spawner.oauth_client_allowed_scopes = traitlets.Undefined\n+\n+## Allowed roles for oauth tokens.\n+# \n+# Deprecated in 3.0: use oauth_client_allowed_scopes\n+# \n+# This sets the maximum and default roles\n+# assigned to oauth tokens issued by a single-user server's\n+# oauth client (i.e. tokens stored in browsers after authenticating with the server),\n+# defining what actions the server can take on behalf of logged-in users.\n+# \n+# Default is an empty list, meaning minimal permissions to identify users,\n+# no actions can be taken on their behalf.\n+# Default: traitlets.Undefined\n+# c.Spawner.oauth_roles = traitlets.Undefined\n+\n+## An HTML form for options a user can specify on launching their server.\n+# \n+# The surrounding `
` element and the submit button are already provided.\n+# \n+# For example:\n+# \n+# .. code:: html\n+# \n+# Set your key:\n+# \n+#
\n+# Choose a letter:\n+# \n+# \n+# The data from this form submission will be passed on to your spawner in\n+# `self.user_options`\n+# \n+# Instead of a form snippet string, this could also be a callable that takes as\n+# one parameter the current spawner instance and returns a string. The callable\n+# will be called asynchronously if it returns a future, rather than a str. Note\n+# that the interface of the spawner class is not deemed stable across versions,\n+# so using this functionality might cause your JupyterHub upgrades to break.\n+# Default: traitlets.Undefined\n+# c.Spawner.options_form = traitlets.Undefined\n+\n+## Interpret HTTP form data\n+# \n+# Form data will always arrive as a dict of lists of strings. Override this\n+# function to understand single-values, numbers, etc.\n+# \n+# This should coerce form data into the structure expected by self.user_options,\n+# which must be a dict, and should be JSON-serializeable, though it can contain\n+# bytes in addition to standard JSON data types.\n+# \n+# This method should not have any side effects. Any handling of `user_options`\n+# should be done in `.start()` to ensure consistent behavior across servers\n+# spawned via the API and form submission page.\n+# \n+# Instances will receive this data on self.user_options, after passing through\n+# this function, prior to `Spawner.start`.\n+# \n+# .. versionchanged:: 1.0\n+# user_options are persisted in the JupyterHub database to be reused\n+# on subsequent spawns if no options are given.\n+# user_options is serialized to JSON as part of this persistence\n+# (with additional support for bytes in case of uploaded file data),\n+# and any non-bytes non-jsonable values will be replaced with None\n+# if the user_options are re-used.\n+# Default: traitlets.Undefined\n+# c.Spawner.options_from_form = traitlets.Undefined\n+\n+## Interval (in seconds) on which to poll the spawner for single-user server's\n+# status.\n+# \n+# At every poll interval, each spawner's `.poll` method is called, which checks\n+# if the single-user server is still running. If it isn't running, then\n+# JupyterHub modifies its own state accordingly and removes appropriate routes\n+# from the configurable proxy.\n+# Default: 30\n+# c.Spawner.poll_interval = 30\n+\n+## Jitter fraction for poll_interval.\n+# \n+# Avoids alignment of poll calls for many Spawners, e.g. when restarting\n+# JupyterHub, which restarts all polls for running Spawners.\n+# \n+# `poll_jitter=0` means no jitter, 0.1 means 10%, etc.\n+# Default: 0.1\n+# c.Spawner.poll_jitter = 0.1\n+\n+## The port for single-user servers to listen on.\n+# \n+# Defaults to `0`, which uses a randomly allocated port number each time.\n+# \n+# If set to a non-zero value, all Spawners will use the same port, which only\n+# makes sense if each server is on a different address, e.g. in containers.\n+# \n+# New in version 0.7.\n+# Default: 0\n+# c.Spawner.port = 0\n+\n+## An optional hook function that you can implement to do work after the spawner\n+# stops.\n+# \n+# This can be set independent of any concrete spawner implementation.\n+# Default: None\n+# c.Spawner.post_stop_hook = None\n+\n+## An optional hook function that you can implement to do some bootstrapping work\n+# before the spawner starts. For example, create a directory for your user or\n+# load initial content.\n+# \n+# This can be set independent of any concrete spawner implementation.\n+# \n+# This maybe a coroutine.\n+# \n+# Example::\n+# \n+# def my_hook(spawner):\n+# username = spawner.user.name\n+# spawner.environment[\"GREETING\"] = f\"Hello {username}\"\n+# \n+# c.Spawner.pre_spawn_hook = my_hook\n+# Default: None\n+# c.Spawner.pre_spawn_hook = None\n+\n+## An optional hook function that you can implement to modify the ready event,\n+# which will be shown to the user on the spawn progress page when their server\n+# is ready.\n+# \n+# This can be set independent of any concrete spawner implementation.\n+# \n+# This maybe a coroutine.\n+# \n+# Example::\n+# \n+# async def my_ready_hook(spawner, ready_event):\n+# ready_event[\"html_message\"] = f\"Server {spawner.name} is ready for {spawner.user.name}\"\n+# return ready_event\n+# \n+# c.Spawner.progress_ready_hook = my_ready_hook\n+# Default: None\n+# c.Spawner.progress_ready_hook = None\n+\n+## The list of scopes to request for $JUPYTERHUB_API_TOKEN\n+# \n+# If not specified, the scopes in the `server` role will be used\n+# (unchanged from pre-4.0).\n+# \n+# If callable, will be called with the Spawner instance as its sole argument\n+# (JupyterHub user available as spawner.user).\n+# \n+# JUPYTERHUB_API_TOKEN will be assigned the _subset_ of these scopes\n+# that are held by the user (as in oauth_client_allowed_scopes).\n+# \n+# .. versionadded:: 4.0\n+# Default: traitlets.Undefined\n+# c.Spawner.server_token_scopes = traitlets.Undefined\n+\n+## List of SSL alt names\n+# \n+# May be set in config if all spawners should have the same value(s),\n+# or set at runtime by Spawner that know their names.\n+# Default: []\n+# c.Spawner.ssl_alt_names = []\n+\n+## Whether to include `DNS:localhost`, `IP:127.0.0.1` in alt names\n+# Default: True\n+# c.Spawner.ssl_alt_names_include_local = True\n+\n+## Timeout (in seconds) before giving up on starting of single-user server.\n+# \n+# This is the timeout for start to return, not the timeout for the server to\n+# respond. Callers of spawner.start will assume that startup has failed if it\n+# takes longer than this. start should return when the server process is started\n+# and its location is known.\n+# Default: 60\n+# c.Spawner.start_timeout = 60\n+\n+#------------------------------------------------------------------------------\n+# LocalProcessSpawner(Spawner) configuration\n+#------------------------------------------------------------------------------\n+## A Spawner that uses `subprocess.Popen` to start single-user servers as local\n+# processes.\n+# \n+# Requires local UNIX users matching the authenticated users to exist. Does not\n+# work on Windows.\n+# \n+# This is the default spawner for JupyterHub.\n+# \n+# Note: This spawner does not implement CPU / memory guarantees and limits.\n+\n+## \n+# See also: Spawner.args\n+# c.LocalProcessSpawner.args = []\n+\n+## \n+# See also: Spawner.auth_state_hook\n+# c.LocalProcessSpawner.auth_state_hook = None\n+\n+## \n+# See also: Spawner.cmd\n+# c.LocalProcessSpawner.cmd = ['jupyterhub-singleuser']\n+\n+## \n+# See also: Spawner.consecutive_failure_limit\n+# c.LocalProcessSpawner.consecutive_failure_limit = 0\n+\n+## \n+# See also: Spawner.cpu_guarantee\n+# c.LocalProcessSpawner.cpu_guarantee = None\n+\n+## \n+# See also: Spawner.cpu_limit\n+# c.LocalProcessSpawner.cpu_limit = None\n+\n+## Enable debug-logging of the single-user server\n+# See also: Spawner.debug\n+# c.LocalProcessSpawner.debug = False\n+\n+## \n+# See also: Spawner.default_url\n+# c.LocalProcessSpawner.default_url = ''\n+\n+## \n+# See also: Spawner.disable_user_config\n+# c.LocalProcessSpawner.disable_user_config = False\n+\n+## \n+# See also: Spawner.env_keep\n+# c.LocalProcessSpawner.env_keep = ['JUPYTERHUB_SINGLEUSER_APP']\n+\n+## \n+# See also: Spawner.environment\n+# c.LocalProcessSpawner.environment = {}\n+\n+## \n+# See also: Spawner.group_overrides\n+# c.LocalProcessSpawner.group_overrides = traitlets.Undefined\n+\n+## \n+# See also: Spawner.http_timeout\n+# c.LocalProcessSpawner.http_timeout = 30\n+\n+## \n+# See also: Spawner.hub_connect_url\n+# c.LocalProcessSpawner.hub_connect_url = None\n+\n+## Seconds to wait for single-user server process to halt after SIGINT.\n+# \n+# If the process has not exited cleanly after this many seconds, a SIGTERM is\n+# sent.\n+# Default: 10\n+# c.LocalProcessSpawner.interrupt_timeout = 10\n+\n+## \n+# See also: Spawner.ip\n+# c.LocalProcessSpawner.ip = '127.0.0.1'\n+\n+## Seconds to wait for process to halt after SIGKILL before giving up.\n+# \n+# If the process does not exit cleanly after this many seconds of SIGKILL, it\n+# becomes a zombie process. The hub process will log a warning and then give up.\n+# Default: 5\n+# c.LocalProcessSpawner.kill_timeout = 5\n+\n+## \n+# See also: Spawner.mem_guarantee\n+# c.LocalProcessSpawner.mem_guarantee = None\n+\n+## \n+# See also: Spawner.mem_limit\n+# c.LocalProcessSpawner.mem_limit = None\n+\n+## \n+# See also: Spawner.notebook_dir\n+# c.LocalProcessSpawner.notebook_dir = ''\n+\n+## Allowed scopes for oauth tokens issued by this server's oauth client.\n+# See also: Spawner.oauth_client_allowed_scopes\n+# c.LocalProcessSpawner.oauth_client_allowed_scopes = traitlets.Undefined\n+\n+## Allowed roles for oauth tokens.\n+# See also: Spawner.oauth_roles\n+# c.LocalProcessSpawner.oauth_roles = traitlets.Undefined\n+\n+## \n+# See also: Spawner.options_form\n+# c.LocalProcessSpawner.options_form = traitlets.Undefined\n+\n+## \n+# See also: Spawner.options_from_form\n+# c.LocalProcessSpawner.options_from_form = traitlets.Undefined\n+\n+## \n+# See also: Spawner.poll_interval\n+# c.LocalProcessSpawner.poll_interval = 30\n+\n+## \n+# See also: Spawner.poll_jitter\n+# c.LocalProcessSpawner.poll_jitter = 0.1\n+\n+## Extra keyword arguments to pass to Popen\n+# \n+# when spawning single-user servers.\n+# \n+# For example::\n+# \n+# popen_kwargs = dict(shell=True)\n+# Default: {}\n+# c.LocalProcessSpawner.popen_kwargs = {}\n+\n+## \n+# See also: Spawner.port\n+# c.LocalProcessSpawner.port = 0\n+\n+## \n+# See also: Spawner.post_stop_hook\n+# c.LocalProcessSpawner.post_stop_hook = None\n+\n+## \n+# See also: Spawner.pre_spawn_hook\n+# c.LocalProcessSpawner.pre_spawn_hook = None\n+\n+## \n+# See also: Spawner.progress_ready_hook\n+# c.LocalProcessSpawner.progress_ready_hook = None\n+\n+## The list of scopes to request for $JUPYTERHUB_API_TOKEN\n+# See also: Spawner.server_token_scopes\n+# c.LocalProcessSpawner.server_token_scopes = traitlets.Undefined\n+\n+## Specify a shell command to launch.\n+# \n+# The single-user command will be appended to this list,\n+# so it sould end with `-c` (for bash) or equivalent.\n+# \n+# For example::\n+# \n+# c.LocalProcessSpawner.shell_cmd = ['bash', '-l', '-c']\n+# \n+# to launch with a bash login shell, which would set up the user's own\n+# complete environment.\n+# \n+# .. warning::\n+# \n+# Using shell_cmd gives users control over PATH, etc.,\n+# which could change what the jupyterhub-singleuser launch command does.\n+# Only use this for trusted users.\n+# Default: []\n+# c.LocalProcessSpawner.shell_cmd = []\n+\n+## List of SSL alt names\n+# See also: Spawner.ssl_alt_names\n+# c.LocalProcessSpawner.ssl_alt_names = []\n+\n+## Whether to include `DNS:localhost`, `IP:127.0.0.1` in alt names\n+# See also: Spawner.ssl_alt_names_include_local\n+# c.LocalProcessSpawner.ssl_alt_names_include_local = True\n+\n+## \n+# See also: Spawner.start_timeout\n+# c.LocalProcessSpawner.start_timeout = 60\n+\n+## Seconds to wait for single-user server process to halt after SIGTERM.\n+# \n+# If the process does not exit cleanly after this many seconds of SIGTERM, a\n+# SIGKILL is sent.\n+# Default: 5\n+# c.LocalProcessSpawner.term_timeout = 5\n+\n+#------------------------------------------------------------------------------\n+# SimpleLocalProcessSpawner(LocalProcessSpawner) configuration\n+#------------------------------------------------------------------------------\n+## A version of LocalProcessSpawner that doesn't require users to exist on the\n+# system beforehand.\n+# \n+# Only use this for testing.\n+# \n+# Note: DO NOT USE THIS FOR PRODUCTION USE CASES! It is very insecure, and\n+# provides absolutely no isolation between different users!\n+\n+## \n+# See also: Spawner.args\n+# c.SimpleLocalProcessSpawner.args = []\n+\n+## \n+# See also: Spawner.auth_state_hook\n+# c.SimpleLocalProcessSpawner.auth_state_hook = None\n+\n+## \n+# See also: Spawner.cmd\n+# c.SimpleLocalProcessSpawner.cmd = ['jupyterhub-singleuser']\n+\n+## \n+# See also: Spawner.consecutive_failure_limit\n+# c.SimpleLocalProcessSpawner.consecutive_failure_limit = 0\n+\n+## \n+# See also: Spawner.cpu_guarantee\n+# c.SimpleLocalProcessSpawner.cpu_guarantee = None\n+\n+## \n+# See also: Spawner.cpu_limit\n+# c.SimpleLocalProcessSpawner.cpu_limit = None\n+\n+## Enable debug-logging of the single-user server\n+# See also: Spawner.debug\n+# c.SimpleLocalProcessSpawner.debug = False\n+\n+## \n+# See also: Spawner.default_url\n+# c.SimpleLocalProcessSpawner.default_url = ''\n+\n+## \n+# See also: Spawner.disable_user_config\n+# c.SimpleLocalProcessSpawner.disable_user_config = False\n+\n+## \n+# See also: Spawner.env_keep\n+# c.SimpleLocalProcessSpawner.env_keep = ['JUPYTERHUB_SINGLEUSER_APP']\n+\n+## \n+# See also: Spawner.environment\n+# c.SimpleLocalProcessSpawner.environment = {}\n+\n+## \n+# See also: Spawner.group_overrides\n+# c.SimpleLocalProcessSpawner.group_overrides = traitlets.Undefined\n+\n+## Template to expand to set the user home. {username} is expanded to the\n+# jupyterhub username.\n+# Default: '/tmp/{username}'\n+# c.SimpleLocalProcessSpawner.home_dir_template = '/tmp/{username}'\n+\n+## \n+# See also: Spawner.http_timeout\n+# c.SimpleLocalProcessSpawner.http_timeout = 30\n+\n+## \n+# See also: Spawner.hub_connect_url\n+# c.SimpleLocalProcessSpawner.hub_connect_url = None\n+\n+## \n+# See also: LocalProcessSpawner.interrupt_timeout\n+# c.SimpleLocalProcessSpawner.interrupt_timeout = 10\n+\n+## \n+# See also: Spawner.ip\n+# c.SimpleLocalProcessSpawner.ip = '127.0.0.1'\n+\n+## \n+# See also: LocalProcessSpawner.kill_timeout\n+# c.SimpleLocalProcessSpawner.kill_timeout = 5\n+\n+## \n+# See also: Spawner.mem_guarantee\n+# c.SimpleLocalProcessSpawner.mem_guarantee = None\n+\n+## \n+# See also: Spawner.mem_limit\n+# c.SimpleLocalProcessSpawner.mem_limit = None\n+\n+## \n+# See also: Spawner.notebook_dir\n+# c.SimpleLocalProcessSpawner.notebook_dir = ''\n+\n+## Allowed scopes for oauth tokens issued by this server's oauth client.\n+# See also: Spawner.oauth_client_allowed_scopes\n+# c.SimpleLocalProcessSpawner.oauth_client_allowed_scopes = traitlets.Undefined\n+\n+## Allowed roles for oauth tokens.\n+# See also: Spawner.oauth_roles\n+# c.SimpleLocalProcessSpawner.oauth_roles = traitlets.Undefined\n+\n+## \n+# See also: Spawner.options_form\n+# c.SimpleLocalProcessSpawner.options_form = traitlets.Undefined\n+\n+## \n+# See also: Spawner.options_from_form\n+# c.SimpleLocalProcessSpawner.options_from_form = traitlets.Undefined\n+\n+## \n+# See also: Spawner.poll_interval\n+# c.SimpleLocalProcessSpawner.poll_interval = 30\n+\n+## \n+# See also: Spawner.poll_jitter\n+# c.SimpleLocalProcessSpawner.poll_jitter = 0.1\n+\n+## Extra keyword arguments to pass to Popen\n+# See also: LocalProcessSpawner.popen_kwargs\n+# c.SimpleLocalProcessSpawner.popen_kwargs = {}\n+\n+## \n+# See also: Spawner.port\n+# c.SimpleLocalProcessSpawner.port = 0\n+\n+## \n+# See also: Spawner.post_stop_hook\n+# c.SimpleLocalProcessSpawner.post_stop_hook = None\n+\n+## \n+# See also: Spawner.pre_spawn_hook\n+# c.SimpleLocalProcessSpawner.pre_spawn_hook = None\n+\n+## \n+# See also: Spawner.progress_ready_hook\n+# c.SimpleLocalProcessSpawner.progress_ready_hook = None\n+\n+## The list of scopes to request for $JUPYTERHUB_API_TOKEN\n+# See also: Spawner.server_token_scopes\n+# c.SimpleLocalProcessSpawner.server_token_scopes = traitlets.Undefined\n+\n+## Specify a shell command to launch.\n+# See also: LocalProcessSpawner.shell_cmd\n+# c.SimpleLocalProcessSpawner.shell_cmd = []\n+\n+## List of SSL alt names\n+# See also: Spawner.ssl_alt_names\n+# c.SimpleLocalProcessSpawner.ssl_alt_names = []\n+\n+## Whether to include `DNS:localhost`, `IP:127.0.0.1` in alt names\n+# See also: Spawner.ssl_alt_names_include_local\n+# c.SimpleLocalProcessSpawner.ssl_alt_names_include_local = True\n+\n+## \n+# See also: Spawner.start_timeout\n+# c.SimpleLocalProcessSpawner.start_timeout = 60\n+\n+## \n+# See also: LocalProcessSpawner.term_timeout\n+# c.SimpleLocalProcessSpawner.term_timeout = 5\n+\n+#------------------------------------------------------------------------------\n # Authenticator(LoggingConfigurable) configuration\n #------------------------------------------------------------------------------\n ## Base class for implementing an authentication provider for JupyterHub\n \n ## Set of users that will be granted admin rights on this JupyterHub.\n # \n # Note:\n@@ -1350,14 +2178,118 @@\n # c.Authenticator.username_pattern = ''\n \n ## Deprecated, use `Authenticator.allowed_users`\n # Default: set()\n # c.Authenticator.whitelist = set()\n \n #------------------------------------------------------------------------------\n+# DummyAuthenticator(Authenticator) configuration\n+#------------------------------------------------------------------------------\n+## Dummy Authenticator for testing\n+# \n+# By default, any username + password is allowed If a non-empty password is set,\n+# any username will be allowed if it logs in with that password.\n+# \n+# .. versionadded:: 1.0\n+# \n+# .. versionadded:: 5.0\n+# `allow_all` defaults to True,\n+# preserving default behavior.\n+\n+## \n+# See also: Authenticator.admin_users\n+# c.DummyAuthenticator.admin_users = set()\n+\n+## \n+# See also: Authenticator.allow_all\n+# c.DummyAuthenticator.allow_all = False\n+\n+## \n+# See also: Authenticator.allow_existing_users\n+# c.DummyAuthenticator.allow_existing_users = False\n+\n+## \n+# See also: Authenticator.allowed_users\n+# c.DummyAuthenticator.allowed_users = set()\n+\n+## Is there any allow config?\n+# See also: Authenticator.any_allow_config\n+# c.DummyAuthenticator.any_allow_config = False\n+\n+## The max age (in seconds) of authentication info\n+# See also: Authenticator.auth_refresh_age\n+# c.DummyAuthenticator.auth_refresh_age = 300\n+\n+## Automatically begin the login process\n+# See also: Authenticator.auto_login\n+# c.DummyAuthenticator.auto_login = False\n+\n+## \n+# See also: Authenticator.auto_login_oauth2_authorize\n+# c.DummyAuthenticator.auto_login_oauth2_authorize = False\n+\n+## \n+# See also: Authenticator.blocked_users\n+# c.DummyAuthenticator.blocked_users = set()\n+\n+## Delete any users from the database that do not pass validation\n+# See also: Authenticator.delete_invalid_users\n+# c.DummyAuthenticator.delete_invalid_users = False\n+\n+## Enable persisting auth_state (if available).\n+# See also: Authenticator.enable_auth_state\n+# c.DummyAuthenticator.enable_auth_state = False\n+\n+## Let authenticator manage user groups\n+# See also: Authenticator.manage_groups\n+# c.DummyAuthenticator.manage_groups = False\n+\n+## Let authenticator manage roles\n+# See also: Authenticator.manage_roles\n+# c.DummyAuthenticator.manage_roles = False\n+\n+## \n+# See also: Authenticator.otp_prompt\n+# c.DummyAuthenticator.otp_prompt = 'OTP:'\n+\n+## Set a global password for all users wanting to log in.\n+# \n+# This allows users with any username to log in with the same static password.\n+# Default: ''\n+# c.DummyAuthenticator.password = ''\n+\n+## \n+# See also: Authenticator.post_auth_hook\n+# c.DummyAuthenticator.post_auth_hook = None\n+\n+## Force refresh of auth prior to spawn.\n+# See also: Authenticator.refresh_pre_spawn\n+# c.DummyAuthenticator.refresh_pre_spawn = False\n+\n+## \n+# See also: Authenticator.request_otp\n+# c.DummyAuthenticator.request_otp = False\n+\n+## Reset managed roles to result of `load_managed_roles()` on startup.\n+# See also: Authenticator.reset_managed_roles_on_startup\n+# c.DummyAuthenticator.reset_managed_roles_on_startup = False\n+\n+## Dictionary mapping authenticator usernames to JupyterHub users.\n+# See also: Authenticator.username_map\n+# c.DummyAuthenticator.username_map = {}\n+\n+## \n+# See also: Authenticator.username_pattern\n+# c.DummyAuthenticator.username_pattern = ''\n+\n+## Deprecated, use `Authenticator.allowed_users`\n+# See also: Authenticator.whitelist\n+# c.DummyAuthenticator.whitelist = set()\n+\n+#------------------------------------------------------------------------------\n # NullAuthenticator(Authenticator) configuration\n #------------------------------------------------------------------------------\n ## Null Authenticator for JupyterHub\n # \n # For cases where authentication should be disabled, e.g. only allowing access\n # via API tokens.\n # \n@@ -1546,486 +2478,14 @@\n # c.ConfigurableHTTPProxy.pid_file = 'jupyterhub-proxy.pid'\n \n ## Should the Hub start the proxy\n # See also: Proxy.should_start\n # c.ConfigurableHTTPProxy.should_start = True\n \n #------------------------------------------------------------------------------\n-# Spawner(LoggingConfigurable) configuration\n-#------------------------------------------------------------------------------\n-## Base class for spawning single-user notebook servers.\n-# \n-# Subclass this, and override the following methods:\n-# \n-# - load_state - get_state - start - stop - poll\n-# \n-# As JupyterHub supports multiple users, an instance of the Spawner subclass is\n-# created for each user. If there are 20 JupyterHub users, there will be 20\n-# instances of the subclass.\n-\n-## Extra arguments to be passed to the single-user server.\n-# \n-# Some spawners allow shell-style expansion here, allowing you to use\n-# environment variables here. Most, including the default, do not. Consult the\n-# documentation for your spawner to verify!\n-# Default: []\n-# c.Spawner.args = []\n-\n-## An optional hook function that you can implement to pass `auth_state` to the\n-# spawner after it has been initialized but before it starts. The `auth_state`\n-# dictionary may be set by the `.authenticate()` method of the authenticator.\n-# This hook enables you to pass some or all of that information to your spawner.\n-# \n-# Example::\n-# \n-# def userdata_hook(spawner, auth_state):\n-# spawner.userdata = auth_state[\"userdata\"]\n-# \n-# c.Spawner.auth_state_hook = userdata_hook\n-# Default: None\n-# c.Spawner.auth_state_hook = None\n-\n-## The command used for starting the single-user server.\n-# \n-# Provide either a string or a list containing the path to the startup script\n-# command. Extra arguments, other than this path, should be provided via `args`.\n-# \n-# This is usually set if you want to start the single-user server in a different\n-# python environment (with virtualenv/conda) than JupyterHub itself.\n-# \n-# Some spawners allow shell-style expansion here, allowing you to use\n-# environment variables. Most, including the default, do not. Consult the\n-# documentation for your spawner to verify!\n-# Default: ['jupyterhub-singleuser']\n-# c.Spawner.cmd = ['jupyterhub-singleuser']\n-\n-## Maximum number of consecutive failures to allow before shutting down\n-# JupyterHub.\n-# \n-# This helps JupyterHub recover from a certain class of problem preventing\n-# launch in contexts where the Hub is automatically restarted (e.g. systemd,\n-# docker, kubernetes).\n-# \n-# A limit of 0 means no limit and consecutive failures will not be tracked.\n-# Default: 0\n-# c.Spawner.consecutive_failure_limit = 0\n-\n-## Minimum number of cpu-cores a single-user notebook server is guaranteed to\n-# have available.\n-# \n-# If this value is set to 0.5, allows use of 50% of one CPU. If this value is\n-# set to 2, allows use of up to 2 CPUs.\n-# \n-# **This is a configuration setting. Your spawner must implement support for the\n-# limit to work.** The default spawner, `LocalProcessSpawner`, does **not**\n-# implement this support. A custom spawner **must** add support for this setting\n-# for it to be enforced.\n-# Default: None\n-# c.Spawner.cpu_guarantee = None\n-\n-## Maximum number of cpu-cores a single-user notebook server is allowed to use.\n-# \n-# If this value is set to 0.5, allows use of 50% of one CPU. If this value is\n-# set to 2, allows use of up to 2 CPUs.\n-# \n-# The single-user notebook server will never be scheduled by the kernel to use\n-# more cpu-cores than this. There is no guarantee that it can access this many\n-# cpu-cores.\n-# \n-# **This is a configuration setting. Your spawner must implement support for the\n-# limit to work.** The default spawner, `LocalProcessSpawner`, does **not**\n-# implement this support. A custom spawner **must** add support for this setting\n-# for it to be enforced.\n-# Default: None\n-# c.Spawner.cpu_limit = None\n-\n-## Enable debug-logging of the single-user server\n-# Default: False\n-# c.Spawner.debug = False\n-\n-## The URL the single-user server should start in.\n-# \n-# `{username}` will be expanded to the user's username\n-# \n-# Example uses:\n-# \n-# - You can set `notebook_dir` to `/` and `default_url` to `/tree/home/{username}` to allow people to\n-# navigate the whole filesystem from their notebook server, but still start in their home directory.\n-# - Start with `/notebooks` instead of `/tree` if `default_url` points to a notebook instead of a directory.\n-# - You can set this to `/lab` to have JupyterLab start by default, rather than Jupyter Notebook.\n-# Default: ''\n-# c.Spawner.default_url = ''\n-\n-## Disable per-user configuration of single-user servers.\n-# \n-# When starting the user's single-user server, any config file found in the\n-# user's $HOME directory will be ignored.\n-# \n-# Note: a user could circumvent this if the user modifies their Python\n-# environment, such as when they have their own conda environments / virtualenvs\n-# / containers.\n-# Default: False\n-# c.Spawner.disable_user_config = False\n-\n-## List of environment variables for the single-user server to inherit from the\n-# JupyterHub process.\n-# \n-# This list is used to ensure that sensitive information in the JupyterHub\n-# process's environment (such as `CONFIGPROXY_AUTH_TOKEN`) is not passed to the\n-# single-user server's process.\n-# Default: ['JUPYTERHUB_SINGLEUSER_APP']\n-# c.Spawner.env_keep = ['JUPYTERHUB_SINGLEUSER_APP']\n-\n-## Extra environment variables to set for the single-user server's process.\n-# \n-# Environment variables that end up in the single-user server's process come from 3 sources:\n-# - This `environment` configurable\n-# - The JupyterHub process' environment variables that are listed in `env_keep`\n-# - Variables to establish contact between the single-user notebook and the hub (such as JUPYTERHUB_API_TOKEN)\n-# \n-# The `environment` configurable should be set by JupyterHub administrators to\n-# add installation specific environment variables. It is a dict where the key is\n-# the name of the environment variable, and the value can be a string or a\n-# callable. If it is a callable, it will be called with one parameter (the\n-# spawner instance), and should return a string fairly quickly (no blocking\n-# operations please!).\n-# \n-# Note that the spawner class' interface is not guaranteed to be exactly same\n-# across upgrades, so if you are using the callable take care to verify it\n-# continues to work after upgrades!\n-# \n-# .. versionchanged:: 1.2\n-# environment from this configuration has highest priority,\n-# allowing override of 'default' env variables,\n-# such as JUPYTERHUB_API_URL.\n-# Default: {}\n-# c.Spawner.environment = {}\n-\n-## Override specific traitlets based on group membership of the user.\n-# \n-# This can be a dict, or a callable that returns a dict. The keys of the dict\n-# are *only* used for lexicographical sorting, to guarantee consistent ordering\n-# of the overrides. If it is a callable, it may be async, and will be passed one\n-# parameter - the spawner instance. It should return a dictionary.\n-# \n-# The values of the dict are dicts with the following keys:\n-# \n-# - `\"groups\"` - If the user belongs to *any* of these groups, these overrides are\n-# applied to their server before spawning.\n-# - `\"spawner_override\"` - a dictionary with overrides to apply to the Spawner\n-# settings. Each value can be either the final value to change or a callable that\n-# take the `Spawner` instance as parameter and returns the final value.\n-# If the traitlet being overriden is a *dictionary*, the dictionary\n-# will be *recursively updated*, rather than overriden. If you want to\n-# remove a key, set its value to `None`.\n-# \n-# Example:\n-# \n-# The following example config will:\n-# \n-# 1. Add the environment variable \"AM_I_GROUP_ALPHA\" to everyone in the \"group-alpha\" group\n-# 2. Add the environment variable \"AM_I_GROUP_BETA\" to everyone in the \"group-beta\" group.\n-# If a user is part of both \"group-beta\" and \"group-alpha\", they will get *both* these env\n-# vars, due to the dictionary merging functionality.\n-# 3. Add a higher memory limit for everyone in the \"group-beta\" group.\n-# \n-# ::\n-# \n-# c.Spawner.group_overrides = {\n-# \"01-group-alpha-env-add\": {\n-# \"groups\": [\"group-alpha\"],\n-# \"spawner_override\": {\"environment\": {\"AM_I_GROUP_ALPHA\": \"yes\"}},\n-# },\n-# \"02-group-beta-env-add\": {\n-# \"groups\": [\"group-beta\"],\n-# \"spawner_override\": {\"environment\": {\"AM_I_GROUP_BETA\": \"yes\"}},\n-# },\n-# \"03-group-beta-mem-limit\": {\n-# \"groups\": [\"group-beta\"],\n-# \"spawner_override\": {\"mem_limit\": \"2G\"}\n-# }\n-# }\n-# Default: traitlets.Undefined\n-# c.Spawner.group_overrides = traitlets.Undefined\n-\n-## Timeout (in seconds) before giving up on a spawned HTTP server\n-# \n-# Once a server has successfully been spawned, this is the amount of time we\n-# wait before assuming that the server is unable to accept connections.\n-# Default: 30\n-# c.Spawner.http_timeout = 30\n-\n-## The URL the single-user server should connect to the Hub.\n-# \n-# If the Hub URL set in your JupyterHub config is not reachable from spawned\n-# notebooks, you can set differnt URL by this config.\n-# \n-# Is None if you don't need to change the URL.\n-# Default: None\n-# c.Spawner.hub_connect_url = None\n-\n-## The IP address (or hostname) the single-user server should listen on.\n-# \n-# Usually either '127.0.0.1' (default) or '0.0.0.0'.\n-# \n-# The JupyterHub proxy implementation should be able to send packets to this\n-# interface.\n-# \n-# Subclasses which launch remotely or in containers should override the default\n-# to '0.0.0.0'.\n-# \n-# .. versionchanged:: 2.0\n-# Default changed to '127.0.0.1', from ''.\n-# In most cases, this does not result in a change in behavior,\n-# as '' was interpreted as 'unspecified',\n-# which used the subprocesses' own default, itself usually '127.0.0.1'.\n-# Default: '127.0.0.1'\n-# c.Spawner.ip = '127.0.0.1'\n-\n-## Minimum number of bytes a single-user notebook server is guaranteed to have\n-# available.\n-# \n-# Allows the following suffixes:\n-# - K -> Kilobytes\n-# - M -> Megabytes\n-# - G -> Gigabytes\n-# - T -> Terabytes\n-# \n-# **This is a configuration setting. Your spawner must implement support for the\n-# limit to work.** The default spawner, `LocalProcessSpawner`, does **not**\n-# implement this support. A custom spawner **must** add support for this setting\n-# for it to be enforced.\n-# Default: None\n-# c.Spawner.mem_guarantee = None\n-\n-## Maximum number of bytes a single-user notebook server is allowed to use.\n-# \n-# Allows the following suffixes:\n-# - K -> Kilobytes\n-# - M -> Megabytes\n-# - G -> Gigabytes\n-# - T -> Terabytes\n-# \n-# If the single user server tries to allocate more memory than this, it will\n-# fail. There is no guarantee that the single-user notebook server will be able\n-# to allocate this much memory - only that it can not allocate more than this.\n-# \n-# **This is a configuration setting. Your spawner must implement support for the\n-# limit to work.** The default spawner, `LocalProcessSpawner`, does **not**\n-# implement this support. A custom spawner **must** add support for this setting\n-# for it to be enforced.\n-# Default: None\n-# c.Spawner.mem_limit = None\n-\n-## Path to the notebook directory for the single-user server.\n-# \n-# The user sees a file listing of this directory when the notebook interface is\n-# started. The current interface does not easily allow browsing beyond the\n-# subdirectories in this directory's tree.\n-# \n-# `~` will be expanded to the home directory of the user, and {username} will be\n-# replaced with the name of the user.\n-# \n-# Note that this does *not* prevent users from accessing files outside of this\n-# path! They can do so with many other means.\n-# Default: ''\n-# c.Spawner.notebook_dir = ''\n-\n-## Allowed scopes for oauth tokens issued by this server's oauth client.\n-# \n-# This sets the maximum and default scopes\n-# assigned to oauth tokens issued by a single-user server's\n-# oauth client (i.e. tokens stored in browsers after authenticating with the server),\n-# defining what actions the server can take on behalf of logged-in users.\n-# \n-# Default is an empty list, meaning minimal permissions to identify users,\n-# no actions can be taken on their behalf.\n-# \n-# If callable, will be called with the Spawner as a single argument.\n-# Callables may be async.\n-# Default: traitlets.Undefined\n-# c.Spawner.oauth_client_allowed_scopes = traitlets.Undefined\n-\n-## Allowed roles for oauth tokens.\n-# \n-# Deprecated in 3.0: use oauth_client_allowed_scopes\n-# \n-# This sets the maximum and default roles\n-# assigned to oauth tokens issued by a single-user server's\n-# oauth client (i.e. tokens stored in browsers after authenticating with the server),\n-# defining what actions the server can take on behalf of logged-in users.\n-# \n-# Default is an empty list, meaning minimal permissions to identify users,\n-# no actions can be taken on their behalf.\n-# Default: traitlets.Undefined\n-# c.Spawner.oauth_roles = traitlets.Undefined\n-\n-## An HTML form for options a user can specify on launching their server.\n-# \n-# The surrounding `` element and the submit button are already provided.\n-# \n-# For example:\n-# \n-# .. code:: html\n-# \n-# Set your key:\n-# \n-#
\n-# Choose a letter:\n-# \n-# \n-# The data from this form submission will be passed on to your spawner in\n-# `self.user_options`\n-# \n-# Instead of a form snippet string, this could also be a callable that takes as\n-# one parameter the current spawner instance and returns a string. The callable\n-# will be called asynchronously if it returns a future, rather than a str. Note\n-# that the interface of the spawner class is not deemed stable across versions,\n-# so using this functionality might cause your JupyterHub upgrades to break.\n-# Default: traitlets.Undefined\n-# c.Spawner.options_form = traitlets.Undefined\n-\n-## Interpret HTTP form data\n-# \n-# Form data will always arrive as a dict of lists of strings. Override this\n-# function to understand single-values, numbers, etc.\n-# \n-# This should coerce form data into the structure expected by self.user_options,\n-# which must be a dict, and should be JSON-serializeable, though it can contain\n-# bytes in addition to standard JSON data types.\n-# \n-# This method should not have any side effects. Any handling of `user_options`\n-# should be done in `.start()` to ensure consistent behavior across servers\n-# spawned via the API and form submission page.\n-# \n-# Instances will receive this data on self.user_options, after passing through\n-# this function, prior to `Spawner.start`.\n-# \n-# .. versionchanged:: 1.0\n-# user_options are persisted in the JupyterHub database to be reused\n-# on subsequent spawns if no options are given.\n-# user_options is serialized to JSON as part of this persistence\n-# (with additional support for bytes in case of uploaded file data),\n-# and any non-bytes non-jsonable values will be replaced with None\n-# if the user_options are re-used.\n-# Default: traitlets.Undefined\n-# c.Spawner.options_from_form = traitlets.Undefined\n-\n-## Interval (in seconds) on which to poll the spawner for single-user server's\n-# status.\n-# \n-# At every poll interval, each spawner's `.poll` method is called, which checks\n-# if the single-user server is still running. If it isn't running, then\n-# JupyterHub modifies its own state accordingly and removes appropriate routes\n-# from the configurable proxy.\n-# Default: 30\n-# c.Spawner.poll_interval = 30\n-\n-## Jitter fraction for poll_interval.\n-# \n-# Avoids alignment of poll calls for many Spawners, e.g. when restarting\n-# JupyterHub, which restarts all polls for running Spawners.\n-# \n-# `poll_jitter=0` means no jitter, 0.1 means 10%, etc.\n-# Default: 0.1\n-# c.Spawner.poll_jitter = 0.1\n-\n-## The port for single-user servers to listen on.\n-# \n-# Defaults to `0`, which uses a randomly allocated port number each time.\n-# \n-# If set to a non-zero value, all Spawners will use the same port, which only\n-# makes sense if each server is on a different address, e.g. in containers.\n-# \n-# New in version 0.7.\n-# Default: 0\n-# c.Spawner.port = 0\n-\n-## An optional hook function that you can implement to do work after the spawner\n-# stops.\n-# \n-# This can be set independent of any concrete spawner implementation.\n-# Default: None\n-# c.Spawner.post_stop_hook = None\n-\n-## An optional hook function that you can implement to do some bootstrapping work\n-# before the spawner starts. For example, create a directory for your user or\n-# load initial content.\n-# \n-# This can be set independent of any concrete spawner implementation.\n-# \n-# This maybe a coroutine.\n-# \n-# Example::\n-# \n-# def my_hook(spawner):\n-# username = spawner.user.name\n-# spawner.environment[\"GREETING\"] = f\"Hello {username}\"\n-# \n-# c.Spawner.pre_spawn_hook = my_hook\n-# Default: None\n-# c.Spawner.pre_spawn_hook = None\n-\n-## An optional hook function that you can implement to modify the ready event,\n-# which will be shown to the user on the spawn progress page when their server\n-# is ready.\n-# \n-# This can be set independent of any concrete spawner implementation.\n-# \n-# This maybe a coroutine.\n-# \n-# Example::\n-# \n-# async def my_ready_hook(spawner, ready_event):\n-# ready_event[\"html_message\"] = f\"Server {spawner.name} is ready for {spawner.user.name}\"\n-# return ready_event\n-# \n-# c.Spawner.progress_ready_hook = my_ready_hook\n-# Default: None\n-# c.Spawner.progress_ready_hook = None\n-\n-## The list of scopes to request for $JUPYTERHUB_API_TOKEN\n-# \n-# If not specified, the scopes in the `server` role will be used\n-# (unchanged from pre-4.0).\n-# \n-# If callable, will be called with the Spawner instance as its sole argument\n-# (JupyterHub user available as spawner.user).\n-# \n-# JUPYTERHUB_API_TOKEN will be assigned the _subset_ of these scopes\n-# that are held by the user (as in oauth_client_allowed_scopes).\n-# \n-# .. versionadded:: 4.0\n-# Default: traitlets.Undefined\n-# c.Spawner.server_token_scopes = traitlets.Undefined\n-\n-## List of SSL alt names\n-# \n-# May be set in config if all spawners should have the same value(s),\n-# or set at runtime by Spawner that know their names.\n-# Default: []\n-# c.Spawner.ssl_alt_names = []\n-\n-## Whether to include `DNS:localhost`, `IP:127.0.0.1` in alt names\n-# Default: True\n-# c.Spawner.ssl_alt_names_include_local = True\n-\n-## Timeout (in seconds) before giving up on starting of single-user server.\n-# \n-# This is the timeout for start to return, not the timeout for the server to\n-# respond. Callers of spawner.start will assume that startup has failed if it\n-# takes longer than this. start should return when the server process is started\n-# and its location is known.\n-# Default: 60\n-# c.Spawner.start_timeout = 60\n-\n-#------------------------------------------------------------------------------\n # LocalAuthenticator(Authenticator) configuration\n #------------------------------------------------------------------------------\n ## Base class for Authenticators that work with local Linux/UNIX users\n # \n # Checks for local users, and can attempt to create them if they exist.\n \n ## The command to use for creating users as a list of strings\n@@ -2339,469 +2799,9 @@\n # \n # Use via the encryption_config singleton below.\n \n # Default: []\n # c.CryptKeeper.keys = []\n \n ## The number of threads to allocate for encryption\n-# Default: 40\n-# c.CryptKeeper.n_threads = 40\n-\n-#------------------------------------------------------------------------------\n-# LocalProcessSpawner(Spawner) configuration\n-#------------------------------------------------------------------------------\n-## A Spawner that uses `subprocess.Popen` to start single-user servers as local\n-# processes.\n-# \n-# Requires local UNIX users matching the authenticated users to exist. Does not\n-# work on Windows.\n-# \n-# This is the default spawner for JupyterHub.\n-# \n-# Note: This spawner does not implement CPU / memory guarantees and limits.\n-\n-## \n-# See also: Spawner.args\n-# c.LocalProcessSpawner.args = []\n-\n-## \n-# See also: Spawner.auth_state_hook\n-# c.LocalProcessSpawner.auth_state_hook = None\n-\n-## \n-# See also: Spawner.cmd\n-# c.LocalProcessSpawner.cmd = ['jupyterhub-singleuser']\n-\n-## \n-# See also: Spawner.consecutive_failure_limit\n-# c.LocalProcessSpawner.consecutive_failure_limit = 0\n-\n-## \n-# See also: Spawner.cpu_guarantee\n-# c.LocalProcessSpawner.cpu_guarantee = None\n-\n-## \n-# See also: Spawner.cpu_limit\n-# c.LocalProcessSpawner.cpu_limit = None\n-\n-## Enable debug-logging of the single-user server\n-# See also: Spawner.debug\n-# c.LocalProcessSpawner.debug = False\n-\n-## \n-# See also: Spawner.default_url\n-# c.LocalProcessSpawner.default_url = ''\n-\n-## \n-# See also: Spawner.disable_user_config\n-# c.LocalProcessSpawner.disable_user_config = False\n-\n-## \n-# See also: Spawner.env_keep\n-# c.LocalProcessSpawner.env_keep = ['JUPYTERHUB_SINGLEUSER_APP']\n-\n-## \n-# See also: Spawner.environment\n-# c.LocalProcessSpawner.environment = {}\n-\n-## \n-# See also: Spawner.group_overrides\n-# c.LocalProcessSpawner.group_overrides = traitlets.Undefined\n-\n-## \n-# See also: Spawner.http_timeout\n-# c.LocalProcessSpawner.http_timeout = 30\n-\n-## \n-# See also: Spawner.hub_connect_url\n-# c.LocalProcessSpawner.hub_connect_url = None\n-\n-## Seconds to wait for single-user server process to halt after SIGINT.\n-# \n-# If the process has not exited cleanly after this many seconds, a SIGTERM is\n-# sent.\n-# Default: 10\n-# c.LocalProcessSpawner.interrupt_timeout = 10\n-\n-## \n-# See also: Spawner.ip\n-# c.LocalProcessSpawner.ip = '127.0.0.1'\n-\n-## Seconds to wait for process to halt after SIGKILL before giving up.\n-# \n-# If the process does not exit cleanly after this many seconds of SIGKILL, it\n-# becomes a zombie process. The hub process will log a warning and then give up.\n-# Default: 5\n-# c.LocalProcessSpawner.kill_timeout = 5\n-\n-## \n-# See also: Spawner.mem_guarantee\n-# c.LocalProcessSpawner.mem_guarantee = None\n-\n-## \n-# See also: Spawner.mem_limit\n-# c.LocalProcessSpawner.mem_limit = None\n-\n-## \n-# See also: Spawner.notebook_dir\n-# c.LocalProcessSpawner.notebook_dir = ''\n-\n-## Allowed scopes for oauth tokens issued by this server's oauth client.\n-# See also: Spawner.oauth_client_allowed_scopes\n-# c.LocalProcessSpawner.oauth_client_allowed_scopes = traitlets.Undefined\n-\n-## Allowed roles for oauth tokens.\n-# See also: Spawner.oauth_roles\n-# c.LocalProcessSpawner.oauth_roles = traitlets.Undefined\n-\n-## \n-# See also: Spawner.options_form\n-# c.LocalProcessSpawner.options_form = traitlets.Undefined\n-\n-## \n-# See also: Spawner.options_from_form\n-# c.LocalProcessSpawner.options_from_form = traitlets.Undefined\n-\n-## \n-# See also: Spawner.poll_interval\n-# c.LocalProcessSpawner.poll_interval = 30\n-\n-## \n-# See also: Spawner.poll_jitter\n-# c.LocalProcessSpawner.poll_jitter = 0.1\n-\n-## Extra keyword arguments to pass to Popen\n-# \n-# when spawning single-user servers.\n-# \n-# For example::\n-# \n-# popen_kwargs = dict(shell=True)\n-# Default: {}\n-# c.LocalProcessSpawner.popen_kwargs = {}\n-\n-## \n-# See also: Spawner.port\n-# c.LocalProcessSpawner.port = 0\n-\n-## \n-# See also: Spawner.post_stop_hook\n-# c.LocalProcessSpawner.post_stop_hook = None\n-\n-## \n-# See also: Spawner.pre_spawn_hook\n-# c.LocalProcessSpawner.pre_spawn_hook = None\n-\n-## \n-# See also: Spawner.progress_ready_hook\n-# c.LocalProcessSpawner.progress_ready_hook = None\n-\n-## The list of scopes to request for $JUPYTERHUB_API_TOKEN\n-# See also: Spawner.server_token_scopes\n-# c.LocalProcessSpawner.server_token_scopes = traitlets.Undefined\n-\n-## Specify a shell command to launch.\n-# \n-# The single-user command will be appended to this list,\n-# so it sould end with `-c` (for bash) or equivalent.\n-# \n-# For example::\n-# \n-# c.LocalProcessSpawner.shell_cmd = ['bash', '-l', '-c']\n-# \n-# to launch with a bash login shell, which would set up the user's own\n-# complete environment.\n-# \n-# .. warning::\n-# \n-# Using shell_cmd gives users control over PATH, etc.,\n-# which could change what the jupyterhub-singleuser launch command does.\n-# Only use this for trusted users.\n-# Default: []\n-# c.LocalProcessSpawner.shell_cmd = []\n-\n-## List of SSL alt names\n-# See also: Spawner.ssl_alt_names\n-# c.LocalProcessSpawner.ssl_alt_names = []\n-\n-## Whether to include `DNS:localhost`, `IP:127.0.0.1` in alt names\n-# See also: Spawner.ssl_alt_names_include_local\n-# c.LocalProcessSpawner.ssl_alt_names_include_local = True\n-\n-## \n-# See also: Spawner.start_timeout\n-# c.LocalProcessSpawner.start_timeout = 60\n-\n-## Seconds to wait for single-user server process to halt after SIGTERM.\n-# \n-# If the process does not exit cleanly after this many seconds of SIGTERM, a\n-# SIGKILL is sent.\n-# Default: 5\n-# c.LocalProcessSpawner.term_timeout = 5\n-\n-#------------------------------------------------------------------------------\n-# DummyAuthenticator(Authenticator) configuration\n-#------------------------------------------------------------------------------\n-## Dummy Authenticator for testing\n-# \n-# By default, any username + password is allowed If a non-empty password is set,\n-# any username will be allowed if it logs in with that password.\n-# \n-# .. versionadded:: 1.0\n-# \n-# .. versionadded:: 5.0\n-# `allow_all` defaults to True,\n-# preserving default behavior.\n-\n-## \n-# See also: Authenticator.admin_users\n-# c.DummyAuthenticator.admin_users = set()\n-\n-## \n-# See also: Authenticator.allow_all\n-# c.DummyAuthenticator.allow_all = False\n-\n-## \n-# See also: Authenticator.allow_existing_users\n-# c.DummyAuthenticator.allow_existing_users = False\n-\n-## \n-# See also: Authenticator.allowed_users\n-# c.DummyAuthenticator.allowed_users = set()\n-\n-## Is there any allow config?\n-# See also: Authenticator.any_allow_config\n-# c.DummyAuthenticator.any_allow_config = False\n-\n-## The max age (in seconds) of authentication info\n-# See also: Authenticator.auth_refresh_age\n-# c.DummyAuthenticator.auth_refresh_age = 300\n-\n-## Automatically begin the login process\n-# See also: Authenticator.auto_login\n-# c.DummyAuthenticator.auto_login = False\n-\n-## \n-# See also: Authenticator.auto_login_oauth2_authorize\n-# c.DummyAuthenticator.auto_login_oauth2_authorize = False\n-\n-## \n-# See also: Authenticator.blocked_users\n-# c.DummyAuthenticator.blocked_users = set()\n-\n-## Delete any users from the database that do not pass validation\n-# See also: Authenticator.delete_invalid_users\n-# c.DummyAuthenticator.delete_invalid_users = False\n-\n-## Enable persisting auth_state (if available).\n-# See also: Authenticator.enable_auth_state\n-# c.DummyAuthenticator.enable_auth_state = False\n-\n-## Let authenticator manage user groups\n-# See also: Authenticator.manage_groups\n-# c.DummyAuthenticator.manage_groups = False\n-\n-## Let authenticator manage roles\n-# See also: Authenticator.manage_roles\n-# c.DummyAuthenticator.manage_roles = False\n-\n-## \n-# See also: Authenticator.otp_prompt\n-# c.DummyAuthenticator.otp_prompt = 'OTP:'\n-\n-## Set a global password for all users wanting to log in.\n-# \n-# This allows users with any username to log in with the same static password.\n-# Default: ''\n-# c.DummyAuthenticator.password = ''\n-\n-## \n-# See also: Authenticator.post_auth_hook\n-# c.DummyAuthenticator.post_auth_hook = None\n-\n-## Force refresh of auth prior to spawn.\n-# See also: Authenticator.refresh_pre_spawn\n-# c.DummyAuthenticator.refresh_pre_spawn = False\n-\n-## \n-# See also: Authenticator.request_otp\n-# c.DummyAuthenticator.request_otp = False\n-\n-## Reset managed roles to result of `load_managed_roles()` on startup.\n-# See also: Authenticator.reset_managed_roles_on_startup\n-# c.DummyAuthenticator.reset_managed_roles_on_startup = False\n-\n-## Dictionary mapping authenticator usernames to JupyterHub users.\n-# See also: Authenticator.username_map\n-# c.DummyAuthenticator.username_map = {}\n-\n-## \n-# See also: Authenticator.username_pattern\n-# c.DummyAuthenticator.username_pattern = ''\n-\n-## Deprecated, use `Authenticator.allowed_users`\n-# See also: Authenticator.whitelist\n-# c.DummyAuthenticator.whitelist = set()\n-\n-#------------------------------------------------------------------------------\n-# SimpleLocalProcessSpawner(LocalProcessSpawner) configuration\n-#------------------------------------------------------------------------------\n-## A version of LocalProcessSpawner that doesn't require users to exist on the\n-# system beforehand.\n-# \n-# Only use this for testing.\n-# \n-# Note: DO NOT USE THIS FOR PRODUCTION USE CASES! It is very insecure, and\n-# provides absolutely no isolation between different users!\n-\n-## \n-# See also: Spawner.args\n-# c.SimpleLocalProcessSpawner.args = []\n-\n-## \n-# See also: Spawner.auth_state_hook\n-# c.SimpleLocalProcessSpawner.auth_state_hook = None\n-\n-## \n-# See also: Spawner.cmd\n-# c.SimpleLocalProcessSpawner.cmd = ['jupyterhub-singleuser']\n-\n-## \n-# See also: Spawner.consecutive_failure_limit\n-# c.SimpleLocalProcessSpawner.consecutive_failure_limit = 0\n-\n-## \n-# See also: Spawner.cpu_guarantee\n-# c.SimpleLocalProcessSpawner.cpu_guarantee = None\n-\n-## \n-# See also: Spawner.cpu_limit\n-# c.SimpleLocalProcessSpawner.cpu_limit = None\n-\n-## Enable debug-logging of the single-user server\n-# See also: Spawner.debug\n-# c.SimpleLocalProcessSpawner.debug = False\n-\n-## \n-# See also: Spawner.default_url\n-# c.SimpleLocalProcessSpawner.default_url = ''\n-\n-## \n-# See also: Spawner.disable_user_config\n-# c.SimpleLocalProcessSpawner.disable_user_config = False\n-\n-## \n-# See also: Spawner.env_keep\n-# c.SimpleLocalProcessSpawner.env_keep = ['JUPYTERHUB_SINGLEUSER_APP']\n-\n-## \n-# See also: Spawner.environment\n-# c.SimpleLocalProcessSpawner.environment = {}\n-\n-## \n-# See also: Spawner.group_overrides\n-# c.SimpleLocalProcessSpawner.group_overrides = traitlets.Undefined\n-\n-## Template to expand to set the user home. {username} is expanded to the\n-# jupyterhub username.\n-# Default: '/tmp/{username}'\n-# c.SimpleLocalProcessSpawner.home_dir_template = '/tmp/{username}'\n-\n-## \n-# See also: Spawner.http_timeout\n-# c.SimpleLocalProcessSpawner.http_timeout = 30\n-\n-## \n-# See also: Spawner.hub_connect_url\n-# c.SimpleLocalProcessSpawner.hub_connect_url = None\n-\n-## \n-# See also: LocalProcessSpawner.interrupt_timeout\n-# c.SimpleLocalProcessSpawner.interrupt_timeout = 10\n-\n-## \n-# See also: Spawner.ip\n-# c.SimpleLocalProcessSpawner.ip = '127.0.0.1'\n-\n-## \n-# See also: LocalProcessSpawner.kill_timeout\n-# c.SimpleLocalProcessSpawner.kill_timeout = 5\n-\n-## \n-# See also: Spawner.mem_guarantee\n-# c.SimpleLocalProcessSpawner.mem_guarantee = None\n-\n-## \n-# See also: Spawner.mem_limit\n-# c.SimpleLocalProcessSpawner.mem_limit = None\n-\n-## \n-# See also: Spawner.notebook_dir\n-# c.SimpleLocalProcessSpawner.notebook_dir = ''\n-\n-## Allowed scopes for oauth tokens issued by this server's oauth client.\n-# See also: Spawner.oauth_client_allowed_scopes\n-# c.SimpleLocalProcessSpawner.oauth_client_allowed_scopes = traitlets.Undefined\n-\n-## Allowed roles for oauth tokens.\n-# See also: Spawner.oauth_roles\n-# c.SimpleLocalProcessSpawner.oauth_roles = traitlets.Undefined\n-\n-## \n-# See also: Spawner.options_form\n-# c.SimpleLocalProcessSpawner.options_form = traitlets.Undefined\n-\n-## \n-# See also: Spawner.options_from_form\n-# c.SimpleLocalProcessSpawner.options_from_form = traitlets.Undefined\n-\n-## \n-# See also: Spawner.poll_interval\n-# c.SimpleLocalProcessSpawner.poll_interval = 30\n-\n-## \n-# See also: Spawner.poll_jitter\n-# c.SimpleLocalProcessSpawner.poll_jitter = 0.1\n-\n-## Extra keyword arguments to pass to Popen\n-# See also: LocalProcessSpawner.popen_kwargs\n-# c.SimpleLocalProcessSpawner.popen_kwargs = {}\n-\n-## \n-# See also: Spawner.port\n-# c.SimpleLocalProcessSpawner.port = 0\n-\n-## \n-# See also: Spawner.post_stop_hook\n-# c.SimpleLocalProcessSpawner.post_stop_hook = None\n-\n-## \n-# See also: Spawner.pre_spawn_hook\n-# c.SimpleLocalProcessSpawner.pre_spawn_hook = None\n-\n-## \n-# See also: Spawner.progress_ready_hook\n-# c.SimpleLocalProcessSpawner.progress_ready_hook = None\n-\n-## The list of scopes to request for $JUPYTERHUB_API_TOKEN\n-# See also: Spawner.server_token_scopes\n-# c.SimpleLocalProcessSpawner.server_token_scopes = traitlets.Undefined\n-\n-## Specify a shell command to launch.\n-# See also: LocalProcessSpawner.shell_cmd\n-# c.SimpleLocalProcessSpawner.shell_cmd = []\n-\n-## List of SSL alt names\n-# See also: Spawner.ssl_alt_names\n-# c.SimpleLocalProcessSpawner.ssl_alt_names = []\n-\n-## Whether to include `DNS:localhost`, `IP:127.0.0.1` in alt names\n-# See also: Spawner.ssl_alt_names_include_local\n-# c.SimpleLocalProcessSpawner.ssl_alt_names_include_local = True\n-\n-## \n-# See also: Spawner.start_timeout\n-# c.SimpleLocalProcessSpawner.start_timeout = 60\n-\n-## \n-# See also: LocalProcessSpawner.term_timeout\n-# c.SimpleLocalProcessSpawner.term_timeout = 5\n+# Default: 42\n+# c.CryptKeeper.n_threads = 42\n"}]}]}]}]}