{"diffoscope-json-version": 1, "source1": "/srv/reproducible-results/rbuild-debian/r-b-build.uoFKAgTm/b1/jupyterhub_5.2.1+ds1-4_amd64.changes", "source2": "/srv/reproducible-results/rbuild-debian/r-b-build.uoFKAgTm/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- a39f1cef979db6ea4afb3470ecfc1a47 2021824 python optional jupyterhub_5.2.1+ds1-4_all.deb\n+ a55738cfee0525e7fe531a6e98f71f84 2022336 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 1962140 2025-05-28 09:40:25.000000 data.tar.xz\n+-rw-r--r-- 0 0 0 59488 2025-05-28 09:40:25.000000 control.tar.xz\n+-rw-r--r-- 0 0 0 1962656 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,561 +997,14 @@\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-# 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-# \n-# As of JupyterHub 2.0,\n-# full admin rights should not be required,\n-# and more precise permissions can be managed via roles.\n-# \n-# Caution:\n-# \n-# Adding users to `admin_users` can only *grant* admin rights,\n-# removing a username from the admin_users set **DOES NOT** remove admin rights previously granted.\n-# \n-# For an authoritative, restricted set of admins,\n-# assign explicit membership of the `admin` *role*::\n-# \n-# c.JupyterHub.load_roles = [\n-# {\n-# \"name\": \"admin\",\n-# \"users\": [\"admin1\", \"...\"],\n-# }\n-# ]\n-# \n-# Admin users can take every possible action on behalf of all users, for\n-# example:\n-# \n-# - Use the admin panel to see list of users logged in - Add / remove users in\n-# some authenticators - Restart / halt the hub - Start / stop users' single-user\n-# servers - Can access each individual users' single-user server\n-# \n-# Admin access should be treated the same way root access is.\n-# \n-# Defaults to an empty set, in which case no user has admin access.\n-# Default: set()\n-# c.Authenticator.admin_users = set()\n-\n-## Allow every user who can successfully authenticate to access JupyterHub.\n-# \n-# False by default, which means for most Authenticators, _some_ allow-related\n-# configuration is required to allow users to log in.\n-# \n-# Authenticator subclasses may override the default with e.g.::\n-# \n-# @default(\"allow_all\")\n-# def _default_allow_all(self):\n-# # if _any_ auth config (depends on the Authenticator)\n-# if self.allowed_users or self.allowed_groups or self.allow_existing_users:\n-# return False\n-# else:\n-# return True\n-# \n-# .. versionadded:: 5.0\n-# \n-# .. versionchanged:: 5.0\n-# Prior to 5.0, `allow_all` wasn't defined on its own,\n-# and was instead implicitly True when no allow config was provided,\n-# i.e. `allowed_users` unspecified or empty on the base Authenticator class.\n-# \n-# To preserve pre-5.0 behavior,\n-# set `allow_all = True` if you have no other allow configuration.\n-# Default: False\n-# c.Authenticator.allow_all = False\n-\n-## Allow existing users to login.\n-# \n-# Defaults to True if `allowed_users` is set for historical reasons, and False\n-# otherwise.\n-# \n-# With this enabled, all users present in the JupyterHub database are allowed to\n-# login. This has the effect of any user who has _previously_ been allowed to\n-# login via any means will continue to be allowed until the user is deleted via\n-# the /hub/admin page or REST API.\n-# \n-# .. warning::\n-# \n-# Before enabling this you should review the existing users in the\n-# JupyterHub admin panel at `/hub/admin`. You may find users existing\n-# there because they have previously been declared in config such as\n-# `allowed_users` or allowed to sign in.\n-# \n-# .. warning::\n-# \n-# When this is enabled and you wish to remove access for one or more\n-# users previously allowed, you must make sure that they\n-# are removed from the jupyterhub database. This can be tricky to do\n-# if you stop allowing an externally managed group of users for example.\n-# \n-# With this enabled, JupyterHub admin users can visit `/hub/admin` or use\n-# JupyterHub's REST API to add and remove users to manage who can login.\n-# \n-# .. versionadded:: 5.0\n-# Default: False\n-# c.Authenticator.allow_existing_users = False\n-\n-## Set of usernames that are allowed to log in.\n-# \n-# Use this to limit which authenticated users may login. Default behavior: only\n-# users in this set are allowed.\n-# \n-# If empty, does not perform any restriction, in which case any authenticated\n-# user is allowed.\n-# \n-# Authenticators may extend :meth:`.Authenticator.check_allowed` to combine\n-# `allowed_users` with other configuration to either expand or restrict access.\n-# \n-# .. versionchanged:: 1.2\n-# `Authenticator.whitelist` renamed to `allowed_users`\n-# Default: set()\n-# c.Authenticator.allowed_users = set()\n-\n-## Is there any allow config?\n-# \n-# Used to show a warning if it looks like nobody can access the Hub,\n-# which can happen when upgrading to JupyterHub 5,\n-# now that `allow_all` defaults to False.\n-# \n-# Deployments can set this explicitly to True to suppress\n-# the \"No allow config found\" warning.\n-# \n-# Will be True if any config tagged with `.tag(allow_config=True)`\n-# or starts with `allow` is truthy.\n-# \n-# .. versionadded:: 5.0\n-# Default: False\n-# c.Authenticator.any_allow_config = False\n-\n-## The max age (in seconds) of authentication info\n-# before forcing a refresh of user auth info.\n-# \n-# Refreshing auth info allows, e.g. requesting/re-validating auth\n-# tokens.\n-# \n-# See :meth:`.refresh_user` for what happens when user auth info is refreshed\n-# (nothing by default).\n-# Default: 300\n-# c.Authenticator.auth_refresh_age = 300\n-\n-## Automatically begin the login process\n-# \n-# rather than starting with a \"Login with...\" link at `/hub/login`\n-# \n-# To work, `.login_url()` must give a URL other than the default `/hub/login`,\n-# such as an oauth handler or another automatic login handler,\n-# registered with `.get_handlers()`.\n-# \n-# .. versionadded:: 0.8\n-# Default: False\n-# c.Authenticator.auto_login = False\n-\n-## Automatically begin login process for OAuth2 authorization requests\n-# \n-# When another application is using JupyterHub as OAuth2 provider, it sends\n-# users to `/hub/api/oauth2/authorize`. If the user isn't logged in already, and\n-# auto_login is not set, the user will be dumped on the hub's home page, without\n-# any context on what to do next.\n-# \n-# Setting this to true will automatically redirect users to login if they aren't\n-# logged in *only* on the `/hub/api/oauth2/authorize` endpoint.\n-# \n-# .. versionadded:: 1.5\n-# Default: False\n-# c.Authenticator.auto_login_oauth2_authorize = False\n-\n-## Set of usernames that are not allowed to log in.\n-# \n-# Use this with supported authenticators to restrict which users can not log in.\n-# This is an additional block list that further restricts users, beyond whatever\n-# restrictions the authenticator has in place.\n-# \n-# If empty, does not perform any additional restriction.\n-# \n-# .. versionadded: 0.9\n-# \n-# .. versionchanged:: 5.2\n-# Users blocked via `blocked_users` that may have logged in in the past\n-# have all permissions and group membership revoked\n-# and all servers stopped at JupyterHub startup.\n-# Previously, User permissions (e.g. API tokens)\n-# and servers were unaffected and required additional\n-# administrator operations to block after a user is added to `blocked_users`.\n-# \n-# .. versionchanged:: 1.2\n-# `Authenticator.blacklist` renamed to `blocked_users`\n-# Default: set()\n-# c.Authenticator.blocked_users = set()\n-\n-## Delete any users from the database that do not pass validation\n-# \n-# When JupyterHub starts, `.add_user` will be called\n-# on each user in the database to verify that all users are still valid.\n-# \n-# If `delete_invalid_users` is True,\n-# any users that do not pass validation will be deleted from the database.\n-# Use this if users might be deleted from an external system,\n-# such as local user accounts.\n-# \n-# If False (default), invalid users remain in the Hub's database\n-# and a warning will be issued.\n-# This is the default to avoid data loss due to config changes.\n-# Default: False\n-# c.Authenticator.delete_invalid_users = False\n-\n-## Enable persisting auth_state (if available).\n-# \n-# auth_state will be encrypted and stored in the Hub's database.\n-# This can include things like authentication tokens, etc.\n-# to be passed to Spawners as environment variables.\n-# \n-# Encrypting auth_state requires the cryptography package.\n-# \n-# Additionally, the JUPYTERHUB_CRYPT_KEY environment variable must\n-# contain one (or more, separated by ;) 32B encryption keys.\n-# These can be either base64 or hex-encoded.\n-# \n-# If encryption is unavailable, auth_state cannot be persisted.\n-# \n-# New in JupyterHub 0.8\n-# Default: False\n-# c.Authenticator.enable_auth_state = False\n-\n-## Let authenticator manage user groups\n-# \n-# If True, Authenticator.authenticate and/or .refresh_user\n-# may return a list of group names in the 'groups' field,\n-# which will be assigned to the user.\n-# \n-# All group-assignment APIs are disabled if this is True.\n-# Default: False\n-# c.Authenticator.manage_groups = False\n-\n-## Let authenticator manage roles\n-# \n-# If True, Authenticator.authenticate and/or .refresh_user\n-# may return a list of roles in the 'roles' field,\n-# which will be added to the database.\n-# \n-# When enabled, all role management will be handled by the\n-# authenticator; in particular, assignment of roles via\n-# `JupyterHub.load_roles` traitlet will not be possible.\n-# \n-# .. versionadded:: 5.0\n-# Default: False\n-# c.Authenticator.manage_roles = False\n-\n-## The prompt string for the extra OTP (One Time Password) field.\n-# \n-# .. versionadded:: 5.0\n-# Default: 'OTP:'\n-# c.Authenticator.otp_prompt = 'OTP:'\n-\n-## An optional hook function that you can implement to do some bootstrapping work\n-# during authentication. For example, loading user account details from an\n-# external system.\n-# \n-# This function is called after the user has passed all authentication checks\n-# and is ready to successfully authenticate. This function must return the\n-# auth_model dict reguardless of changes to it. The hook is called with 3\n-# positional arguments: `(authenticator, handler, auth_model)`.\n-# \n-# This may be a coroutine.\n-# \n-# .. versionadded: 1.0\n-# \n-# Example::\n-# \n-# import os\n-# import pwd\n-# def my_hook(authenticator, handler, auth_model):\n-# user_data = pwd.getpwnam(auth_model['name'])\n-# spawn_data = {\n-# 'pw_data': user_data\n-# 'gid_list': os.getgrouplist(auth_model['name'], user_data.pw_gid)\n-# }\n-# \n-# if auth_model['auth_state'] is None:\n-# auth_model['auth_state'] = {}\n-# auth_model['auth_state']['spawn_data'] = spawn_data\n-# \n-# return auth_model\n-# \n-# c.Authenticator.post_auth_hook = my_hook\n-# Default: None\n-# c.Authenticator.post_auth_hook = None\n-\n-## Force refresh of auth prior to spawn.\n-# \n-# This forces :meth:`.refresh_user` to be called prior to launching\n-# a server, to ensure that auth state is up-to-date.\n-# \n-# This can be important when e.g. auth tokens that may have expired\n-# are passed to the spawner via environment variables from auth_state.\n-# \n-# If refresh_user cannot refresh the user auth data,\n-# launch will fail until the user logs in again.\n-# Default: False\n-# c.Authenticator.refresh_pre_spawn = False\n-\n-## Prompt for OTP (One Time Password) in the login form.\n-# \n-# .. versionadded:: 5.0\n-# Default: False\n-# c.Authenticator.request_otp = False\n-\n-## Reset managed roles to result of `load_managed_roles()` on startup.\n-# \n-# If True:\n-# - stale managed roles will be removed,\n-# - stale assignments to managed roles will be removed.\n-# \n-# Any role not present in `load_managed_roles()` will be considered\n-# 'stale'.\n-# \n-# The 'stale' status for role assignments is also determined from\n-# `load_managed_roles()` result:\n-# \n-# - user role assignments status will depend on whether the `users` key\n-# is defined or not:\n-# \n-# * if a list is defined under the `users` key and the user is not listed, then the user role assignment will be considered 'stale',\n-# * if the `users` key is not provided, the user role assignment will be preserved;\n-# - service and group role assignments will be considered 'stale':\n-# \n-# * if not included in the `services` and `groups` list,\n-# * if the `services` and `groups` keys are not provided.\n-# \n-# .. versionadded:: 5.0\n-# Default: False\n-# c.Authenticator.reset_managed_roles_on_startup = False\n-\n-## Dictionary mapping authenticator usernames to JupyterHub users.\n-# \n-# Primarily used to normalize OAuth user names to local users.\n-# Default: {}\n-# c.Authenticator.username_map = {}\n-\n-## Regular expression pattern that all valid usernames must match.\n-# \n-# If a username does not match the pattern specified here, authentication will\n-# not be attempted.\n-# \n-# If not set, allow any username.\n-# Default: ''\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-# .. versionadded:: 2.0\n-\n-## \n-# See also: Authenticator.admin_users\n-# c.NullAuthenticator.admin_users = set()\n-\n-## \n-# See also: Authenticator.allow_all\n-# c.NullAuthenticator.allow_all = False\n-\n-## \n-# See also: Authenticator.allow_existing_users\n-# c.NullAuthenticator.allow_existing_users = False\n-\n-## \n-# See also: Authenticator.allowed_users\n-# c.NullAuthenticator.allowed_users = set()\n-\n-## Is there any allow config?\n-# See also: Authenticator.any_allow_config\n-# c.NullAuthenticator.any_allow_config = False\n-\n-## The max age (in seconds) of authentication info\n-# See also: Authenticator.auth_refresh_age\n-# c.NullAuthenticator.auth_refresh_age = 300\n-\n-## \n-# See also: Authenticator.auto_login_oauth2_authorize\n-# c.NullAuthenticator.auto_login_oauth2_authorize = False\n-\n-## \n-# See also: Authenticator.blocked_users\n-# c.NullAuthenticator.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.NullAuthenticator.delete_invalid_users = False\n-\n-## Enable persisting auth_state (if available).\n-# See also: Authenticator.enable_auth_state\n-# c.NullAuthenticator.enable_auth_state = False\n-\n-## Let authenticator manage user groups\n-# See also: Authenticator.manage_groups\n-# c.NullAuthenticator.manage_groups = False\n-\n-## Let authenticator manage roles\n-# See also: Authenticator.manage_roles\n-# c.NullAuthenticator.manage_roles = False\n-\n-## \n-# See also: Authenticator.otp_prompt\n-# c.NullAuthenticator.otp_prompt = 'OTP:'\n-\n-## \n-# See also: Authenticator.post_auth_hook\n-# c.NullAuthenticator.post_auth_hook = None\n-\n-## Force refresh of auth prior to spawn.\n-# See also: Authenticator.refresh_pre_spawn\n-# c.NullAuthenticator.refresh_pre_spawn = False\n-\n-## \n-# See also: Authenticator.request_otp\n-# c.NullAuthenticator.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.NullAuthenticator.reset_managed_roles_on_startup = False\n-\n-## Dictionary mapping authenticator usernames to JupyterHub users.\n-# See also: Authenticator.username_map\n-# c.NullAuthenticator.username_map = {}\n-\n-## \n-# See also: Authenticator.username_pattern\n-# c.NullAuthenticator.username_pattern = ''\n-\n-## Deprecated, use `Authenticator.allowed_users`\n-# See also: Authenticator.whitelist\n-# c.NullAuthenticator.whitelist = set()\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@@ -2016,14 +1469,120 @@\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+# Proxy(LoggingConfigurable) configuration\n+#------------------------------------------------------------------------------\n+## Base class for configurable proxies that JupyterHub can use.\n+# \n+# A proxy implementation should subclass this and must define the following\n+# methods:\n+# \n+# - :meth:`.get_all_routes` return a dictionary of all JupyterHub-related routes\n+# - :meth:`.add_route` adds a route - :meth:`.delete_route` deletes a route\n+# \n+# In addition to these, the following method(s) may need to be implemented:\n+# \n+# - :meth:`.start` start the proxy, if it should be launched by the Hub\n+# instead of externally managed.\n+# If the proxy is externally managed, it should set :attr:`should_start` to False.\n+# - :meth:`.stop` stop the proxy. Only used if :meth:`.start` is also used.\n+# \n+# And the following method(s) are optional, but can be provided:\n+# \n+# - :meth:`.get_route` gets a single route.\n+# There is a default implementation that extracts data from :meth:`.get_all_routes`,\n+# but implementations may choose to provide a more efficient implementation\n+# of fetching a single route.\n+\n+## Additional routes to be maintained in the proxy.\n+# \n+# A dictionary with a route specification as key, and a URL as target. The hub\n+# will ensure this route is present in the proxy.\n+# \n+# If the hub is running in host based mode (with JupyterHub.subdomain_host set),\n+# the routespec *must* have a domain component (example.com/my-url/). If the hub\n+# is not running in host based mode, the routespec *must not* have a domain\n+# component (/my-url/).\n+# \n+# Helpful when the hub is running in API-only mode.\n+# Default: {}\n+# c.Proxy.extra_routes = {}\n+\n+## Should the Hub start the proxy\n+# \n+# If True, the Hub will start the proxy and stop it.\n+# Set to False if the proxy is managed externally,\n+# such as by systemd, docker, or another service manager.\n+# Default: True\n+# c.Proxy.should_start = True\n+\n+#------------------------------------------------------------------------------\n+# ConfigurableHTTPProxy(Proxy) configuration\n+#------------------------------------------------------------------------------\n+## Proxy implementation for the default configurable-http-proxy.\n+# \n+# This is the default proxy implementation for running the nodejs proxy\n+# `configurable-http-proxy`.\n+# \n+# If the proxy should not be run as a subprocess of the Hub, (e.g. in a separate\n+# container), set::\n+# \n+# c.ConfigurableHTTPProxy.should_start = False\n+\n+## The ip (or hostname) of the proxy's API endpoint\n+# Default: ''\n+# c.ConfigurableHTTPProxy.api_url = ''\n+\n+## The Proxy auth token\n+# \n+# Loaded from the CONFIGPROXY_AUTH_TOKEN env variable by default.\n+# Default: ''\n+# c.ConfigurableHTTPProxy.auth_token = ''\n+\n+## Interval (in seconds) at which to check if the proxy is running.\n+# Default: 5\n+# c.ConfigurableHTTPProxy.check_running_interval = 5\n+\n+## The command to start the proxy\n+# Default: ['configurable-http-proxy']\n+# c.ConfigurableHTTPProxy.command = ['configurable-http-proxy']\n+\n+## The number of requests allowed to be concurrently outstanding to the proxy\n+# \n+# Limiting this number avoids potential timeout errors by sending too many\n+# requests to update the proxy at once\n+# Default: 10\n+# c.ConfigurableHTTPProxy.concurrency = 10\n+\n+## Add debug-level logging to the Proxy.\n+# Default: False\n+# c.ConfigurableHTTPProxy.debug = False\n+\n+## \n+# See also: Proxy.extra_routes\n+# c.ConfigurableHTTPProxy.extra_routes = {}\n+\n+## Proxy log level\n+# Choices: any of ['debug', 'info', 'warn', 'error'] (case-insensitive)\n+# Default: 'info'\n+# c.ConfigurableHTTPProxy.log_level = 'info'\n+\n+## File in which to write the PID of the proxy process.\n+# Default: 'jupyterhub-proxy.pid'\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 # 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@@ -2208,14 +1767,575 @@\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+# CryptKeeper(SingletonConfigurable) configuration\n+#------------------------------------------------------------------------------\n+## Encapsulate encryption configuration\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: 42\n+# c.CryptKeeper.n_threads = 42\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+# \n+# As of JupyterHub 2.0,\n+# full admin rights should not be required,\n+# and more precise permissions can be managed via roles.\n+# \n+# Caution:\n+# \n+# Adding users to `admin_users` can only *grant* admin rights,\n+# removing a username from the admin_users set **DOES NOT** remove admin rights previously granted.\n+# \n+# For an authoritative, restricted set of admins,\n+# assign explicit membership of the `admin` *role*::\n+# \n+# c.JupyterHub.load_roles = [\n+# {\n+# \"name\": \"admin\",\n+# \"users\": [\"admin1\", \"...\"],\n+# }\n+# ]\n+# \n+# Admin users can take every possible action on behalf of all users, for\n+# example:\n+# \n+# - Use the admin panel to see list of users logged in - Add / remove users in\n+# some authenticators - Restart / halt the hub - Start / stop users' single-user\n+# servers - Can access each individual users' single-user server\n+# \n+# Admin access should be treated the same way root access is.\n+# \n+# Defaults to an empty set, in which case no user has admin access.\n+# Default: set()\n+# c.Authenticator.admin_users = set()\n+\n+## Allow every user who can successfully authenticate to access JupyterHub.\n+# \n+# False by default, which means for most Authenticators, _some_ allow-related\n+# configuration is required to allow users to log in.\n+# \n+# Authenticator subclasses may override the default with e.g.::\n+# \n+# @default(\"allow_all\")\n+# def _default_allow_all(self):\n+# # if _any_ auth config (depends on the Authenticator)\n+# if self.allowed_users or self.allowed_groups or self.allow_existing_users:\n+# return False\n+# else:\n+# return True\n+# \n+# .. versionadded:: 5.0\n+# \n+# .. versionchanged:: 5.0\n+# Prior to 5.0, `allow_all` wasn't defined on its own,\n+# and was instead implicitly True when no allow config was provided,\n+# i.e. `allowed_users` unspecified or empty on the base Authenticator class.\n+# \n+# To preserve pre-5.0 behavior,\n+# set `allow_all = True` if you have no other allow configuration.\n+# Default: False\n+# c.Authenticator.allow_all = False\n+\n+## Allow existing users to login.\n+# \n+# Defaults to True if `allowed_users` is set for historical reasons, and False\n+# otherwise.\n+# \n+# With this enabled, all users present in the JupyterHub database are allowed to\n+# login. This has the effect of any user who has _previously_ been allowed to\n+# login via any means will continue to be allowed until the user is deleted via\n+# the /hub/admin page or REST API.\n+# \n+# .. warning::\n+# \n+# Before enabling this you should review the existing users in the\n+# JupyterHub admin panel at `/hub/admin`. You may find users existing\n+# there because they have previously been declared in config such as\n+# `allowed_users` or allowed to sign in.\n+# \n+# .. warning::\n+# \n+# When this is enabled and you wish to remove access for one or more\n+# users previously allowed, you must make sure that they\n+# are removed from the jupyterhub database. This can be tricky to do\n+# if you stop allowing an externally managed group of users for example.\n+# \n+# With this enabled, JupyterHub admin users can visit `/hub/admin` or use\n+# JupyterHub's REST API to add and remove users to manage who can login.\n+# \n+# .. versionadded:: 5.0\n+# Default: False\n+# c.Authenticator.allow_existing_users = False\n+\n+## Set of usernames that are allowed to log in.\n+# \n+# Use this to limit which authenticated users may login. Default behavior: only\n+# users in this set are allowed.\n+# \n+# If empty, does not perform any restriction, in which case any authenticated\n+# user is allowed.\n+# \n+# Authenticators may extend :meth:`.Authenticator.check_allowed` to combine\n+# `allowed_users` with other configuration to either expand or restrict access.\n+# \n+# .. versionchanged:: 1.2\n+# `Authenticator.whitelist` renamed to `allowed_users`\n+# Default: set()\n+# c.Authenticator.allowed_users = set()\n+\n+## Is there any allow config?\n+# \n+# Used to show a warning if it looks like nobody can access the Hub,\n+# which can happen when upgrading to JupyterHub 5,\n+# now that `allow_all` defaults to False.\n+# \n+# Deployments can set this explicitly to True to suppress\n+# the \"No allow config found\" warning.\n+# \n+# Will be True if any config tagged with `.tag(allow_config=True)`\n+# or starts with `allow` is truthy.\n+# \n+# .. versionadded:: 5.0\n+# Default: False\n+# c.Authenticator.any_allow_config = False\n+\n+## The max age (in seconds) of authentication info\n+# before forcing a refresh of user auth info.\n+# \n+# Refreshing auth info allows, e.g. requesting/re-validating auth\n+# tokens.\n+# \n+# See :meth:`.refresh_user` for what happens when user auth info is refreshed\n+# (nothing by default).\n+# Default: 300\n+# c.Authenticator.auth_refresh_age = 300\n+\n+## Automatically begin the login process\n+# \n+# rather than starting with a \"Login with...\" link at `/hub/login`\n+# \n+# To work, `.login_url()` must give a URL other than the default `/hub/login`,\n+# such as an oauth handler or another automatic login handler,\n+# registered with `.get_handlers()`.\n+# \n+# .. versionadded:: 0.8\n+# Default: False\n+# c.Authenticator.auto_login = False\n+\n+## Automatically begin login process for OAuth2 authorization requests\n+# \n+# When another application is using JupyterHub as OAuth2 provider, it sends\n+# users to `/hub/api/oauth2/authorize`. If the user isn't logged in already, and\n+# auto_login is not set, the user will be dumped on the hub's home page, without\n+# any context on what to do next.\n+# \n+# Setting this to true will automatically redirect users to login if they aren't\n+# logged in *only* on the `/hub/api/oauth2/authorize` endpoint.\n+# \n+# .. versionadded:: 1.5\n+# Default: False\n+# c.Authenticator.auto_login_oauth2_authorize = False\n+\n+## Set of usernames that are not allowed to log in.\n+# \n+# Use this with supported authenticators to restrict which users can not log in.\n+# This is an additional block list that further restricts users, beyond whatever\n+# restrictions the authenticator has in place.\n+# \n+# If empty, does not perform any additional restriction.\n+# \n+# .. versionadded: 0.9\n+# \n+# .. versionchanged:: 5.2\n+# Users blocked via `blocked_users` that may have logged in in the past\n+# have all permissions and group membership revoked\n+# and all servers stopped at JupyterHub startup.\n+# Previously, User permissions (e.g. API tokens)\n+# and servers were unaffected and required additional\n+# administrator operations to block after a user is added to `blocked_users`.\n+# \n+# .. versionchanged:: 1.2\n+# `Authenticator.blacklist` renamed to `blocked_users`\n+# Default: set()\n+# c.Authenticator.blocked_users = set()\n+\n+## Delete any users from the database that do not pass validation\n+# \n+# When JupyterHub starts, `.add_user` will be called\n+# on each user in the database to verify that all users are still valid.\n+# \n+# If `delete_invalid_users` is True,\n+# any users that do not pass validation will be deleted from the database.\n+# Use this if users might be deleted from an external system,\n+# such as local user accounts.\n+# \n+# If False (default), invalid users remain in the Hub's database\n+# and a warning will be issued.\n+# This is the default to avoid data loss due to config changes.\n+# Default: False\n+# c.Authenticator.delete_invalid_users = False\n+\n+## Enable persisting auth_state (if available).\n+# \n+# auth_state will be encrypted and stored in the Hub's database.\n+# This can include things like authentication tokens, etc.\n+# to be passed to Spawners as environment variables.\n+# \n+# Encrypting auth_state requires the cryptography package.\n+# \n+# Additionally, the JUPYTERHUB_CRYPT_KEY environment variable must\n+# contain one (or more, separated by ;) 32B encryption keys.\n+# These can be either base64 or hex-encoded.\n+# \n+# If encryption is unavailable, auth_state cannot be persisted.\n+# \n+# New in JupyterHub 0.8\n+# Default: False\n+# c.Authenticator.enable_auth_state = False\n+\n+## Let authenticator manage user groups\n+# \n+# If True, Authenticator.authenticate and/or .refresh_user\n+# may return a list of group names in the 'groups' field,\n+# which will be assigned to the user.\n+# \n+# All group-assignment APIs are disabled if this is True.\n+# Default: False\n+# c.Authenticator.manage_groups = False\n+\n+## Let authenticator manage roles\n+# \n+# If True, Authenticator.authenticate and/or .refresh_user\n+# may return a list of roles in the 'roles' field,\n+# which will be added to the database.\n+# \n+# When enabled, all role management will be handled by the\n+# authenticator; in particular, assignment of roles via\n+# `JupyterHub.load_roles` traitlet will not be possible.\n+# \n+# .. versionadded:: 5.0\n+# Default: False\n+# c.Authenticator.manage_roles = False\n+\n+## The prompt string for the extra OTP (One Time Password) field.\n+# \n+# .. versionadded:: 5.0\n+# Default: 'OTP:'\n+# c.Authenticator.otp_prompt = 'OTP:'\n+\n+## An optional hook function that you can implement to do some bootstrapping work\n+# during authentication. For example, loading user account details from an\n+# external system.\n+# \n+# This function is called after the user has passed all authentication checks\n+# and is ready to successfully authenticate. This function must return the\n+# auth_model dict reguardless of changes to it. The hook is called with 3\n+# positional arguments: `(authenticator, handler, auth_model)`.\n+# \n+# This may be a coroutine.\n+# \n+# .. versionadded: 1.0\n+# \n+# Example::\n+# \n+# import os\n+# import pwd\n+# def my_hook(authenticator, handler, auth_model):\n+# user_data = pwd.getpwnam(auth_model['name'])\n+# spawn_data = {\n+# 'pw_data': user_data\n+# 'gid_list': os.getgrouplist(auth_model['name'], user_data.pw_gid)\n+# }\n+# \n+# if auth_model['auth_state'] is None:\n+# auth_model['auth_state'] = {}\n+# auth_model['auth_state']['spawn_data'] = spawn_data\n+# \n+# return auth_model\n+# \n+# c.Authenticator.post_auth_hook = my_hook\n+# Default: None\n+# c.Authenticator.post_auth_hook = None\n+\n+## Force refresh of auth prior to spawn.\n+# \n+# This forces :meth:`.refresh_user` to be called prior to launching\n+# a server, to ensure that auth state is up-to-date.\n+# \n+# This can be important when e.g. auth tokens that may have expired\n+# are passed to the spawner via environment variables from auth_state.\n+# \n+# If refresh_user cannot refresh the user auth data,\n+# launch will fail until the user logs in again.\n+# Default: False\n+# c.Authenticator.refresh_pre_spawn = False\n+\n+## Prompt for OTP (One Time Password) in the login form.\n+# \n+# .. versionadded:: 5.0\n+# Default: False\n+# c.Authenticator.request_otp = False\n+\n+## Reset managed roles to result of `load_managed_roles()` on startup.\n+# \n+# If True:\n+# - stale managed roles will be removed,\n+# - stale assignments to managed roles will be removed.\n+# \n+# Any role not present in `load_managed_roles()` will be considered\n+# 'stale'.\n+# \n+# The 'stale' status for role assignments is also determined from\n+# `load_managed_roles()` result:\n+# \n+# - user role assignments status will depend on whether the `users` key\n+# is defined or not:\n+# \n+# * if a list is defined under the `users` key and the user is not listed, then the user role assignment will be considered 'stale',\n+# * if the `users` key is not provided, the user role assignment will be preserved;\n+# - service and group role assignments will be considered 'stale':\n+# \n+# * if not included in the `services` and `groups` list,\n+# * if the `services` and `groups` keys are not provided.\n+# \n+# .. versionadded:: 5.0\n+# Default: False\n+# c.Authenticator.reset_managed_roles_on_startup = False\n+\n+## Dictionary mapping authenticator usernames to JupyterHub users.\n+# \n+# Primarily used to normalize OAuth user names to local users.\n+# Default: {}\n+# c.Authenticator.username_map = {}\n+\n+## Regular expression pattern that all valid usernames must match.\n+# \n+# If a username does not match the pattern specified here, authentication will\n+# not be attempted.\n+# \n+# If not set, allow any username.\n+# Default: ''\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+# .. versionadded:: 2.0\n+\n+## \n+# See also: Authenticator.admin_users\n+# c.NullAuthenticator.admin_users = set()\n+\n+## \n+# See also: Authenticator.allow_all\n+# c.NullAuthenticator.allow_all = False\n+\n+## \n+# See also: Authenticator.allow_existing_users\n+# c.NullAuthenticator.allow_existing_users = False\n+\n+## \n+# See also: Authenticator.allowed_users\n+# c.NullAuthenticator.allowed_users = set()\n+\n+## Is there any allow config?\n+# See also: Authenticator.any_allow_config\n+# c.NullAuthenticator.any_allow_config = False\n+\n+## The max age (in seconds) of authentication info\n+# See also: Authenticator.auth_refresh_age\n+# c.NullAuthenticator.auth_refresh_age = 300\n+\n+## \n+# See also: Authenticator.auto_login_oauth2_authorize\n+# c.NullAuthenticator.auto_login_oauth2_authorize = False\n+\n+## \n+# See also: Authenticator.blocked_users\n+# c.NullAuthenticator.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.NullAuthenticator.delete_invalid_users = False\n+\n+## Enable persisting auth_state (if available).\n+# See also: Authenticator.enable_auth_state\n+# c.NullAuthenticator.enable_auth_state = False\n+\n+## Let authenticator manage user groups\n+# See also: Authenticator.manage_groups\n+# c.NullAuthenticator.manage_groups = False\n+\n+## Let authenticator manage roles\n+# See also: Authenticator.manage_roles\n+# c.NullAuthenticator.manage_roles = False\n+\n+## \n+# See also: Authenticator.otp_prompt\n+# c.NullAuthenticator.otp_prompt = 'OTP:'\n+\n+## \n+# See also: Authenticator.post_auth_hook\n+# c.NullAuthenticator.post_auth_hook = None\n+\n+## Force refresh of auth prior to spawn.\n+# See also: Authenticator.refresh_pre_spawn\n+# c.NullAuthenticator.refresh_pre_spawn = False\n+\n+## \n+# See also: Authenticator.request_otp\n+# c.NullAuthenticator.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.NullAuthenticator.reset_managed_roles_on_startup = False\n+\n+## Dictionary mapping authenticator usernames to JupyterHub users.\n+# See also: Authenticator.username_map\n+# c.NullAuthenticator.username_map = {}\n+\n+## \n+# See also: Authenticator.username_pattern\n+# c.NullAuthenticator.username_pattern = ''\n+\n+## Deprecated, use `Authenticator.allowed_users`\n+# See also: Authenticator.whitelist\n+# c.NullAuthenticator.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@@ -2681,127 +2801,7 @@\n ## \n # See also: Authenticator.username_pattern\n # c.PAMAuthenticator.username_pattern = ''\n \n ## Deprecated, use `Authenticator.allowed_users`\n # See also: Authenticator.whitelist\n # c.PAMAuthenticator.whitelist = set()\n-\n-#------------------------------------------------------------------------------\n-# CryptKeeper(SingletonConfigurable) configuration\n-#------------------------------------------------------------------------------\n-## Encapsulate encryption configuration\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-# Proxy(LoggingConfigurable) configuration\n-#------------------------------------------------------------------------------\n-## Base class for configurable proxies that JupyterHub can use.\n-# \n-# A proxy implementation should subclass this and must define the following\n-# methods:\n-# \n-# - :meth:`.get_all_routes` return a dictionary of all JupyterHub-related routes\n-# - :meth:`.add_route` adds a route - :meth:`.delete_route` deletes a route\n-# \n-# In addition to these, the following method(s) may need to be implemented:\n-# \n-# - :meth:`.start` start the proxy, if it should be launched by the Hub\n-# instead of externally managed.\n-# If the proxy is externally managed, it should set :attr:`should_start` to False.\n-# - :meth:`.stop` stop the proxy. Only used if :meth:`.start` is also used.\n-# \n-# And the following method(s) are optional, but can be provided:\n-# \n-# - :meth:`.get_route` gets a single route.\n-# There is a default implementation that extracts data from :meth:`.get_all_routes`,\n-# but implementations may choose to provide a more efficient implementation\n-# of fetching a single route.\n-\n-## Additional routes to be maintained in the proxy.\n-# \n-# A dictionary with a route specification as key, and a URL as target. The hub\n-# will ensure this route is present in the proxy.\n-# \n-# If the hub is running in host based mode (with JupyterHub.subdomain_host set),\n-# the routespec *must* have a domain component (example.com/my-url/). If the hub\n-# is not running in host based mode, the routespec *must not* have a domain\n-# component (/my-url/).\n-# \n-# Helpful when the hub is running in API-only mode.\n-# Default: {}\n-# c.Proxy.extra_routes = {}\n-\n-## Should the Hub start the proxy\n-# \n-# If True, the Hub will start the proxy and stop it.\n-# Set to False if the proxy is managed externally,\n-# such as by systemd, docker, or another service manager.\n-# Default: True\n-# c.Proxy.should_start = True\n-\n-#------------------------------------------------------------------------------\n-# ConfigurableHTTPProxy(Proxy) configuration\n-#------------------------------------------------------------------------------\n-## Proxy implementation for the default configurable-http-proxy.\n-# \n-# This is the default proxy implementation for running the nodejs proxy\n-# `configurable-http-proxy`.\n-# \n-# If the proxy should not be run as a subprocess of the Hub, (e.g. in a separate\n-# container), set::\n-# \n-# c.ConfigurableHTTPProxy.should_start = False\n-\n-## The ip (or hostname) of the proxy's API endpoint\n-# Default: ''\n-# c.ConfigurableHTTPProxy.api_url = ''\n-\n-## The Proxy auth token\n-# \n-# Loaded from the CONFIGPROXY_AUTH_TOKEN env variable by default.\n-# Default: ''\n-# c.ConfigurableHTTPProxy.auth_token = ''\n-\n-## Interval (in seconds) at which to check if the proxy is running.\n-# Default: 5\n-# c.ConfigurableHTTPProxy.check_running_interval = 5\n-\n-## The command to start the proxy\n-# Default: ['configurable-http-proxy']\n-# c.ConfigurableHTTPProxy.command = ['configurable-http-proxy']\n-\n-## The number of requests allowed to be concurrently outstanding to the proxy\n-# \n-# Limiting this number avoids potential timeout errors by sending too many\n-# requests to update the proxy at once\n-# Default: 10\n-# c.ConfigurableHTTPProxy.concurrency = 10\n-\n-## Add debug-level logging to the Proxy.\n-# Default: False\n-# c.ConfigurableHTTPProxy.debug = False\n-\n-## \n-# See also: Proxy.extra_routes\n-# c.ConfigurableHTTPProxy.extra_routes = {}\n-\n-## Proxy log level\n-# Choices: any of ['debug', 'info', 'warn', 'error'] (case-insensitive)\n-# Default: 'info'\n-# c.ConfigurableHTTPProxy.log_level = 'info'\n-\n-## File in which to write the PID of the proxy process.\n-# Default: 'jupyterhub-proxy.pid'\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"}]}]}]}]}