### Start configurable-http-proxy command line Source: https://jupyterhub.readthedocs.io/en/stable/howto/separate-proxy.html Example command to start the configurable-http-proxy as a separate service. Ensure the API IP/port match the hub's configuration and that the default/error targets point to the hub. ```bash $ configurable-http-proxy --ip=127.0.0.1 --port=8000 --api-ip=127.0.0.1 --api-port=8001 --default-target=http://localhost:8081 --error-target=http://localhost:8081/hub/error ``` -------------------------------- ### Install Kernelspecs System-Wide Source: https://jupyterhub.readthedocs.io/en/stable/_sources/howto/configuration/config-user-env.md.txt Example commands to install Python 2 and Python 3 kernelspecs system-wide to /usr/local. ```bash /path/to/python3 -m ipykernel install --prefix=/usr/local /path/to/python2 -m ipykernel install --prefix=/usr/local ``` -------------------------------- ### Spawner.start method example Source: https://jupyterhub.readthedocs.io/en/stable/reference/spawners.html Illustrates the typical structure of a Spawner's start method, including environment variable retrieval, command construction, and process initiation. ```python async def start(self): self.ip = '127.0.0.1' self.port = random_port() # get environment variables, # several of which are required for configuring the single-user server env = self.get_env() cmd = [] # get jupyterhub command to run, # typically ['jupyterhub-singleuser'] cmd.extend(self.cmd) cmd.extend(self.get_args()) await self._actually_start_server_somehow(cmd, env) # url may not match self.ip:self.port, but it could! url = self._get_connectable_url() return url ``` -------------------------------- ### Install Configurable HTTP Proxy Locally Source: https://jupyterhub.readthedocs.io/en/stable/_sources/contributing/setup.md.txt Install configurable-http-proxy locally if a global install fails due to permissions. Ensure the local bin directory is added to your PATH. ```bash npm install configurable-http-proxy export PATH=$PATH:$(pwd)/node_modules/.bin ``` -------------------------------- ### start Source: https://jupyterhub.readthedocs.io/en/stable/reference/api/proxy.html Starts the proxy. This method must be defined by subclasses if the proxy is to be started by the Hub. ```APIDOC ## `start` ### Description Starts the proxy. Will be called during startup if `should_start` is True. This method must be defined by subclasses if the proxy is to be started by the Hub. ### Method `start()` ``` -------------------------------- ### Start Server Source: https://jupyterhub.readthedocs.io/en/stable/_sources/tutorial/server-api.md.txt Initiate the launch of a user's server. This endpoint can be used to start the default server or a named server for a given user. The response indicates whether the server is immediately ready or has started the spawning process. ```APIDOC ## POST /hub/api/users/:username/servers/[:servername] ### Description Starts a server for a given user. If `servername` is omitted, it starts the default server. ### Method POST ### Endpoint /hub/api/users/:username/servers/[:servername] ### Parameters #### Path Parameters - **username** (string) - Required - The username of the user for whom to start the server. - **servername** (string) - Optional - The name of the server to start. If omitted, the default server is started. ### Response #### Success Response (201 Created) Indicates the launch completed and the server is ready and available immediately. #### Success Response (202 Accepted) Indicates the server has begun launching but is not immediately ready. The server will show `pending: 'spawn'` and requires polling or using the progress API to determine readiness. ``` -------------------------------- ### Service Configuration Examples Source: https://jupyterhub.readthedocs.io/en/stable/reference/api/service.html Examples of how to configure services in JupyterHub, demonstrating both externally managed and hub-managed services. ```APIDOC An externally managed service running on a URL: ```python { 'name': 'my-service', 'url': 'https://host:8888', 'admin': True, 'api_token': 'super-secret', } ``` A hub-managed service with no URL: ```python { 'name': 'cull-idle', 'command': ['python', '/path/to/cull- বাহ'] 'admin': True, } ``` ``` -------------------------------- ### Example Resource Requests and Limits Source: https://jupyterhub.readthedocs.io/en/stable/_sources/explanation/capacity-planning.md.txt A sensible starting point for CPU and memory requests and limits in a JupyterHub deployment. Adjust memory based on expected computations like machine learning or data analysis. ```yaml request: cpu: 0.5 mem: 2G limit: cpu: 1 mem: 2G ``` -------------------------------- ### Spawner Pre-Spawn Hook Example Source: https://jupyterhub.readthedocs.io/en/stable/reference/api/spawner.html Implement a pre-spawn hook to perform bootstrapping tasks before a user's server starts. This hook can modify the spawner's environment. ```python def my_hook(spawner): username = spawner.user.name spawner.environment["GREETING"] = f"Hello {username}" c.Spawner.pre_spawn_hook = my_hook ``` -------------------------------- ### Start a user's single-user notebook server Source: https://jupyterhub.readthedocs.io/en/stable/reference/rest-api.html Starts a user's single-user notebook server. Spawn options can be provided in the request body. ```APIDOC ## Start a user's single-user notebook server ### Description Starts a user's single-user notebook server. Spawn options can be passed as a JSON body when spawning via the API instead of spawn form. The structure of the options will depend on the Spawner's configuration. The body itself will be available as `user_options` for the Spawner. ### Method POST ### Endpoint /hub/api/users/{name}/server ### Parameters #### Path Parameters - **name** (string) - Required - username ### Request Body - **Spawn options** (object) - Optional - Spawn options can be passed as a JSON body when spawning via the API instead of spawn form. The structure of the options will depend on the Spawner's configuration. ### Request Example ```json { } ``` ### Response #### Success Response (201) The user's notebook server has started #### Success Response (202) The user's notebook server has not yet started, but has been requested ``` -------------------------------- ### Example of a Complete Server Progress Event Source: https://jupyterhub.readthedocs.io/en/stable/tutorial/server-api.html Shows a typical final event from the server progress API when a server has successfully started. Includes the server URL and a confirmation message. ```json { "progress": 100, "ready": true, "message": "Server ready at /user/test-1/", "html_message": "Server ready at /user/test-1/", "url": "/user/test-1/" } ``` -------------------------------- ### Example of adding a user route Source: https://jupyterhub.readthedocs.io/en/stable/_sources/howto/proxy.md.txt This example demonstrates how to add a route for a specific user, including associated user data. ```python await proxy.add_route('/user/pgeorgiou/', 'http://127.0.0.1:1227', {'user': 'pgeorgiou'}) ``` -------------------------------- ### Install Kernelsystem-wide Source: https://jupyterhub.readthedocs.io/en/stable/howto/configuration/config-user-env.html Install Python 2 and Python 3 kernels system-wide using 'ipykernel install' with the --prefix=/usr/local option. This ensures kernels are available to all users. ```bash /path/to/python3 -m ipykernel install --prefix=/usr/local /path/to/python2 -m ipykernel install --prefix=/usr/local ``` -------------------------------- ### Example Hub-Managed Service Environment Variables Source: https://jupyterhub.readthedocs.io/en/stable/_sources/reference/services.md.txt Shows the specific environment variables passed to the 'idle-culler' service example when it is launched by the Hub. ```bash JUPYTERHUB_SERVICE_NAME: 'idle-culler' JUPYTERHUB_API_TOKEN: API token assigned to the service JUPYTERHUB_API_URL: http://127.0.0.1:8080/hub/api JUPYTERHUB_BASE_URL: https://mydomain[:port] JUPYTERHUB_SERVICE_PREFIX: /services/idle-culler/ ``` -------------------------------- ### Install Configurable HTTP Proxy Globally Source: https://jupyterhub.readthedocs.io/en/stable/_sources/contributing/setup.md.txt Install the configurable-http-proxy globally using npm. This is required for running and testing the default JupyterHub configuration. If permission errors occur, consider using `sudo` or a local install. ```bash npm install -g configurable-http-proxy ``` -------------------------------- ### Set Server Start Timeout Source: https://jupyterhub.readthedocs.io/en/stable/reference/config-reference.html Configure the maximum time in seconds allowed for a single-user server to start. If exceeded, startup is considered failed. ```python c.SimpleLocalProcessSpawner.start_timeout = 120 ``` -------------------------------- ### Build and install SELinux module Source: https://jupyterhub.readthedocs.io/en/stable/_sources/howto/configuration/config-sudo.md.txt Compile the SELinux policy definition into a module and install it on the system. This is part of the SELinux troubleshooting steps. ```bash $ checkmodule -M -m -o sudo_exec_selinux.mod sudo_exec_selinux.te $ semodule_package -o sudo_exec_selinux.pp -m sudo_exec_selinux.mod $ semodule -i sudo_exec_selinux.pp ``` -------------------------------- ### Start JupyterHub for Development Source: https://jupyterhub.readthedocs.io/en/stable/_sources/contributing/setup.md.txt Start the JupyterHub service using a development configuration file. This allows you to test your changes locally. ```bash jupyterhub -f testing/jupyterhub_config.py ``` -------------------------------- ### Start a user's named server Source: https://jupyterhub.readthedocs.io/en/stable/reference/rest-api.html Starts a user's named server. Spawn options can be provided in the request body. ```APIDOC ## Start a user's named server ### Description Starts a user's named server. Spawn options can be passed as a JSON body when spawning via the API instead of spawn form. The structure of the options will depend on the Spawner's configuration. ### Method POST ### Endpoint /hub/api/users/{name}/servers/{server_name} ### Parameters #### Path Parameters - **name** (string) - Required - username - **server_name** (string) - Required - name given to a named-server (empty string for default server). Note that depending on your JupyterHub infrastructure there are limitations to `server_name`. Default spawner with K8s pod will not allow Jupyter Notebooks to be spawned with a name that contains more than 253 characters (keep in mind that the pod will be spawned with extra characters to identify the user and hub). ### Request Body - **Spawn options** (object) - Optional - Spawn options can be passed as a JSON body when spawning via the API instead of spawn form. The structure of the options will depend on the Spawner's configuration. ### Request Example ```json { } ``` ### Response #### Success Response (201) The user's notebook named-server has started #### Success Response (202) The user's notebook named-server has not yet started, but has been requested ``` -------------------------------- ### Tutorial Setup on AWS Source: https://jupyterhub.readthedocs.io/en/stable/reference/gallery-jhub-deployments.html This describes a manual setup for spinning up multiple Jupyter Notebooks on AWS for a tutorial. It involves using Docker to create isolated student environments. ```text * I started a big Amazon machine; * I installed Docker and built a custom image containing my software of interest; * I ran multiple containers, one connected to port 8000, one on 8001, etc. and gave each student a different port; * students could connect in and use the Terminal program in Jupyter to execute commands, and could upload/download files via the Jupyter console interface; * in theory I could have used notebooks too, but for this I didn’t have need. I am aware that JupyterHub can probably do all of this including manage the containers, but I’m still a bit shy of diving into that; this was fairly straightforward, gave me disposable containers that were isolated for each individual student, and worked almost flawlessly. Should be easy to do with RStudio too. ``` -------------------------------- ### Basic Spawner start method Source: https://jupyterhub.readthedocs.io/en/stable/_sources/reference/spawners.md.txt Illustrates a typical implementation of the `Spawner.start` method, including setting IP and port, retrieving environment variables, constructing the command, and initiating the server process. ```python async def start(self): self.ip = '127.0.0.1' self.port = random_port() # get environment variables, # several of which are required for configuring the single-user server env = self.get_env() cmd = [] # get jupyterhub command to run, # typically ['jupyterhub-singleuser'] cmd.extend(self.cmd) cmd.extend(self.get_args()) await self._actually_start_server_somehow(cmd, env) # url may not match self.ip:self.port, but it could! url = self._get_connectable_url() return url ``` -------------------------------- ### Install Node.js Dependencies Source: https://jupyterhub.readthedocs.io/en/stable/_sources/contributing/setup.md.txt Install necessary Node.js dependencies to compile CSS. This is often required if the 'lessc' command is not found during setup. ```bash npm install ``` -------------------------------- ### Install JavaScript Dependencies for LESS Compilation Source: https://jupyterhub.readthedocs.io/en/stable/contributing/setup.html If 'lessc' is not found during setup, run this command to install necessary Node.js dependencies for CSS compilation. ```bash npm install ``` -------------------------------- ### Spawner State Management Example Source: https://jupyterhub.readthedocs.io/en/stable/_sources/reference/spawners.md.txt Implement methods to get, load, and clear the state for a Spawner, typically used for persisting information like process IDs between server restarts. This example shows how to manage the PID for single-process spawners. ```python def get_state(self): """get the current state""" state = super().get_state() if self.pid: state['pid'] = self.pid return state ``` ```python def load_state(self, state): """load state from the database""" super().load_state(state) if 'pid' in state: self.pid = state['pid'] ``` ```python def clear_state(self): """clear any state (called after shutdown)""" super().clear_state() self.pid = 0 ``` -------------------------------- ### Start a server with POST /hub/api/users/:username/servers/[:servername] Source: https://jupyterhub.readthedocs.io/en/stable/_sources/tutorial/server-api.md.txt Initiate the launch of a user's server using a POST request. A '201 Created' response means the server is ready immediately, while '202 Accepted' indicates it has started spawning and requires further waiting. ```bash POST /hub/api/users/:username/servers/[:servername] ``` -------------------------------- ### Start a Server with POST Request Source: https://jupyterhub.readthedocs.io/en/stable/tutorial/server-api.html Initiate the launch of a user's server by making a POST request to the specified API endpoint. This action requires the 'servers' scope. ```bash POST /hub/api/users/:username/servers/[:servername] ``` -------------------------------- ### Get Service by Name Response Source: https://jupyterhub.readthedocs.io/en/stable/reference/rest-api.html Example response when retrieving a specific service by its name. Provides detailed information about the service. ```json { "name": "string", "kind": "service", "admin": true, "roles": [ "string" ], "url": "string", "prefix": "string", "pid": 0, "command": [ "string" ], "info": { } } ``` -------------------------------- ### Example Spawned Command Source: https://jupyterhub.readthedocs.io/en/stable/_sources/reference/spawners.md.txt Illustrates the resulting command-line execution after applying Spawner.cmd and Spawner.args configurations. ```bash my-singleuser-wrapper --debug --flag ``` -------------------------------- ### Troubleshoot JupyterHub Deployment Source: https://jupyterhub.readthedocs.io/en/stable/faq/troubleshooting.html Run this command to get detailed information about installed packages, versions, and system configuration for troubleshooting. ```bash jupyter troubleshoot ``` -------------------------------- ### Spawner.start Method Source: https://jupyterhub.readthedocs.io/en/stable/_sources/reference/spawners.md.txt The `Spawner.start` method is responsible for initiating a single-user server for a given user. It should return the `(ip, port)` of the running server or a full URL. The example demonstrates how to construct the command and environment variables for the server process. ```APIDOC ## Spawner.start ### Description Starts a single-user server for a single user. Information about the user is available via `self.user`. The return value should be the `(ip, port)` of the running server, or a full URL as a string. ### Method `async def start(self)` ### Parameters None explicitly defined, but relies on instance attributes like `self.user`, `self.ip`, `self.port`, `self.cmd`, and methods like `self.get_env()`, `self.get_args()`, `self._get_connectable_url()`. ### Request Example ```python async def start(self): self.ip = '127.0.0.1' self.port = random_port() # get environment variables, # several of which are required for configuring the single-user server env = self.get_env() cmd = [] # get jupyterhub command to run, # typically ['jupyterhub-singleuser'] cmd.extend(self.cmd) cmd.extend(self.get_args()) await self._actually_start_server_somehow(cmd, env) # url may not match self.ip:self.port, but it could! url = self._get_connectable_url() return url ``` ### Response - **(ip, port)** or **URL** (string) - The connection details for the running server. ### Response Example `'http://127.0.0.1:8888'` ### Exception Handling If `Spawner.start` raises an Exception, a message can be passed to the user via `.jupyterhub_html_message` (rendered as HTML) or `.jupyterhub_message` (rendered as plain text). ``` -------------------------------- ### Build and Serve Documentation Locally Source: https://jupyterhub.readthedocs.io/en/stable/contributing/docs.html Builds the HTML version of the documentation and serves it locally for preview. This command automatically re-renders HTML upon detecting changes. ```bash sphinx-autobuild docs/source/ docs/_build/html ``` -------------------------------- ### Retrieve User Model via API with Requests Source: https://jupyterhub.readthedocs.io/en/stable/_sources/reference/services.md.txt Make a GET request to the /hub/api/user endpoint with an access token in the Authorization header to retrieve the user model. This example uses the requests library. ```python r = requests.get( "http://127.0.0.1:8081/hub/api/user", headers = { 'Authorization' : f'token {api_token}', }, ) r.raise_for_status() user = r.json() ``` -------------------------------- ### cmd Source: https://jupyterhub.readthedocs.io/en/stable/reference/api/spawner.html The command used for starting the single-user server. This can be a string or a list containing the path to the startup script. Extra arguments should be provided via `args`. Useful for starting servers in different Python environments. ```APIDOC ## c.Spawner.cmd = Command() The command used for starting the single-user server. Provide either a string or a list containing the path to the startup script command. Extra arguments, other than this path, should be provided via `args`. This is usually set if you want to start the single-user server in a different python environment (with virtualenv/conda) than JupyterHub itself. Some spawners allow shell-style expansion here, allowing you to use environment variables. Most, including the default, do not. Consult the documentation for your spawner to verify! ``` -------------------------------- ### Install JupyterHub with conda Source: https://jupyterhub.readthedocs.io/en/stable/_sources/tutorial/quickstart.md.txt Install JupyterHub and its proxy using conda. Also installs JupyterLab and notebook if needed for the same environment. ```bash conda install -c conda-forge jupyterhub # installs jupyterhub and proxy conda install jupyterlab notebook # needed if running the notebook servers in the same environment ``` -------------------------------- ### Example of Spawned Command Source: https://jupyterhub.readthedocs.io/en/stable/reference/spawners.html Illustrates the resulting command-line string after applying `Spawner.cmd` and `Spawner.args` configuration. ```bash my-singleuser-wrapper --debug --flag ``` -------------------------------- ### Install and Install Hooks for Pre-commit Source: https://jupyterhub.readthedocs.io/en/stable/contributing/tests.html Install the pre-commit package and register git hooks to automatically check code formatting before commits. ```bash pip install pre-commit pre-commit install --install-hooks ``` -------------------------------- ### Example route structure Source: https://jupyterhub.readthedocs.io/en/stable/howto/proxy.html Illustrates the expected dictionary format for routes when retrieved via `get_all_routes`. ```json { '/proxy/path/': { 'routespec': '/proxy/path/', 'target': 'http://...', 'data': {}, }, } ``` -------------------------------- ### Install Node.js and npm on Debian/Ubuntu Source: https://jupyterhub.readthedocs.io/en/stable/_sources/tutorial/quickstart.md.txt Use this command to install Node.js and npm on Debian/Ubuntu systems if you are using pip for JupyterHub installation. ```bash sudo apt-get install nodejs npm ``` -------------------------------- ### Start Configurable HTTP Proxy Source: https://jupyterhub.readthedocs.io/en/stable/_sources/howto/separate-proxy.md.txt This command starts the configurable-http-proxy. Ensure `--api-ip` and `--api-port` match the hub's `ConfigurableHTTPProxy.api_url`. `--default-target` and `--error-target` should point to the hub. ```bash $ configurable-http-proxy --ip=127.0.0.1 --port=8000 --api-ip=127.0.0.1 --api-port=8001 --default-target=http://localhost:8081 --error-target=http://localhost:8081/hub/error ``` -------------------------------- ### Install JupyterHub with pip and npm Source: https://jupyterhub.readthedocs.io/en/stable/_sources/tutorial/quickstart.md.txt Install JupyterHub and the configurable-http-proxy using pip and npm. Also installs JupyterLab and notebook if needed for the same environment. ```bash python3 -m pip install jupyterhub npm install -g configurable-http-proxy python3 -m pip install jupyterlab notebook # needed if running the notebook servers in the same environment ``` -------------------------------- ### Install Node.js/npm on Linux (Debian/Ubuntu) Source: https://jupyterhub.readthedocs.io/en/stable/tutorial/quickstart.html Install Node.js and npm using the system's package manager. This is a prerequisite for JupyterHub installation if not using conda. ```bash sudo apt-get install nodejs npm ``` -------------------------------- ### Install Documentation Build Dependencies Source: https://jupyterhub.readthedocs.io/en/stable/contributing/docs.html Installs the necessary Python packages for building JupyterHub's documentation locally. Ensure you have Python and Git installed. ```bash python3 -m pip install -r docs/requirements.txt python3 -m pip install sphinx-autobuild ``` -------------------------------- ### Spawner Options Form Example Source: https://jupyterhub.readthedocs.io/en/stable/reference/api/spawner.html An example of an HTML form that can be used to allow users to specify options when launching their server. The data from this form is passed to the spawner. ```html Set your key:
Choose a letter: ``` -------------------------------- ### Install Python Package System-Wide Source: https://jupyterhub.readthedocs.io/en/stable/_sources/howto/configuration/config-user-env.md.txt Use pip to install Python packages system-wide for all users. Ensure the installation location is readable and executable by users. ```bash sudo python3 -m pip install numpy ``` -------------------------------- ### Configure User Creation Command Source: https://jupyterhub.readthedocs.io/en/stable/reference/api/auth.html Specify the command and arguments for creating new system users. The USERNAME placeholder will be replaced with the actual username. This example shows how to set a custom home directory. ```python c.LocalAuthenticator.add_user_cmd = [ 'adduser', '-q', '--gecos', '""', '--home', '/customhome/USERNAME', '--disabled-password' ] ``` -------------------------------- ### Spawner.start() Source: https://jupyterhub.readthedocs.io/en/stable/reference/api/spawner.html Asynchronously starts the single-user server. Returns the IP address and port where the Hub can connect to the server. ```APIDOC ## Spawner.start() ### Description Start the single-user server. ### Returns - (str, int): The (ip, port) where the Hub can connect to the server. ### Changed in version 0.7 Return ip, port instead of setting on self.user.server directly. ``` -------------------------------- ### List Installed Kernelspecs Source: https://jupyterhub.readthedocs.io/en/stable/_sources/howto/configuration/config-user-env.md.txt Command to list the locations of all installed Jupyter kernelspecs. ```bash jupyter kernelspec list ``` -------------------------------- ### Test JupyterHub Installation Source: https://jupyterhub.readthedocs.io/en/stable/tutorial/quickstart.html Verify the installation of JupyterHub and configurable-http-proxy by checking their help outputs. ```bash jupyterhub -h configurable-http-proxy -h ``` -------------------------------- ### Full Authenticator Skeleton Example Source: https://jupyterhub.readthedocs.io/en/stable/reference/authenticators.html A comprehensive example demonstrating how to structure an Authenticator class, including backporting `allow_all`, defining restrictive configuration checks in `check_blocked_users`, and permissive configuration checks in `check_allowed`. ```python class MyAuthenticator(Authenticator): # backport allow_all for compatibility with JupyterHub < 5 allow_all = Bool(False, config=True) require_something = List(config=True) allowed_something = Set() def authenticate(self, data, handler): ... if success: return {"username": username, "auth_state": {...}} else: return None def check_blocked_users(self, username, authentication=None): """Apply _restrictive_ configuration""" if self.require_something and not has_something(username, self.request_): return False # repeat for each restriction if restriction_defined and restriction_not_met: return False return super().check_blocked_users(self, username, authentication) def check_allowed(self, username, authentication=None): """Apply _permissive_ configuration Only called if check_blocked_users returns True AND allow_all is False """ if self.allow_all: # check here to backport allow_all behavior # from JupyterHub 5 # this branch will never be taken with jupyterhub >=5 return True if self.allowed_something and user_has_something(username): return True # repeat for each allow if allow_config and allow_met: return True # should always have this at the end if self.allowed_users and username in self.allowed_users: return True # do not call super! # super().check_allowed is not safe with JupyterHub < 5.0, # as it will return True if allowed_users is empty return False ``` -------------------------------- ### Configure LocalProcessSpawner command Source: https://jupyterhub.readthedocs.io/en/stable/reference/config-reference.html Set the command used for starting the single-user server. Provide a string or a list containing the path to the startup script. Extra arguments should be passed via `args`. This is typically used for starting servers in different Python environments. ```python c.LocalProcessSpawner.cmd = "/path/to/jupyterhub-singleuser" ``` ```python c.LocalProcessSpawner.cmd = ["/usr/bin/env", "python", "-m", "jupyterhub_singleuser"] ``` -------------------------------- ### Configure PAM Authenticator User Creation Command Source: https://jupyterhub.readthedocs.io/en/stable/reference/config-reference.html Specify the command and arguments for creating new users with PAM. This example shows how to set a custom home directory for new users. ```python c.PAMAuthenticator.add_user_cmd = [ 'adduser', '-q', '--gecos', '""', '--home', '/customhome/USERNAME', '--disabled-password' ] ``` -------------------------------- ### Install jupyterhub-idle-culler Source: https://jupyterhub.readthedocs.io/en/stable/tutorial/getting-started/services-basics.html Install the jupyterhub-idle-culler package using pip. This is the first step to configuring it as a Hub-managed service. ```bash pip install jupyterhub-idle-culler ``` -------------------------------- ### Test JupyterHub and proxy installation Source: https://jupyterhub.readthedocs.io/en/stable/_sources/tutorial/quickstart.md.txt Verify that JupyterHub and configurable-http-proxy are installed correctly by checking their help messages. ```bash jupyterhub -h configurable-http-proxy -h ``` -------------------------------- ### Build Frontend Components (Admin Page) Source: https://jupyterhub.readthedocs.io/en/stable/contributing/setup.html Navigate to the 'jsx' directory and run these commands to install dependencies and continuously rebuild the admin page as you make changes. Requires a refresh of the browser. ```bash cd jsx npm install npm run build:watch ``` -------------------------------- ### Spawner Configuration Options Source: https://jupyterhub.readthedocs.io/en/stable/reference/api/spawner.html Example of Spawner configuration settings, including checkbox and multi-select options. ```yaml "checked": ["on"], # checkbox "multi-select": ["a", "b"], } ```