v0.15.0
Loading...
Searching...
No Matches
jupyterhub_config.py
Go to the documentation of this file.
1# Configuration file for jupyterhub.
2
3#------------------------------------------------------------------------------
4# Application(SingletonConfigurable) configuration
5#------------------------------------------------------------------------------
6## This is an application.
7
8## The date format used by logging formatters for %(asctime)s
9# Default: '%Y-%m-%d %H:%M:%S'
10# c.Application.log_datefmt = '%Y-%m-%d %H:%M:%S'
11
12## The Logging format template
13# Default: '[%(name)s]%(highlevel)s %(message)s'
14# c.Application.log_format = '[%(name)s]%(highlevel)s %(message)s'
15
16## Set the log level by value or name.
17# Choices: any of [0, 10, 20, 30, 40, 50, 'DEBUG', 'INFO', 'WARN', 'ERROR', 'CRITICAL']
18# Default: 30
19# c.Application.log_level = 30
20
21## Instead of starting the Application, dump configuration to stdout
22# Default: False
23# c.Application.show_config = False
24
25## Instead of starting the Application, dump configuration to stdout (as JSON)
26# Default: False
27# c.Application.show_config_json = False
28
29#------------------------------------------------------------------------------
30# JupyterHub(Application) configuration
31#------------------------------------------------------------------------------
32## An Application for starting a Multi-User Jupyter Notebook server.
33
34## Maximum number of concurrent servers that can be active at a time.
35#
36# Setting this can limit the total resources your users can consume.
37#
38# An active server is any server that's not fully stopped. It is considered
39# active from the time it has been requested until the time that it has
40# completely stopped.
41#
42# If this many user servers are active, users will not be able to launch new
43# servers until a server is shutdown. Spawn requests will be rejected with a 429
44# error asking them to try again.
45#
46# If set to 0, no limit is enforced.
47# Default: 0
48c.JupyterHub.active_server_limit = 0
49
50## Duration (in seconds) to determine the number of active users.
51# Default: 1800
52#c.JupyterHub.active_user_window = 1800
53
54## Resolution (in seconds) for updating activity
55#
56# If activity is registered that is less than activity_resolution seconds more
57# recent than the current value, the new value will be ignored.
58#
59# This avoids too many writes to the Hub database.
60# Default: 30
61# c.JupyterHub.activity_resolution = 30
62
63## Grant admin users permission to access single-user servers.
64#
65# Users should be properly informed if this is enabled.
66# Default: False
67c.JupyterHub.admin_access = True
68
69## DEPRECATED since version 0.7.2, use Authenticator.admin_users instead.
70# Default: set()
71
72from firstuseauthenticator import FirstUseAuthenticator
73import subprocess
74import os
75
76# Authenticator config
77c.JupyterHub.authenticator_class = FirstUseAuthenticator
78
79# Allow admin to create users manually
80c.FirstUseAuthenticator.create_users = False
81
82# Disable open signup — no random logins
83c.FirstUseAuthenticator.open_signup = False
84
85# Admin settings
86c.Authenticator.admin_users = {"mofem"} # First user becomes admin
87
88c.JupyterHub.spawner_class = 'jupyterhub.spawner.LocalProcessSpawner'
89
90# Pre-spawn hook to create system user and home directory
91def setup_user_home(spawner):
92 username = spawner.user.name
93 home = f"/mofem_install/jupyter/{username}"
94 skel = "/mofem_install/jupyter/skel"
95
96 # locate current mofem spack configuration files
97 spack_config_packages = "/mofem_install/spack_config_dir/packages.yaml"
98 spack_config_repo = "/mofem_install/spack_config_dir/repos.yaml"
99 spack_config_dest = os.path.join(home, ".spack/")
100
101 spawner.log.info(f"Setting up home for {username} at {home}")
102
103 try:
104 subprocess.check_call(["id", username])
105 spawner.log.info(f"User {username} already exists")
106 except subprocess.CalledProcessError:
107 # create user and home directory
108 subprocess.check_call([
109 "useradd", "-m", "-d", home, "-k", skel, "-s", "/bin/bash", username
110 ])
111 # copy spack configuration files to user's home directory
112 os.makedirs(spack_config_dest, exist_ok=True)
113 subprocess.check_call(["cp", spack_config_packages, spack_config_dest])
114 subprocess.check_call(["cp", spack_config_repo, spack_config_dest])
115 # change md to ipynb in user's home directory when user is created
116 cmd = r'''grep -rl "jupyter:" --include="*.md" . | while read f; do
117 jupytext --to ipynb "$f" && rm "$f"
118 done'''
119 subprocess.run(cmd, shell=True, check=True)
120 # inform that user has been created
121 spawner.log.info(f"Created user {username} with home {home}")
122 # ensure home directory has correct permissions
123 subprocess.check_call(["chown", "-R", f"{username}:{username}", home])
124
125 spawner.environment["HOME"] = home
126 spawner.args = [f"--ServerApp.root_dir={home}"]
127
128# Set the pre-spawn hook to create user home directories
129c.Spawner.pre_spawn_hook = setup_user_home
130
131## Allow named single-user servers per user
132# Default: False
133# c.JupyterHub.allow_named_servers = False
134
135## Answer yes to any questions (e.g. confirm overwrite)
136# Default: False
137# c.JupyterHub.answer_yes = False
138
139## PENDING DEPRECATION: consider using services
140#
141# Dict of token:username to be loaded into the database.
142#
143# Allows ahead-of-time generation of API tokens for use by externally managed
144# services, which authenticate as JupyterHub users.
145#
146# Consider using services for general services that talk to the JupyterHub API.
147# Default: {}
148# c.JupyterHub.api_tokens = {}
149
150## Authentication for prometheus metrics
151# Default: True
152# c.JupyterHub.authenticate_prometheus = True
153
154## Class for authenticating users.
155#
156# This should be a subclass of :class:`jupyterhub.auth.Authenticator`
157#
158# with an :meth:`authenticate` method that:
159#
160# - is a coroutine (asyncio or tornado)
161# - returns username on success, None on failure
162# - takes two arguments: (handler, data),
163# where `handler` is the calling web.RequestHandler,
164# and `data` is the POST form data from the login page.
165#
166# .. versionchanged:: 1.0
167# authenticators may be registered via entry points,
168# e.g. `c.JupyterHub.authenticator_class = 'pam'`
169#
170# Currently installed:
171# - default: jupyterhub.auth.PAMAuthenticator
172# - dummy: jupyterhub.auth.DummyAuthenticator
173# - pam: jupyterhub.auth.PAMAuthenticator
174# Default: 'jupyterhub.auth.PAMAuthenticator'
175#c.JupyterHub.authenticator_class = 'dummyauthenticator.DummyAuthenticator'
176
177## The base URL of the entire application.
178#
179# Add this to the beginning of all JupyterHub URLs. Use base_url to run
180# JupyterHub within an existing website.
181#
182# .. deprecated: 0.9
183# Use JupyterHub.bind_url
184# Default: '/'
185# c.JupyterHub.base_url = '/'
186
187## The public facing URL of the whole JupyterHub application.
188#
189# This is the address on which the proxy will bind. Sets protocol, ip, base_url
190# Default: 'http://:8000'
191# c.JupyterHub.bind_url = 'http://:8000'
192
193## Whether to shutdown the proxy when the Hub shuts down.
194#
195# Disable if you want to be able to teardown the Hub while leaving the proxy
196# running.
197#
198# Only valid if the proxy was starting by the Hub process.
199#
200# If both this and cleanup_servers are False, sending SIGINT to the Hub will
201# only shutdown the Hub, leaving everything else running.
202#
203# The Hub should be able to resume from database state.
204# Default: True
205# c.JupyterHub.cleanup_proxy = True
206
207## Whether to shutdown single-user servers when the Hub shuts down.
208#
209# Disable if you want to be able to teardown the Hub while leaving the single-
210# user servers running.
211#
212# If both this and cleanup_proxy are False, sending SIGINT to the Hub will only
213# shutdown the Hub, leaving everything else running.
214#
215# The Hub should be able to resume from database state.
216# Default: True
217# c.JupyterHub.cleanup_servers = True
218
219## Maximum number of concurrent users that can be spawning at a time.
220#
221# Spawning lots of servers at the same time can cause performance problems for
222# the Hub or the underlying spawning system. Set this limit to prevent bursts of
223# logins from attempting to spawn too many servers at the same time.
224#
225# This does not limit the number of total running servers. See
226# active_server_limit for that.
227#
228# If more than this many users attempt to spawn at a time, their requests will
229# be rejected with a 429 error asking them to try again. Users will have to wait
230# for some of the spawning services to finish starting before they can start
231# their own.
232#
233# If set to 0, no limit is enforced.
234# Default: 100
235c.JupyterHub.concurrent_spawn_limit = 100
236
237## The config file to load
238# Default: 'jupyterhub_config.py'
239# c.JupyterHub.config_file = 'jupyterhub_config.py'
240
241## DEPRECATED: does nothing
242# Default: False
243# c.JupyterHub.confirm_no_ssl = False
244
245## Number of days for a login cookie to be valid. Default is two weeks.
246# Default: 14
247# c.JupyterHub.cookie_max_age_days = 14
248
249## The cookie secret to use to encrypt cookies.
250#
251# Loaded from the JPY_COOKIE_SECRET env variable by default.
252#
253# Should be exactly 256 bits (32 bytes).
254# Default: b''
255# c.JupyterHub.cookie_secret = b''
256
257## File in which to store the cookie secret.
258# Default: 'jupyterhub_cookie_secret'
259# c.JupyterHub.cookie_secret_file = 'jupyterhub_cookie_secret'
260
261## The location of jupyterhub data files (e.g. /usr/local/share/jupyterhub)
262# Default: '/usr/local/share/jupyterhub'
263# c.JupyterHub.data_files_path = '/usr/local/share/jupyterhub'
264
265## Include any kwargs to pass to the database connection. See
266# sqlalchemy.create_engine for details.
267# Default: {}
268# c.JupyterHub.db_kwargs = {}
269
270## url for the database. e.g. `sqlite:///jupyterhub.sqlite`
271# Default: 'sqlite:///jupyterhub.sqlite'
272# c.JupyterHub.db_url = 'sqlite:///jupyterhub.sqlite'
273
274## log all database transactions. This has A LOT of output
275# Default: False
276# c.JupyterHub.debug_db = False
277
278## DEPRECATED since version 0.8: Use ConfigurableHTTPProxy.debug
279# Default: False
280# c.JupyterHub.debug_proxy = False
281
282## If named servers are enabled, default name of server to spawn or open, e.g. by
283# user-redirect.
284# Default: ''
285# c.JupyterHub.default_server_name = ''
286
287## The default URL for users when they arrive (e.g. when user directs to "/")
288#
289# By default, redirects users to their own server.
290#
291# Can be a Unicode string (e.g. '/hub/home') or a callable based on the handler
292# object:
293#
294# ::
295#
296# def default_url_fn(handler):
297# user = handler.current_user
298# if user and user.admin:
299# return '/hub/admin'
300# return '/hub/home'
301#
302# c.JupyterHub.default_url = default_url_fn
303# Default: traitlets.Undefined
304# c.JupyterHub.default_url = traitlets.Undefined
305
306## Dict authority:dict(files). Specify the key, cert, and/or ca file for an
307# authority. This is useful for externally managed proxies that wish to use
308# internal_ssl.
309#
310# The files dict has this format (you must specify at least a cert)::
311#
312# {
313# 'key': '/path/to/key.key',
314# 'cert': '/path/to/cert.crt',
315# 'ca': '/path/to/ca.crt'
316# }
317#
318# The authorities you can override: 'hub-ca', 'notebooks-ca', 'proxy-api-ca',
319# 'proxy-client-ca', and 'services-ca'.
320#
321# Use with internal_ssl
322# Default: {}
323# c.JupyterHub.external_ssl_authorities = {}
324
325## Register extra tornado Handlers for jupyterhub.
326#
327# Should be of the form ``("<regex>", Handler)``
328#
329# The Hub prefix will be added, so `/my-page` will be served at `/hub/my-page`.
330# Default: []
331# c.JupyterHub.extra_handlers = []
332
333## DEPRECATED: use output redirection instead, e.g.
334#
335# jupyterhub &>> /var/log/jupyterhub.log
336# Default: ''
337# c.JupyterHub.extra_log_file = ''
338
339## Extra log handlers to set on JupyterHub logger
340# Default: []
341# c.JupyterHub.extra_log_handlers = []
342
343## Generate certs used for internal ssl
344# Default: False
345# c.JupyterHub.generate_certs = False
346
347## Generate default config file
348# Default: False
349# c.JupyterHub.generate_config = False
350
351## The URL on which the Hub will listen. This is a private URL for internal
352# communication. Typically set in combination with hub_connect_url. If a unix
353# socket, hub_connect_url **must** also be set.
354#
355# For example:
356#
357# "http://127.0.0.1:8081"
358# "unix+http://%2Fsrv%2Fjupyterhub%2Fjupyterhub.sock"
359#
360# .. versionadded:: 0.9
361# Default: ''
362# c.JupyterHub.hub_bind_url = ''
363
364## The ip or hostname for proxies and spawners to use for connecting to the Hub.
365#
366# Use when the bind address (`hub_ip`) is 0.0.0.0, :: or otherwise different
367# from the connect address.
368#
369# Default: when `hub_ip` is 0.0.0.0 or ::, use `socket.gethostname()`, otherwise
370# use `hub_ip`.
371#
372# Note: Some spawners or proxy implementations might not support hostnames.
373# Check your spawner or proxy documentation to see if they have extra
374# requirements.
375#
376# .. versionadded:: 0.8
377# Default: ''
378# c.JupyterHub.hub_connect_ip = ''
379
380## DEPRECATED
381#
382# Use hub_connect_url
383#
384# .. versionadded:: 0.8
385#
386# .. deprecated:: 0.9
387# Use hub_connect_url
388# Default: 0
389# c.JupyterHub.hub_connect_port = 0
390
391## The URL for connecting to the Hub. Spawners, services, and the proxy will use
392# this URL to talk to the Hub.
393#
394# Only needs to be specified if the default hub URL is not connectable (e.g.
395# using a unix+http:// bind url).
396#
397# .. seealso::
398# JupyterHub.hub_connect_ip
399# JupyterHub.hub_bind_url
400#
401# .. versionadded:: 0.9
402# Default: ''
403# c.JupyterHub.hub_connect_url = ''
404
405## The ip address for the Hub process to *bind* to.
406#
407# By default, the hub listens on localhost only. This address must be accessible
408# from the proxy and user servers. You may need to set this to a public ip or ''
409# for all interfaces if the proxy or user servers are in containers or on a
410# different host.
411#
412# See `hub_connect_ip` for cases where the bind and connect address should
413# differ, or `hub_bind_url` for setting the full bind URL.
414# Default: '127.0.0.1'
415# c.JupyterHub.hub_ip = '127.0.0.1'
416
417## The internal port for the Hub process.
418#
419# This is the internal port of the hub itself. It should never be accessed
420# directly. See JupyterHub.port for the public port to use when accessing
421# jupyterhub. It is rare that this port should be set except in cases of port
422# conflict.
423#
424# See also `hub_ip` for the ip and `hub_bind_url` for setting the full bind URL.
425# Default: 8081
426# c.JupyterHub.hub_port = 8081
427
428## Trigger implicit spawns after this many seconds.
429#
430# When a user visits a URL for a server that's not running, they are shown a
431# page indicating that the requested server is not running with a button to
432# spawn the server.
433#
434# Setting this to a positive value will redirect the user after this many
435# seconds, effectively clicking this button automatically for the users,
436# automatically beginning the spawn process.
437#
438# Warning: this can result in errors and surprising behavior when sharing access
439# URLs to actual servers, since the wrong server is likely to be started.
440# Default: 0
441# c.JupyterHub.implicit_spawn_seconds = 0
442
443## Timeout (in seconds) to wait for spawners to initialize
444#
445# Checking if spawners are healthy can take a long time if many spawners are
446# active at hub start time.
447#
448# If it takes longer than this timeout to check, init_spawner will be left to
449# complete in the background and the http server is allowed to start.
450#
451# A timeout of -1 means wait forever, which can mean a slow startup of the Hub
452# but ensures that the Hub is fully consistent by the time it starts responding
453# to requests. This matches the behavior of jupyterhub 1.0.
454#
455# .. versionadded: 1.1.0
456# Default: 10
457# c.JupyterHub.init_spawners_timeout = 10
458
459## The location to store certificates automatically created by JupyterHub.
460#
461# Use with internal_ssl
462# Default: 'internal-ssl'
463# c.JupyterHub.internal_certs_location = 'internal-ssl'
464
465## Enable SSL for all internal communication
466#
467# This enables end-to-end encryption between all JupyterHub components.
468# JupyterHub will automatically create the necessary certificate authority and
469# sign notebook certificates as they're created.
470# Default: False
471# c.JupyterHub.internal_ssl = False
472
473## The public facing ip of the whole JupyterHub application (specifically
474# referred to as the proxy).
475#
476# This is the address on which the proxy will listen. The default is to listen
477# on all interfaces. This is the only address through which JupyterHub should be
478# accessed by users.
479#
480# .. deprecated: 0.9
481# Use JupyterHub.bind_url
482# Default: ''
483# c.JupyterHub.ip = ''
484
485## Supply extra arguments that will be passed to Jinja environment.
486# Default: {}
487# c.JupyterHub.jinja_environment_options = {}
488
489## Interval (in seconds) at which to update last-activity timestamps.
490# Default: 300
491# c.JupyterHub.last_activity_interval = 300
492
493## Dict of 'group': ['usernames'] to load at startup.
494#
495# This strictly *adds* groups and users to groups.
496#
497# Loading one set of groups, then starting JupyterHub again with a different set
498# will not remove users or groups from previous launches. That must be done
499# through the API.
500# Default: {}
501# c.JupyterHub.load_groups = {}
502
503## The date format used by logging formatters for %(asctime)s
504# See also: Application.log_datefmt
505# c.JupyterHub.log_datefmt = '%Y-%m-%d %H:%M:%S'
506
507## The Logging format template
508# See also: Application.log_format
509# c.JupyterHub.log_format = '[%(name)s]%(highlevel)s %(message)s'
510
511## Set the log level by value or name.
512# See also: Application.log_level
513# c.JupyterHub.log_level = 30
514
515## Specify path to a logo image to override the Jupyter logo in the banner.
516# Default: ''
517# c.JupyterHub.logo_file = ''
518
519## Maximum number of concurrent named servers that can be created by a user at a
520# time.
521#
522# Setting this can limit the total resources a user can consume.
523#
524# If set to 0, no limit is enforced.
525# Default: 0
526# c.JupyterHub.named_server_limit_per_user = 0
527
528## File to write PID Useful for daemonizing JupyterHub.
529# Default: ''
530# c.JupyterHub.pid_file = ''
531
532## The public facing port of the proxy.
533#
534# This is the port on which the proxy will listen. This is the only port through
535# which JupyterHub should be accessed by users.
536#
537# .. deprecated: 0.9
538# Use JupyterHub.bind_url
539# Default: 8000
540# c.JupyterHub.port = 8000
541
542## DEPRECATED since version 0.8 : Use ConfigurableHTTPProxy.api_url
543# Default: ''
544# c.JupyterHub.proxy_api_ip = ''
545
546## DEPRECATED since version 0.8 : Use ConfigurableHTTPProxy.api_url
547# Default: 0
548# c.JupyterHub.proxy_api_port = 0
549
550## DEPRECATED since version 0.8: Use ConfigurableHTTPProxy.auth_token
551# Default: ''
552# c.JupyterHub.proxy_auth_token = ''
553
554## Interval (in seconds) at which to check if the proxy is running.
555# Default: 30
556# c.JupyterHub.proxy_check_interval = 30
557
558## The class to use for configuring the JupyterHub proxy.
559#
560# Should be a subclass of :class:`jupyterhub.proxy.Proxy`.
561#
562# .. versionchanged:: 1.0
563# proxies may be registered via entry points,
564# e.g. `c.JupyterHub.proxy_class = 'traefik'`
565#
566# Currently installed:
567# - configurable-http-proxy: jupyterhub.proxy.ConfigurableHTTPProxy
568# - default: jupyterhub.proxy.ConfigurableHTTPProxy
569# Default: 'jupyterhub.proxy.ConfigurableHTTPProxy'
570# c.JupyterHub.proxy_class = 'jupyterhub.proxy.ConfigurableHTTPProxy'
571
572## DEPRECATED since version 0.8. Use ConfigurableHTTPProxy.command
573# Default: []
574# c.JupyterHub.proxy_cmd = []
575
576## Recreate all certificates used within JupyterHub on restart.
577#
578# Note: enabling this feature requires restarting all notebook servers.
579#
580# Use with internal_ssl
581# Default: False
582# c.JupyterHub.recreate_internal_certs = False
583
584## Redirect user to server (if running), instead of control panel.
585# Default: True
586# c.JupyterHub.redirect_to_server = True
587
588## Purge and reset the database.
589# Default: False
590# c.JupyterHub.reset_db = False
591
592## Interval (in seconds) at which to check connectivity of services with web
593# endpoints.
594# Default: 60
595# c.JupyterHub.service_check_interval = 60
596
597## Dict of token:servicename to be loaded into the database.
598#
599# Allows ahead-of-time generation of API tokens for use by externally managed
600# services.
601# Default: {}
602# c.JupyterHub.service_tokens = {}
603
604## List of service specification dictionaries.
605#
606# A service
607#
608# For instance::
609#
610# services = [
611# {
612# 'name': 'cull_idle',
613# 'command': ['/path/to/cull_idle_servers.py'],
614# },
615# {
616# 'name': 'formgrader',
617# 'url': 'http://127.0.0.1:1234',
618# 'api_token': 'super-secret',
619# 'environment':
620# }
621# ]
622# Default: []
623# c.JupyterHub.services = []
624
625## Instead of starting the Application, dump configuration to stdout
626# See also: Application.show_config
627# c.JupyterHub.show_config = False
628
629## Instead of starting the Application, dump configuration to stdout (as JSON)
630# See also: Application.show_config_json
631# c.JupyterHub.show_config_json = False
632
633## Shuts down all user servers on logout
634# Default: False
635# c.JupyterHub.shutdown_on_logout = False
636
637## The class to use for spawning single-user servers.
638#
639# Should be a subclass of :class:`jupyterhub.spawner.Spawner`.
640#
641# .. versionchanged:: 1.0
642# spawners may be registered via entry points,
643# e.g. `c.JupyterHub.spawner_class = 'localprocess'`
644#
645# Currently installed:
646# - default: jupyterhub.spawner.LocalProcessSpawner
647# - localprocess: jupyterhub.spawner.LocalProcessSpawner
648# - simple: jupyterhub.spawner.SimpleLocalProcessSpawner
649# Default: 'jupyterhub.spawner.LocalProcessSpawner'
650# c.JupyterHub.spawner_class = 'jupyterhub.spawner.LocalProcessSpawner'
651
652## Path to SSL certificate file for the public facing interface of the proxy
653#
654# When setting this, you should also set ssl_key
655# Default: ''
656# c.JupyterHub.ssl_cert = ''
657
658## Path to SSL key file for the public facing interface of the proxy
659#
660# When setting this, you should also set ssl_cert
661# Default: ''
662# c.JupyterHub.ssl_key = ''
663
664## Host to send statsd metrics to. An empty string (the default) disables sending
665# metrics.
666# Default: ''
667# c.JupyterHub.statsd_host = ''
668
669## Port on which to send statsd metrics about the hub
670# Default: 8125
671# c.JupyterHub.statsd_port = 8125
672
673## Prefix to use for all metrics sent by jupyterhub to statsd
674# Default: 'jupyterhub'
675# c.JupyterHub.statsd_prefix = 'jupyterhub'
676
677## Run single-user servers on subdomains of this host.
678#
679# This should be the full `https://hub.domain.tld[:port]`.
680#
681# Provides additional cross-site protections for javascript served by single-
682# user servers.
683#
684# Requires `<username>.hub.domain.tld` to resolve to the same host as
685# `hub.domain.tld`.
686#
687# In general, this is most easily achieved with wildcard DNS.
688#
689# When using SSL (i.e. always) this also requires a wildcard SSL certificate.
690# Default: ''
691# c.JupyterHub.subdomain_host = ''
692
693## Paths to search for jinja templates, before using the default templates.
694# Default: []
695c.JupyterHub.template_paths = ['/mofem_install/jupyter/templates']
696
697## Extra variables to be passed into jinja templates
698# Default: {}
699# c.JupyterHub.template_vars = {}
700
701## Extra settings overrides to pass to the tornado application.
702# Default: {}
703# c.JupyterHub.tornado_settings = {}
704
705## Trust user-provided tokens (via JupyterHub.service_tokens) to have good
706# entropy.
707#
708# If you are not inserting additional tokens via configuration file, this flag
709# has no effect.
710#
711# In JupyterHub 0.8, internally generated tokens do not pass through additional
712# hashing because the hashing is costly and does not increase the entropy of
713# already-good UUIDs.
714#
715# User-provided tokens, on the other hand, are not trusted to have good entropy
716# by default, and are passed through many rounds of hashing to stretch the
717# entropy of the key (i.e. user-provided tokens are treated as passwords instead
718# of random keys). These keys are more costly to check.
719#
720# If your inserted tokens are generated by a good-quality mechanism, e.g.
721# `openssl rand -hex 32`, then you can set this flag to True to reduce the cost
722# of checking authentication tokens.
723# Default: False
724# c.JupyterHub.trust_user_provided_tokens = False
725
726## Names to include in the subject alternative name.
727#
728# These names will be used for server name verification. This is useful if
729# JupyterHub is being run behind a reverse proxy or services using ssl are on
730# different hosts.
731#
732# Use with internal_ssl
733# Default: []
734# c.JupyterHub.trusted_alt_names = []
735
736## Downstream proxy IP addresses to trust.
737#
738# This sets the list of IP addresses that are trusted and skipped when
739# processing the `X-Forwarded-For` header. For example, if an external proxy is
740# used for TLS termination, its IP address should be added to this list to
741# ensure the correct client IP addresses are recorded in the logs instead of the
742# proxy server's IP address.
743# Default: []
744# c.JupyterHub.trusted_downstream_ips = []
745
746## Upgrade the database automatically on start.
747#
748# Only safe if database is regularly backed up. Only SQLite databases will be
749# backed up to a local file automatically.
750# Default: False
751# c.JupyterHub.upgrade_db = False
752
753## Callable to affect behavior of /user-redirect/
754#
755# Receives 4 parameters: 1. path - URL path that was provided after /user-
756# redirect/ 2. request - A Tornado HTTPServerRequest representing the current
757# request. 3. user - The currently authenticated user. 4. base_url - The
758# base_url of the current hub, for relative redirects
759#
760# It should return the new URL to redirect to, or None to preserve current
761# behavior.
762# Default: None
763# c.JupyterHub.user_redirect_hook = None
764
765#------------------------------------------------------------------------------
766# Spawner(LoggingConfigurable) configuration
767#------------------------------------------------------------------------------
768## Base class for spawning single-user notebook servers.
769#
770# Subclass this, and override the following methods:
771#
772# - load_state - get_state - start - stop - poll
773#
774# As JupyterHub supports multiple users, an instance of the Spawner subclass is
775# created for each user. If there are 20 JupyterHub users, there will be 20
776# instances of the subclass.
777
778## Extra arguments to be passed to the single-user server.
779#
780# Some spawners allow shell-style expansion here, allowing you to use
781# environment variables here. Most, including the default, do not. Consult the
782# documentation for your spawner to verify!
783# Default: []
784# c.Spawner.args = ['--NotebookApp.show_banner=False']
785
786## An optional hook function that you can implement to pass `auth_state` to the
787# spawner after it has been initialized but before it starts. The `auth_state`
788# dictionary may be set by the `.authenticate()` method of the authenticator.
789# This hook enables you to pass some or all of that information to your spawner.
790#
791# Example::
792#
793# def userdata_hook(spawner, auth_state):
794# spawner.userdata = auth_state["userdata"]
795#
796# c.Spawner.auth_state_hook = userdata_hook
797# Default: None
798# c.Spawner.auth_state_hook = None
799
800## The command used for starting the single-user server.
801#
802# Provide either a string or a list containing the path to the startup script
803# command. Extra arguments, other than this path, should be provided via `args`.
804#
805# This is usually set if you want to start the single-user server in a different
806# python environment (with virtualenv/conda) than JupyterHub itself.
807#
808# Some spawners allow shell-style expansion here, allowing you to use
809# environment variables. Most, including the default, do not. Consult the
810# documentation for your spawner to verify!
811# Default: ['jupyterhub-singleuser']
812# c.Spawner.cmd = ['jupyterhub-singleuser']
813
814## Maximum number of consecutive failures to allow before shutting down
815# JupyterHub.
816#
817# This helps JupyterHub recover from a certain class of problem preventing
818# launch in contexts where the Hub is automatically restarted (e.g. systemd,
819# docker, kubernetes).
820#
821# A limit of 0 means no limit and consecutive failures will not be tracked.
822# Default: 0
823# c.Spawner.consecutive_failure_limit = 0
824
825## Minimum number of cpu-cores a single-user notebook server is guaranteed to
826# have available.
827#
828# If this value is set to 0.5, allows use of 50% of one CPU. If this value is
829# set to 2, allows use of up to 2 CPUs.
830#
831# **This is a configuration setting. Your spawner must implement support for the
832# limit to work.** The default spawner, `LocalProcessSpawner`, does **not**
833# implement this support. A custom spawner **must** add support for this setting
834# for it to be enforced.
835# Default: None
836# c.Spawner.cpu_guarantee = None
837
838## Maximum number of cpu-cores a single-user notebook server is allowed to use.
839#
840# If this value is set to 0.5, allows use of 50% of one CPU. If this value is
841# set to 2, allows use of up to 2 CPUs.
842#
843# The single-user notebook server will never be scheduled by the kernel to use
844# more cpu-cores than this. There is no guarantee that it can access this many
845# cpu-cores.
846#
847# **This is a configuration setting. Your spawner must implement support for the
848# limit to work.** The default spawner, `LocalProcessSpawner`, does **not**
849# implement this support. A custom spawner **must** add support for this setting
850# for it to be enforced.
851# Default: None
852# c.Spawner.cpu_limit = None
853
854## Enable debug-logging of the single-user server
855# Default: False
856# c.Spawner.debug = False
857
858## The URL the single-user server should start in.
859#
860# `{username}` will be expanded to the user's username
861#
862# Example uses:
863#
864# - You can set `notebook_dir` to `/` and `default_url` to `/tree/home/{username}` to allow people to
865# navigate the whole filesystem from their notebook server, but still start in their home directory.
866# - Start with `/notebooks` instead of `/tree` if `default_url` points to a notebook instead of a directory.
867# - You can set this to `/lab` to have JupyterLab start by default, rather than Jupyter Notebook.
868# Default: ''
869# c.Spawner.default_url = '/tree'
870c.Spawner.default_url = '/lab/tree/README.md'
871
872
873## Disable per-user configuration of single-user servers.
874#
875# When starting the user's single-user server, any config file found in the
876# user's $HOME directory will be ignored.
877#
878# Note: a user could circumvent this if the user modifies their Python
879# environment, such as when they have their own conda environments / virtualenvs
880# / containers.
881# Default: False
882# c.Spawner.disable_user_config = False
883
884## List of environment variables for the single-user server to inherit from the
885# JupyterHub process.
886#
887# This list is used to ensure that sensitive information in the JupyterHub
888# process's environment (such as `CONFIGPROXY_AUTH_TOKEN`) is not passed to the
889# single-user server's process.
890# Default: ['PATH', 'PYTHONPATH', 'CONDA_ROOT', 'CONDA_DEFAULT_ENV', 'VIRTUAL_ENV', 'LANG', 'LC_ALL', 'JUPYTERHUB_SINGLEUSER_APP']
891c.Spawner.env_keep = ['LD_LIBRARY_PATH', 'PATH', 'PYTHONPATH', 'CONDA_ROOT', 'CONDA_DEFAULT_ENV', 'VIRTUAL_ENV', 'LANG', 'LC_ALL', 'JUPYTERHUB_SINGLEUSER_APP']
892
893## Extra environment variables to set for the single-user server's process.
894#
895# Environment variables that end up in the single-user server's process come from 3 sources:
896# - This `environment` configurable
897# - The JupyterHub process' environment variables that are listed in `env_keep`
898# - Variables to establish contact between the single-user notebook and the hub (such as JUPYTERHUB_API_TOKEN)
899#
900# The `environment` configurable should be set by JupyterHub administrators to
901# add installation specific environment variables. It is a dict where the key is
902# the name of the environment variable, and the value can be a string or a
903# callable. If it is a callable, it will be called with one parameter (the
904# spawner instance), and should return a string fairly quickly (no blocking
905# operations please!).
906#
907# Note that the spawner class' interface is not guaranteed to be exactly same
908# across upgrades, so if you are using the callable take care to verify it
909# continues to work after upgrades!
910#
911# .. versionchanged:: 1.2
912# environment from this configuration has highest priority,
913# allowing override of 'default' env variables,
914# such as JUPYTERHUB_API_URL.
915# Default: {}
916# c.Spawner.environment = {
917# 'DISPLAY' : '99.0',
918# 'JUPYTER_ENABLE_LAB' : 'yes',
919# 'PYVISTA_USE_IPYVTK' : 'true'
920# }
921
922## Timeout (in seconds) before giving up on a spawned HTTP server
923#
924# Once a server has successfully been spawned, this is the amount of time we
925# wait before assuming that the server is unable to accept connections.
926# Default: 30
927# c.Spawner.http_timeout = 30
928
929## The IP address (or hostname) the single-user server should listen on.
930#
931# The JupyterHub proxy implementation should be able to send packets to this
932# interface.
933# Default: ''
934# c.Spawner.ip = ''
935
936## Minimum number of bytes a single-user notebook server is guaranteed to have
937# available.
938#
939# Allows the following suffixes:
940# - K -> Kilobytes
941# - M -> Megabytes
942# - G -> Gigabytes
943# - T -> Terabytes
944#
945# **This is a configuration setting. Your spawner must implement support for the
946# limit to work.** The default spawner, `LocalProcessSpawner`, does **not**
947# implement this support. A custom spawner **must** add support for this setting
948# for it to be enforced.
949# Default: None
950# c.Spawner.mem_guarantee = None
951
952## Maximum number of bytes a single-user notebook server is allowed to use.
953#
954# Allows the following suffixes:
955# - K -> Kilobytes
956# - M -> Megabytes
957# - G -> Gigabytes
958# - T -> Terabytes
959#
960# If the single user server tries to allocate more memory than this, it will
961# fail. There is no guarantee that the single-user notebook server will be able
962# to allocate this much memory - only that it can not allocate more than this.
963#
964# **This is a configuration setting. Your spawner must implement support for the
965# limit to work.** The default spawner, `LocalProcessSpawner`, does **not**
966# implement this support. A custom spawner **must** add support for this setting
967# for it to be enforced.
968# Default: None
969# c.Spawner.mem_limit = None
970
971## Path to the notebook directory for the single-user server.
972#
973# The user sees a file listing of this directory when the notebook interface is
974# started. The current interface does not easily allow browsing beyond the
975# subdirectories in this directory's tree.
976#
977# `~` will be expanded to the home directory of the user, and {username} will be
978# replaced with the name of the user.
979#
980# Note that this does *not* prevent users from accessing files outside of this
981# path! They can do so with many other means.
982# Default: ''
983# c.Spawner.notebook_dir = ''
984
985## An HTML form for options a user can specify on launching their server.
986#
987# The surrounding `<form>` element and the submit button are already provided.
988#
989# For example:
990#
991# .. code:: html
992#
993# Set your key:
994# <input name="key" val="default_key"></input>
995# <br>
996# Choose a letter:
997# <select name="letter" multiple="true">
998# <option value="A">The letter A</option>
999# <option value="B">The letter B</option>
1000# </select>
1001#
1002# The data from this form submission will be passed on to your spawner in
1003# `self.user_options`
1004#
1005# Instead of a form snippet string, this could also be a callable that takes as
1006# one parameter the current spawner instance and returns a string. The callable
1007# will be called asynchronously if it returns a future, rather than a str. Note
1008# that the interface of the spawner class is not deemed stable across versions,
1009# so using this functionality might cause your JupyterHub upgrades to break.
1010# Default: traitlets.Undefined
1011# c.Spawner.options_form = traitlets.Undefined
1012
1013## Interpret HTTP form data
1014#
1015# Form data will always arrive as a dict of lists of strings. Override this
1016# function to understand single-values, numbers, etc.
1017#
1018# This should coerce form data into the structure expected by self.user_options,
1019# which must be a dict, and should be JSON-serializeable, though it can contain
1020# bytes in addition to standard JSON data types.
1021#
1022# This method should not have any side effects. Any handling of `user_options`
1023# should be done in `.start()` to ensure consistent behavior across servers
1024# spawned via the API and form submission page.
1025#
1026# Instances will receive this data on self.user_options, after passing through
1027# this function, prior to `Spawner.start`.
1028#
1029# .. versionchanged:: 1.0
1030# user_options are persisted in the JupyterHub database to be reused
1031# on subsequent spawns if no options are given.
1032# user_options is serialized to JSON as part of this persistence
1033# (with additional support for bytes in case of uploaded file data),
1034# and any non-bytes non-jsonable values will be replaced with None
1035# if the user_options are re-used.
1036# Default: traitlets.Undefined
1037# c.Spawner.options_from_form = traitlets.Undefined
1038
1039## Interval (in seconds) on which to poll the spawner for single-user server's
1040# status.
1041#
1042# At every poll interval, each spawner's `.poll` method is called, which checks
1043# if the single-user server is still running. If it isn't running, then
1044# JupyterHub modifies its own state accordingly and removes appropriate routes
1045# from the configurable proxy.
1046# Default: 30
1047# c.Spawner.poll_interval = 30
1048
1049## The port for single-user servers to listen on.
1050#
1051# Defaults to `0`, which uses a randomly allocated port number each time.
1052#
1053# If set to a non-zero value, all Spawners will use the same port, which only
1054# makes sense if each server is on a different address, e.g. in containers.
1055#
1056# New in version 0.7.
1057# Default: 0
1058# c.Spawner.port = 0
1059
1060## An optional hook function that you can implement to do work after the spawner
1061# stops.
1062#
1063# This can be set independent of any concrete spawner implementation.
1064# Default: None
1065# c.Spawner.post_stop_hook = None
1066
1067## An optional hook function that you can implement to do some bootstrapping work
1068# before the spawner starts. For example, create a directory for your user or
1069# load initial content.
1070#
1071# This can be set independent of any concrete spawner implementation.
1072#
1073# This maybe a coroutine.
1074#
1075# Example::
1076#
1077# from subprocess import check_call
1078# def my_hook(spawner):
1079# username = spawner.user.name
1080# check_call(['./examples/bootstrap-script/bootstrap.sh', username])
1081#
1082# c.Spawner.pre_spawn_hook = my_hook
1083# Default: None
1084# c.Spawner.pre_spawn_hook = None
1085
1086## List of SSL alt names
1087#
1088# May be set in config if all spawners should have the same value(s), or set at
1089# runtime by Spawner that know their names.
1090# Default: []
1091# c.Spawner.ssl_alt_names = []
1092
1093## Whether to include DNS:localhost, IP:127.0.0.1 in alt names
1094# Default: True
1095# c.Spawner.ssl_alt_names_include_local = True
1096
1097## Timeout (in seconds) before giving up on starting of single-user server.
1098#
1099# This is the timeout for start to return, not the timeout for the server to
1100# respond. Callers of spawner.start will assume that startup has failed if it
1101# takes longer than this. start should return when the server process is started
1102# and its location is known.
1103# Default: 60
1104# c.Spawner.start_timeout = 60
1105
1106#------------------------------------------------------------------------------
1107# Authenticator(LoggingConfigurable) configuration
1108#------------------------------------------------------------------------------
1109## Base class for implementing an authentication provider for JupyterHub
1110
1111## Set of users that will have admin rights on this JupyterHub.
1112#
1113# Admin users have extra privileges:
1114# - Use the admin panel to see list of users logged in
1115# - Add / remove users in some authenticators
1116# - Restart / halt the hub
1117# - Start / stop users' single-user servers
1118# - Can access each individual users' single-user server (if configured)
1119#
1120# Admin access should be treated the same way root access is.
1121#
1122# Defaults to an empty set, in which case no user has admin access.
1123# Default: set()
1124# c.Authenticator.admin_users = set()
1125
1126## Set of usernames that are allowed to log in.
1127#
1128# Use this with supported authenticators to restrict which users can log in.
1129# This is an additional list that further restricts users, beyond whatever
1130# restrictions the authenticator has in place.
1131#
1132# If empty, does not perform any additional restriction.
1133#
1134# .. versionchanged:: 1.2
1135# `Authenticator.whitelist` renamed to `allowed_users`
1136# Default: set()
1137# c.Authenticator.allowed_users = set()
1138
1139## The max age (in seconds) of authentication info before forcing a refresh of
1140# user auth info.
1141#
1142# Refreshing auth info allows, e.g. requesting/re-validating auth tokens.
1143#
1144# See :meth:`.refresh_user` for what happens when user auth info is refreshed
1145# (nothing by default).
1146# Default: 300
1147# c.Authenticator.auth_refresh_age = 300
1148
1149## Automatically begin the login process
1150#
1151# rather than starting with a "Login with..." link at `/hub/login`
1152#
1153# To work, `.login_url()` must give a URL other than the default `/hub/login`,
1154# such as an oauth handler or another automatic login handler, registered with
1155# `.get_handlers()`.
1156#
1157# .. versionadded:: 0.8
1158# Default: False
1159# c.Authenticator.auto_login = False
1160
1161## Set of usernames that are not allowed to log in.
1162#
1163# Use this with supported authenticators to restrict which users can not log in.
1164# This is an additional block list that further restricts users, beyond whatever
1165# restrictions the authenticator has in place.
1166#
1167# If empty, does not perform any additional restriction.
1168#
1169# .. versionadded: 0.9
1170#
1171# .. versionchanged:: 1.2
1172# `Authenticator.blacklist` renamed to `blocked_users`
1173# Default: set()
1174# c.Authenticator.blocked_users = set()
1175
1176## Delete any users from the database that do not pass validation
1177#
1178# When JupyterHub starts, `.add_user` will be called on each user in the
1179# database to verify that all users are still valid.
1180#
1181# If `delete_invalid_users` is True, any users that do not pass validation will
1182# be deleted from the database. Use this if users might be deleted from an
1183# external system, such as local user accounts.
1184#
1185# If False (default), invalid users remain in the Hub's database and a warning
1186# will be issued. This is the default to avoid data loss due to config changes.
1187# Default: False
1188# c.Authenticator.delete_invalid_users = False
1189
1190## Enable persisting auth_state (if available).
1191#
1192# auth_state will be encrypted and stored in the Hub's database. This can
1193# include things like authentication tokens, etc. to be passed to Spawners as
1194# environment variables.
1195#
1196# Encrypting auth_state requires the cryptography package.
1197#
1198# Additionally, the JUPYTERHUB_CRYPT_KEY environment variable must contain one
1199# (or more, separated by ;) 32B encryption keys. These can be either base64 or
1200# hex-encoded.
1201#
1202# If encryption is unavailable, auth_state cannot be persisted.
1203#
1204# New in JupyterHub 0.8
1205# Default: False
1206# c.Authenticator.enable_auth_state = False
1207
1208## An optional hook function that you can implement to do some bootstrapping work
1209# during authentication. For example, loading user account details from an
1210# external system.
1211#
1212# This function is called after the user has passed all authentication checks
1213# and is ready to successfully authenticate. This function must return the
1214# authentication dict reguardless of changes to it.
1215#
1216# This maybe a coroutine.
1217#
1218# .. versionadded: 1.0
1219#
1220# Example::
1221#
1222# import os, pwd
1223# def my_hook(authenticator, handler, authentication):
1224# user_data = pwd.getpwnam(authentication['name'])
1225# spawn_data = {
1226# 'pw_data': user_data
1227# 'gid_list': os.getgrouplist(authentication['name'], user_data.pw_gid)
1228# }
1229#
1230# if authentication['auth_state'] is None:
1231# authentication['auth_state'] = {}
1232# authentication['auth_state']['spawn_data'] = spawn_data
1233#
1234# return authentication
1235#
1236# c.Authenticator.post_auth_hook = my_hook
1237# Default: None
1238# c.Authenticator.post_auth_hook = None
1239
1240## Force refresh of auth prior to spawn.
1241#
1242# This forces :meth:`.refresh_user` to be called prior to launching a server, to
1243# ensure that auth state is up-to-date.
1244#
1245# This can be important when e.g. auth tokens that may have expired are passed
1246# to the spawner via environment variables from auth_state.
1247#
1248# If refresh_user cannot refresh the user auth data, launch will fail until the
1249# user logs in again.
1250# Default: False
1251# c.Authenticator.refresh_pre_spawn = False
1252
1253## Dictionary mapping authenticator usernames to JupyterHub users.
1254#
1255# Primarily used to normalize OAuth user names to local users.
1256# Default: {}
1257# c.Authenticator.username_map = {}
1258
1259## Regular expression pattern that all valid usernames must match.
1260#
1261# If a username does not match the pattern specified here, authentication will
1262# not be attempted.
1263#
1264# If not set, allow any username.
1265# Default: ''
1266# c.Authenticator.username_pattern = ''
1267
1268## Deprecated, use `Authenticator.allowed_users`
1269# Default: set()
1270# c.Authenticator.whitelist = set()
1271
1272#------------------------------------------------------------------------------
1273# CryptKeeper(SingletonConfigurable) configuration
1274#------------------------------------------------------------------------------
1275## Encapsulate encryption configuration
1276#
1277# Use via the encryption_config singleton below.
1278
1279# Default: []
1280# c.CryptKeeper.keys = []
1281
1282## The number of threads to allocate for encryption
1283# Default: 4
1284# c.CryptKeeper.n_threads = 4
1285
1286#------------------------------------------------------------------------------
1287# Pagination(Configurable) configuration
1288#------------------------------------------------------------------------------
1289## Default number of entries per page for paginated results.
1290# Default: 100
1291# c.Pagination.default_per_page = 100
1292
1293## Maximum number of entries per page for paginated results.
1294# Default: 250
1295# c.Pagination.max_per_page = 250