OutpostSpawner#
- class outpostspawner.OutpostSpawner(**kwargs: Any)#
A JupyterHub spawner that spawns services on remote locations in combination with a JupyterHub Outpost service.
- cancelling_event c.OutpostSpawner.cancelling_event = Union({'failed': False, 'ready': False, 'progress': 99, 'message': '', 'html_message': 'JupyterLab is cancelling the start.'})#
Event shown when a singleuser server was cancelled. Can be a function or a dict.
This may be a coroutine.
Example:
from datetime import datetime async def cancel_click_event(spawner): now = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3] return { "failed": False, "ready": False, "progress": 99, "message": "", "html_message": f"<details><summary>{now}: Cancelling start ...</summary>We're stopping the start process.</details>", } c.ForwardBaseSpawner.cancelling_event = cancel_click_event
- check_allowed c.OutpostSpawner.check_allowed = Any(None)#
An optional hook function you can implement to double check if the given user_options allow a start. If the start is not allowed, it should raise an exception.
This may be a coroutine.
Example:
def custom_check_allowed(spawner, user_options): if not user_options.get("allowed", True): raise Exception("This is not allowed") c.OutpostSpawner.check_allowed = custom_check_allowed
- custom_env c.OutpostSpawner.custom_env = Union()#
An optional hook function, or dict, you can implement to add extra environment variables to send to the JupyterHub Outpost service.
This may be a coroutine.
Example:
async def custom_env(spawner, user_options, jupyterhub_api_url): system = user_options.get("system", "") env = { "JUPYTERHUB_STAGE": os.environ.get("JUPYTERHUB_STAGE", ""), "JUPYTERHUB_DOMAIN": os.environ.get("JUPYTERHUB_DOMAIN", ""), "JUPYTERHUB_OPTION1": user_options.get("option1", "") } if system: env["JUPYTERHUB_FLAVORS_UPDATE_URL"] = f"{jupyterhub_api_url.rstrip('/')}/outpostflavors/{system}" return env c.OutpostSpawner.custom_env = custom_env
- custom_misc c.OutpostSpawner.custom_misc = Union()#
An optional hook function, or dict, you can implement to add extra configurations to send to the JupyterHub Outpost service. This will override the Spawner configuration set at the Outpost.
key
can be anything you would normally use in your Spawner configuration:c.OutpostSpawner.<key> = <value>
This may be a coroutine.
Example:
async def custom_misc(spawner, user_options): return { "image": "jupyter/base-notebook:latest" } c.OutpostSpawner.custom_misc = custom_misc
will override the image configured at the Outpost:
c.JupyterHubOutpost.spawner_class = KubeSpawner c.KubeSpawner.image = "default_image:1.0"
and spawn a JupyterLab using the
jupyter/base-notebook:latest
image.
- custom_misc_disable_default c.OutpostSpawner.custom_misc_disable_default = Bool(False)#
By default, these
misc
options will be send to the Outpost service to override the corresponding values of the Spawner configured at the Outpost. You can disable this behaviour by setting this value to true.Default
custom_misc
options:extra_labels = await self.get_extra_labels() custom_misc.update({ "dns_name_template": self.dns_name_template, "pod_name_template": self.svc_name_template, "internal_ssl": self.internal_ssl, "ip": "0.0.0.0", "port": self.port, "services_enabled": True, "extra_labels": extra_labels }
- custom_poll_interval c.OutpostSpawner.custom_poll_interval = Union(0)#
An optional hook function, or dict, you can implement to define the poll interval (in milliseconds). This allows you to have to different intervals for different Outpost services. You can use this to randomize the poll interval for each spawner object.
Example:
import random def custom_poll_interval(spawner, user_options): system = user_options.get("system", "None") if system == "A": base_poll_interval = 30 poll_interval_randomizer = 10 poll_interval = 1e3 * base_poll_interval + random.randint( 0, 1e3 * poll_interval_randomizer ) else: poll_interval = 0 return poll_interval c.OutpostSpawner.custom_poll_interval = custom_poll_interval
- custom_port c.OutpostSpawner.custom_port = Union(8080)#
An optional hook function, or dict, you can implement to define a port depending on the spawner object.
Example:
from jupyterhub.utils import random_potr def custom_port(spawner, user_options): if user_options.get("system", "") == "A": return 8080 return random_port() c.OutpostSpawner.custom_port = custom_port
- custom_user_options c.OutpostSpawner.custom_user_options = Union()#
An optional hook function, or dict, you can implement to add extra user_options to send to the JupyterHub Outpost service.
This may be a coroutine.
Example:
async def custom_user_options(spawner, user_options): user_options["image"] = "jupyter/minimal-notebook:latest" return user_options c.OutpostSpawner.custom_user_options = custom_user_options
- dns_name_template c.OutpostSpawner.dns_name_template = Unicode('{name}.{namespace}.svc.cluster.local')#
Template to use to form the dns name for the pod.
- extra_labels c.OutpostSpawner.extra_labels = Union()#
An optional hook function, or dict, you can implement to add extra labels to the service created when using port-forwarding. Will also be forwarded to the Outpost service (see self.custom_misc_disable_default)
This may be a coroutine.
Example:
def extra_labels(spawner): labels = { "hub.jupyter.org/username": spawner.user.name, "hub.jupyter.org/servername": spawner.name, "sidecar.istio.io/inject": "false" } return labels c.ForwardBaseSpawner.extra_labels = extra_labels
- failed_spawn_request_hook c.OutpostSpawner.failed_spawn_request_hook = Any(None)#
An optional hook function you can implement to handle a failed start attempt properly. This will be called if the POST request to the Outpost service was not successful.
This may be a coroutine.
Example:
def custom_failed_spawn_request_hook(Spawner, exception_thrown): ... return c.OutpostSpawner.failed_spawn_request_hook = custom_failed_spawn_request_hook
- filter_events c.OutpostSpawner.filter_events = Callable(None)#
Different JupyterHub single-user servers may send different events. This filter allows you to unify all events. Should always return a dict. If the dict should not be shown, return an empty dict.
Example:
def custom_filter_events(spawner, event): event["html_message"] = event.get("message", "No message available") return event c.ForwardBaseSpawner.filter_events = custom_filter_events
- namespace c.OutpostSpawner.namespace = Unicode('')#
Kubernetes namespace to create services in.
Default:
ns_path = "/var/run/secrets/kubernetes.io/serviceaccount/namespace" if os.path.exists(ns_path): with open(ns_path) as f: return f.read().strip() return "default"
- post_spawn_request_hook c.OutpostSpawner.post_spawn_request_hook = Any(None)#
An optional hook function you can implement to handle a successful start attempt properly. This will be called if the POST request to the Outpost service was successful.
This may be a coroutine.
Example:
def post_spawn_request_hook(Spawner, resp_json): ... return c.OutpostSpawner.post_spawn_request_hook = post_spawn_request_hook
- public_api_url c.OutpostSpawner.public_api_url = Any(None)#
Singleuser servers started remotely may have to use a different api_url than the default internal one. This will overwrite
JUPYTERHUB_API_URL
in env. Default value is the default internalJUPYTERHUB_API_URL
- request_404_poll_keep_running c.OutpostSpawner.request_404_poll_keep_running = Bool(False)#
How to handle a 404 response from Outpost API during a singleuser poll request.
- request_failed_poll_keep_running c.OutpostSpawner.request_failed_poll_keep_running = Bool(True)#
How to handle a failed request to Outpost API during a singleuser poll request.
- request_headers c.OutpostSpawner.request_headers = Union()#
An optional hook function, or dict, you can implement to define the header used for all requests sent to the JupyterHub Outpost service. They are forwarded directly to the tornado.httpclient.HTTPRequest object.
Example:
def request_headers(spawner, user_options): if user_options.get("system", "") == "A": auth = os.environ.get("SYSTEM_A_AUTHENTICATION") else: auth = os.environ.get("SYSTEM_B_AUTHENTICATION") return { "Content-Type": "application/json", "Accept": "application/json", "Authorization": f"Basic {auth}" } c.OutpostSpawner.request_headers = request_headers
- request_kwargs c.OutpostSpawner.request_kwargs = Union({})#
An optional hook function, or dict, you can implement to define keyword arguments for all requests sent to the JupyterHub Outpost service. They are directly forwarded to the tornado.httpclient.HTTPRequest object.
Example:
def request_kwargs(spawner, user_options): return { "request_timeout": 30, "connect_timeout": 10, "ca_certs": ..., "validate_cert": ..., } c.OutpostSpawner.request_kwargs = request_kwargs
- request_url c.OutpostSpawner.request_url = Union()#
The URL used to communicate with the JupyterHub Outpost service.
This may be a coroutine.
Example:
def request_url(spawner, user_options): if user_options.get("system", "") == "A": return "http://outpost.namespace.svc:8080/services/" else: return "https://remote-outpost.com/services/" c.OutpostSpawner.request_url = request_url
- show_first_default_event c.OutpostSpawner.show_first_default_event = Any(True)#
Hook to define if the default event at 0% should be shown.
Can be a boolean or a callable function. This may be a coroutine.
- ssh_create_remote_forward c.OutpostSpawner.ssh_create_remote_forward = Any(False)#
Whether a port forwarding process from a remote system to the hub is required or not. The remote system must be prepared properly to support this feature.
Must be a boolean or a callable function
- ssh_custom_forward c.OutpostSpawner.ssh_custom_forward = Any(None)#
An optional hook function you can implement to create your own ssh port forwarding called in the start function. This can be used to use an external pod for the port forwarding instead of having JupyterHub handle it.
Example:
from tornado.httpclient import HTTPRequest def ssh_custom_forward(spawner, port_forward_info): url = "..." headers = { ... } req = HTTPRequest( url=url, method="POST", headers=headers, body=json.dumps(port_forward_info), ) await spawner.send_request( req, action="setuptunnel" ) c.ForwardBaseSpawner.ssh_custom_forward = ssh_custom_forward
- ssh_custom_forward_remote c.OutpostSpawner.ssh_custom_forward_remote = Any(None)#
An optional hook function you can implement to create your own ssh port forwarding from remote system to hub.
- ssh_custom_forward_remote_remove c.OutpostSpawner.ssh_custom_forward_remote_remove = Any(None)#
An optional hook function you can implement to remove your own ssh port forwarding from remote system to hub.
- ssh_custom_forward_remove c.OutpostSpawner.ssh_custom_forward_remove = Any(None)#
An optional hook function you can implement to remove your own ssh port forwarding called in the stop function. This can be used to use an external pod for the port forwarding instead of having JupyterHub handle it.
Example:
from tornado.httpclient import HTTPRequest def ssh_custom_forward_remove(spawner, port_forward_info): url = "..." headers = { ... } req = HTTPRequest( url=url, method="DELETE", headers=headers, body=json.dumps(port_forward_info), ) await spawner.send_request( req, action="removetunnel" ) c.ForwardBaseSpawner.ssh_custom_forward_remove = ssh_custom_forward_remove
- ssh_custom_svc c.OutpostSpawner.ssh_custom_svc = Any(None)#
An optional hook function you can implement to create a customized kubernetes svc called in the start function.
Example:
def ssh_custom_svc(spawner, port_forward_info): ... return spawner.pod_name, spawner.port c.ForwardBaseSpawner.ssh_custom_svc = ssh_custom_svc
- ssh_custom_svc_remove c.OutpostSpawner.ssh_custom_svc_remove = Any(None)#
An optional hook function you can implement to remove a customized kubernetes svc called in the stop function.
Example:
def ssh_custom_svc_remove(spawner, port_forward_info): ... return spawner.pod_name, spawner.port c.ForwardBaseSpawner.ssh_custom_svc_remove = ssh_custom_svc_remove
- ssh_during_startup c.OutpostSpawner.ssh_during_startup = Union(False)#
An optional hook function, or boolean, you can implement to decide whether a ssh port forwarding process should be run after the POST request to the JupyterHub Outpost service.
Common Use Case: singleuser service was started remotely and is not accessible by JupyterHub (e.g. it’s running on a different K8s Cluster), but you know exactly where it is (e.g. the service address).
Example:
def ssh_during_startup(spawner): if spawner.user_options.get("system", "") == "A": return True return False c.ForwardBaseSpawner.ssh_during_startup = ssh_during_startup
- ssh_forward_options c.OutpostSpawner.ssh_forward_options = Union()#
An optional hook, or dict, to configure the ssh commands used in the spawner.ssh_default_forward function. The default configuration parameters (see below) can be overridden.
Default:
ssh_forward_options_all = { "ServerAliveInterval": "15", "StrictHostKeyChecking": "accept-new", "ControlMaster": "auto", "ControlPersist": "yes", "Port": str(ssh_port), "ControlPath": f"/tmp/control_{ssh_address_or_host}", "IdentityFile": ssh_pkey, }
- ssh_forward_remote_options c.OutpostSpawner.ssh_forward_remote_options = Union()#
An optional hook, or dict, to configure the ssh commands used in the spawner.ssh_default_forward function. The default configuration parameters (see below) can be overriden.
Default:
ssh_forward_remote_options_all = { "StrictHostKeyChecking": "accept-new", "Port": str(ssh_port), "ControlPath": f"/tmp/control_{ssh_address_or_host}", }
- ssh_key c.OutpostSpawner.ssh_key = Union('/home/jovyan/.ssh/id_rsa')#
An optional hook function, or string, you can implement to set the ssh privatekey used for ssh port forwarding.
This may be a coroutine.
Example:
def ssh_key(spawner): if spawner.user_options.get("system", "") == "A": return "/mnt/private_keys/a" return "/mnt/private_keys/b" c.ForwardBaseSpawner.ssh_key = ssh_key
- ssh_node c.OutpostSpawner.ssh_node = Union(None)#
An optional hook function, or string, you can implement to set the ssh node used for ssh port forwarding.
This may be a coroutine.
Example:
def ssh_node(spawner): if spawner.user_options.get("system", "") == "A": return "outpost.namespace.svc" else: return "<public_ip>" c.ForwardBaseSpawner.ssh_node = ssh_node
- ssh_node_mapping c.OutpostSpawner.ssh_node_mapping = Callable(None)#
An optional hook function, you can implement to set the map the given ssh node to a different avlue.
This may be a coroutine.
Example:
def ssh_node_mapping(spawner, ssh_node): if ssh_node == "<internal_hostname>": return "<external_dns_name>" return ssh_node c.ForwardBaseSpawner.ssh_node_mapping = ssh_node_mapping
- ssh_port c.OutpostSpawner.ssh_port = Union(22)#
An optional hook function, or string, you can implement to set the ssh port used for ssh port forwarding.
This may be a coroutine.
Example:
def ssh_port(spawner): if spawner.user_options.get("system", "") == "A": return 22 else: return 2222 c.ForwardBaseSpawner.ssh_port = ssh_port
- ssh_recreate_at_start c.OutpostSpawner.ssh_recreate_at_start = Union(False)#
Whether ssh tunnels should be recreated when JupyterHub starts or not. If you have outsourced the port forwarding to an extra pod, you can set this to false. Outsourcing also means, that connections to running JupyterLabs are not affected by JupyterHub restarts.
This may be a coroutine.
- ssh_remote_key c.OutpostSpawner.ssh_remote_key = Union('/home/jovyan/.ssh/id_rsa_remote')#
An optional hook function, or string, you can implement to set the ssh privatekey used for ssh port forwarding remote.
This may be a coroutine.
Example:
def ssh_remote_key(spawner): if spawner.user_options.get("system", "") == "A": return "/mnt/private_keys/a" return "/mnt/private_keys/b" c.ForwardBaseSpawner.ssh_remote_key = ssh_remote_key
- ssh_remote_node c.OutpostSpawner.ssh_remote_node = Union(None)#
An optional hook function, or string, you can implement to set the ssh node used for ssh port forwarding remote.
This may be a coroutine.
Example:
def ssh_node(spawner): if spawner.user_options.get("system", "") == "A": return "outpost.namespace.svc" else: return "<public_ip>" c.ForwardBaseSpawner.ssh_remote_node = ssh_node
- ssh_remote_port c.OutpostSpawner.ssh_remote_port = Union(22)#
An optional hook function, or string, you can implement to set the ssh port used for ssh port forwarding remote.
This may be a coroutine.
Example:
def ssh_port(spawner): if spawner.user_options.get("system", "") == "A": return 22 else: return 2222 c.ForwardBaseSpawner.ssh_remote_port = ssh_port
- ssh_remote_username c.OutpostSpawner.ssh_remote_username = Union('jupyterhuboutpost')#
An optional hook function, or string, you can implement to set the ssh username used for ssh port forwarding remote.
This may be a coroutine.
Example:
def ssh_username(spawner): if spawner.user_options.get("system", "") == "A": return "jupyterhuboutpost" return "ubuntu" c.ForwardBaseSpawner.ssh_remote_username = ssh_username
- ssh_username c.OutpostSpawner.ssh_username = Union('jupyterhuboutpost')#
An optional hook function, or string, you can implement to set the ssh username used for ssh port forwarding.
This may be a coroutine.
Example:
def ssh_username(spawner): if spawner.user_options.get("system", "") == "A": return "jupyterhuboutpost" return "ubuntu" c.ForwardBaseSpawner.ssh_username = ssh_username
- start_async c.OutpostSpawner.start_async = Bool(False)#
Whether the start at the Outpost service should run in the background or not.
- stop_async c.OutpostSpawner.stop_async = Bool(False)#
Whether the stop at the Outpost service should run in the background or not.
- stop_event c.OutpostSpawner.stop_event = Union({'failed': True, 'ready': False, 'progress': 100, 'message': '', 'html_message': 'JupyterLab was stopped.'})#
Event shown when single-user server was stopped.
- svc_create c.OutpostSpawner.svc_create = Union(True)#
An optional hook function, or boolean, you can implement to disable the svc creation.
This may be a coroutine.
Example:
async def svc_create(spawner): if spawner.user_options.get("system", "") == "A": return False else: return True c.ForwardBaseSpawner.svc_create = svc_create
- svc_name_template c.OutpostSpawner.svc_name_template = Unicode('jupyter-{username}--{servername}')#
Template to use to form the name of user’s pods.
{username}
,{userid}
,{servername}
,{hubnamespace}
,{unescaped_username}
, and{unescaped_servername}
will be expanded if found within strings of this configuration. The username and servername come escaped to follow the DNS label standard.Trailing
-
characters are stripped for safe handling of empty server names (user default servers).This must be unique within the namespace the pods are being spawned in, so if you are running multiple jupyterhubs spawning in the same namespace, consider setting this to be something more unique.
- update_expected_path c.OutpostSpawner.update_expected_path = Any(False)#
Hook which allows to update the return value of Spawner.start().
Callable function, may be a coroutine.