an observable configuration object for the JupyterLite lifecycle

class jupyterlite.config.LiteBuildConfig(**kwargs: Any)#

the description of a JupyterLite build

This is most likely to be configured: - from environment variables - in a pyproject.toml - from the command line With direct instantiation a distant last place.

This is conceptually similar in scale to jupyter_server_config.json, and will piggy-back off of the {sys.prefix}/share/jupyter_{notebook,server}_config.d/ loader paths


Well-known (and otherwise) constants used by JupyterLite

jupyterlite.constants.ADDON_ENTRYPOINT = 'jupyterlite.addon.v0'#

the extension point for addons, including core

jupyterlite.constants.ALL_APP_ARCHIVES = [PosixPath('/home/docs/checkouts/readthedocs.org/user_builds/jupyterlite/checkouts/latest/py/jupyterlite/src/jupyterlite/jupyterlite-app-0.1.0-beta.11.tgz')]#

all of the archives

jupyterlite.constants.ALL_JSON = 'all.json'#

commonly-used filename for response fixtures, e.g. settings

jupyterlite.constants.ALL_WHL = ['py3-none-any.whl', 'emscripten_wasm32.whl']#

the only kinds of wheels piplite understands

jupyterlite.constants.API_CONTENTS = 'api/contents'#

the Jupyter API route for Contents API

jupyterlite.constants.C_LOCALE = 'C'#

a locale for reproducible file sorting

jupyterlite.constants.DEFAULT_FILE_TYPES = {'base64': {'gzip': [['.tgz', '.gz', '.gzip'], ['application/gzip']], 'ico': [['.ico'], ['image/x-icon']], 'jpeg': [['.jpeg', '.jpg'], ['image/jpeg']], 'pdf': [['.pdf'], ['application/pdf']], 'png': [['.png'], ['image/png']], 'wasm': [['.wasm'], ['application/wasm']], 'wheel': [['.whl'], ['octet/stream', 'application/x-wheel+zip']]}, 'json': {'geojson': [['.geojson'], ['application/geo+json']], 'ipynb': [['.ipynb'], ['application/x-ipynb+json']], 'jsmap': [['.map'], ['application/json']], 'json': [['.json'], ['application/json']]}, 'text': {'css': [['.css'], ['text/css']], 'csv': [['.csv'], ['text/csv']], 'fasta': [['.fasta'], ['text/plain']], 'html': [['.html'], ['text/html']], 'ical': [['.ical', '.ics', '.ifb', '.icalendar'], ['text/calendar']], 'js': [['.js', '.mjs'], ['application/javascript']], 'manifest': [['.manifest'], ['text/cache-manifest']], 'md': [['.md', '.markdown'], ['text/markdown']], 'plain': [['.txt'], ['text/plain']], 'py': [['.py'], ['text/x-python', 'application/x-python-code']], 'svg': [['.svg'], ['image/svg+xml']], 'toml': [['.toml'], ['application/toml']], 'vue': [['.vue'], ['text/plain']], 'xml': [['.xml'], ['application/xml']], 'yaml': [['.yaml', '.yml'], ['application/x-yaml']]}}#

enough file types to serve all our demo files

jupyterlite.constants.DEFAULT_OUTPUT_DIR = '_output'#

Needs a better canonical location

jupyterlite.constants.DISABLED_EXTENSIONS = 'disabledExtensions'#

configuration key for disabled extensions

jupyterlite.constants.FEDERATED_EXTENSIONS = 'federated_extensions'#

configuration key for prebuilt extensions

jupyterlite.constants.HOOKS = ['status', 'init', 'build', 'check', 'serve', 'archive']#

our doit task-based plugin system

jupyterlite.constants.HOOK_PARENTS = {'archive': 'build', 'build': 'init', 'check': 'build', 'serve': 'build'}#

the name of the previous hook

jupyterlite.constants.INDEX_HTML = 'index.html'#

a predictably-serveable HTML file

jupyterlite.constants.JUPYTERLITE_IPYNB = 'jupyter-lite.ipynb'#

our configuration file

jupyterlite.constants.JUPYTERLITE_JSON = 'jupyter-lite.json'#

our configuration file

jupyterlite.constants.JUPYTERLITE_SCHEMA = 'jupyterlite.schema.v0.json'#

our schema

jupyterlite.constants.JUPYTER_CONFIG_DATA = 'jupyter-config-data'#

a script DOM ID on most jupyter pages

jupyterlite.constants.LITE_PLUGIN_SETTINGS = 'litePluginSettings'#

the top-level key for lite plugin settings

jupyterlite.constants.NOARCH_WHL = 'py3-none-any.whl'#

the only kind of noarch wheel piplite understands

jupyterlite.constants.NPM_SOURCE_DATE_EPOCH = 499162500#

this is arrived at by inspection

jupyterlite.constants.OVERRIDES_JSON = 'overrides.json'#

settings overrides. used JupyterLab build system, usually goes in $PREFIX/share/jupyter/lab/

jupyterlite.constants.PACKAGE_JSON = 'package.json'#

the canonical location of labextension metadata

jupyterlite.constants.PHASES = ['pre_', '', 'post_']#

the lifecycle stages inside a hook

jupyterlite.constants.PYOLITE_PLUGIN_ID = '@jupyterlite/pyolite-kernel-extension:kernel'#

the plugin id for the pyolite kernel

jupyterlite.constants.REQUIREMENTS_TXT = 'requirements.txt'#

the generally-used listing of pip requirements

jupyterlite.constants.SETTINGS_FILE_TYPES = 'fileTypes'#

configuration key for file types

jupyterlite.constants.SETTINGS_OVERRIDES = 'settingsOverrides'#

configuration key for extension settings overrides

jupyterlite.constants.SHA256SUMS = 'SHA256SUMS'#

output equivalent to sha256sum * for providing a local bill-of-data

jupyterlite.constants.SHARE_LABEXTENSIONS = 'share/jupyter/labextensions'#

the canonical location within an env (or archive) for labextensions

jupyterlite.constants.SOURCEMAPS = ['.js.map', '.mjs.map']#

extensions to be considered sourcemaps

jupyterlite.constants.SOURCE_DATE_EPOCH = 'SOURCE_DATE_EPOCH'#

a canonical environment variable for triggering reproducible builds

jupyterlite.constants.UTF8 = {'encoding': 'utf-8'}#

the encoding for pretty much every file written and read by jupyterlite

jupyterlite.constants.WASM_WHL = 'emscripten_wasm32.whl'#

the only kind of binary wheel piplite understands


the JupyterLite CLI App(s)

class jupyterlite.app.BaseLiteApp(**kwargs: Any)#

TODO: An undescribed app

aliases: Dict[str, str] = {'app-archive': 'LiteBuildConfig.app_archive', 'apps': 'LiteBuildConfig.apps', 'base-url': 'LiteBuildConfig.base_url', 'config': 'JupyterApp.config_file', 'contents': 'LiteBuildConfig.contents', 'disable-addons': 'LiteBuildConfig.disable_addons', 'ignore-contents': 'LiteBuildConfig.ignore_contents', 'lite-dir': 'LiteBuildConfig.lite_dir', 'log-level': 'Application.log_level', 'mathjax-dir': 'LiteBuildConfig.mathjax_dir', 'output-archive': 'LiteBuildConfig.output_archive', 'output-dir': 'LiteBuildConfig.output_dir', 'piplite-wheels': 'LiteBuildConfig.piplite_urls', 'port': 'LiteBuildConfig.port', 'pyodide': 'LiteBuildConfig.pyodide_url', 'settings-overrides': 'LiteBuildConfig.settings_overrides', 'source-date-epoch': 'LiteBuildConfig.source_date_epoch'}#

the alias map for configurables Keys might strings or tuples for additional options; single-letter alias accessed like -v. Values might be like “Class.trait” strings of two-tuples: (Class.trait, help-text).

class jupyterlite.app.DescribedMixin#

a self-describing mixin

class jupyterlite.app.LiteApp(**kwargs: Any)#

build ready-to-serve (or -publish) JupyterLite sites

class jupyterlite.app.LiteArchiveApp(**kwargs: Any)#

build a JupyterLite app archive, which can be used as a baseline

class jupyterlite.app.LiteBuildApp(**kwargs: Any)#

build a JupyterLite site, including user content

class jupyterlite.app.LiteCheckApp(**kwargs: Any)#

verify a JupyterLite site, using available schema and rules

class jupyterlite.app.LiteDoitApp(**kwargs: Any)#

Run the doit command


Start the whole thing

class jupyterlite.app.LiteInitApp(**kwargs: Any)#

initialize a JupyterLite site from an app archive baseline

class jupyterlite.app.LiteListApp(**kwargs: Any)#

describe a JupyterLite site

class jupyterlite.app.LiteRawDoitApp(**kwargs: Any)#

use the full doit CLI, see https://pydoit.org/contents.html

tell jupyter to not parse the arguments with –, e.g.

jupyter-lite doit – –help


Parse the command line arguments.

class jupyterlite.app.LiteServeApp(**kwargs: Any)#

serve a JupyterLite site, using best available HTTP server

class jupyterlite.app.LiteStatusApp(**kwargs: Any)#

report about what a JupyterLite build _might_ do

class jupyterlite.app.LiteTaskApp(**kwargs: Any)#

run a doit task, optionally with –force


Start the whole thing

class jupyterlite.app.ManagedApp(**kwargs: Any)#

An app with a LiteManager that can do some config fixing


Start the whole thing

class jupyterlite.app.PipliteApp(**kwargs: Any)#

tools for working with piplite

class jupyterlite.app.PipliteIndex(**kwargs: Any)#

index a directory of wheels for piplite into an all.json

this file is suitable for including in a pre-built lab extension and will be found by adding to the extension’s package.json:


Parse the command line arguments.


Start the whole thing

jupyterlite.app.lite_flags = {'debug': ({'Application': {'log_level': 10}}, 'set log level to logging.DEBUG (maximize logging output)'), 'ignore-sys-prefix': ({'LiteBuildConfig': {'ignore_sys_prefix': True}}, 'Do not copy anything from sys.prefix'), 'no-sourcemaps': ({'LiteBuildConfig': {'no_sourcemaps': True}}, 'Strip all sourcemaps from applications and extensions'), 'no-unused-shared-packages': ({'LiteBuildConfig': {'no_unused_shared_packages': True}}, 'Remove shared packages not used by --apps'), 'y': ({'JupyterApp': {'answer_yes': True}}, 'Answer yes to any questions instead of prompting.')}#

some flags we use


Manager for JupyterLite

class jupyterlite.manager.LiteManager(**kwargs: Any)#

a manager for building jupyterlite sites

This primarily handles the business of mapping _addons_ to doit _tasks_, and then calling the doit API.

doit_run(task, *args, raw=False)#

run a subset of the doit command line


perform one-time inialization of the manager



a JupyterLite addon for generating app archives which can be used as input

class jupyterlite.addons.archive.ArchiveAddon(**kwargs: Any)#

Adds contents from the lite_dir to the output_dir, creates API output

If --source-date-epoch (SDE) is set, a number of features will be enabled to improve reproducibility of the final artifact. In addition to timestamps newer than SDE being “clamped” to SDE, this will also adjust some permissions inside the tarball


add all files created prior to pre_archive to an archive


apply best-effort entropy fixes to give more reproducible archives

log_archive(tarball, prefix='')#

print some information about an archive

make_archive_stdlib(tarball, root, members)#

actually build the archive.

  • this takes longer than any other hook
    • while this pure-python implementation needs to be maintained, a libarchive-based build might be preferable for e.g. CI performance.

  • an npm-compatible .tgz is the only supported archive format, as this is compatible with the upstream webpack build and its native packaged format.


Context manager for changing the current locale


class jupyterlite.addons.base.BaseAddon(**kwargs: Any)#

A base class for addons to the JupyterLite build chain

Subclassing this is optional, but provides some useful utilities

copy_one(src, dest)#

copy one Path (a file or folder)


update a federated_extension list in-place, ensuring unique names.


delete… somethings

fetch_one(url, dest)#

fetch one file

TODO: enable other backends, auth, etc.

property log#

A trait which allows any value.

merge_jupyter_config_data(config, in_config)#

merge well-known jupyter-config-data fields

merge_one_jupyterlite(out_path, in_paths)#

write the out_path with the merge content of in_paths, where all are valid jupyter-lite.* files.


adjust the timestamp to be –source-date-epoch for files newer than then

see https://reproducible-builds.org/specs/source-date-epoch


a JupyterLite addon for Jupyter Server-compatible contents

class jupyterlite.addons.contents.ContentsAddon(**kwargs: Any)#

Adds contents from the lite_dir to the output_dir, creates API output


perform the main user build of pre-populating /files/


verify that all Contents API is valid (sorta)

property file_src_dest#

the pairs of contents that will be copied

these are processed in reverse order, such that only the last path wins

maybe_add_one_path(path, root=None)#

add a file or folder’s contents (if not ignored)

one_contents_path(output_file_dir, api_path)#

A lazy reuse of a jupyter_server Contents API generator

patch_listing_timestamps(listing, sde=None)#

clamp a contents listing’s times to SOURCE_DATE_EPOCH


create a Contents API index for each subdirectory in /files/


yield some status information about the state of contents

class jupyterlite.addons.contents.DateTimeEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)#

A custom date-aware JSON encoder


Implement this method in a subclass such that it returns a serializable object for o, or calls the base implementation (to raise a TypeError).

For example, to support arbitrary iterators, you could implement default like this:

def default(self, o):
        iterable = iter(o)
    except TypeError:
        return list(iterable)
    # Let the base class default method raise the TypeError
    return JSONEncoder.default(self, o)

a small helper to user Z for UTC ISO strings

Federated Extensions#

a JupyterLite addon for supporting federated_extensions

class jupyterlite.addons.federated_extensions.FederatedExtensionAddon(**kwargs: Any)#

sync the as-installed federated_extensions and update jupyter-lite.json


yield a doit task to copy each local extension into the output_dir


copy the labextensions from a local conda package


copy one unpacked on-disk extension from sys.prefix into the output dir


copy one unpacked on-disk extension from anywhere into the output dir


copy one extension from the given path


copy the labextensions from a local wheel


a list of all federated extensions

property ext_cache#

where extensions will go in the cache

extract_one_conda_extension(conda_pkg, pkg_json_info, all_infos)#

extract one labextension from a conda package

extract_one_wheel_extension(wheel, pkg_json_info, all_infos)#

extract one labextension from a wheel


verify this is an actual pre-built extension, containing load information

property output_extensions#

where labextensions will go in the output folder


add the federated_extensions to jupyter-lite.json


update the root jupyter-lite.json, and copy each output theme to each app


handle downloading of federated extensions


yield a doit task to copy each federated extension into the output_dir

resolve_one_extension(path_or_url, init)#

try to resolve one URL or local folder/archive as a (set of) federated_extension(s)


a JupyterLite addon for jupyterlite-specific tasks

class jupyterlite.addons.lite.LiteAddon(**kwargs: Any)#

ensure jupyterlite files have been merged, and validate them


merge jupyter-lite.json into the output_dir


apply schema validation to all jupyter-lite.json in the output_dir

property lite_files#

all the source jupyter-lite.* files


a JupyterLite addon for generating hashes

class jupyterlite.addons.report.ReportAddon(**kwargs: Any)#

update static listings of the site contents in various formats

having these in various formats down the line can be handy for various publishing tasks


generate a hash file of all files in the distribution.

As this is relatively expensive for hundreds of files, this is performed as late as possible, while still providing some useful publishing / QA features.

TODO: develop some contract with the frontend in relation to this file,

or a derivative, as it has precisely the right information for certain cache tasks.

property sha256sums#

The location of the hashfile.


a JupyterLite addon for serving

class jupyterlite.addons.serve.ServeAddon(**kwargs: Any)#


a JupyterLite addon for supporting extension settings

class jupyterlite.addons.settings.SettingsAddon(**kwargs: Any)#

sync the as-installed overrides.json and update jupyter-lite.json

property output_extensions#

where labextensions will go in the output folder

patch_one_overrides(jupyterlite_json, overrides_json)#

update and normalize settingsOverrides


add settings from overrides.json per app where they exist


a JupyterLite addon for jupyterlab core

class jupyterlite.addons.static.StaticAddon(**kwargs: Any)#

Copy the core “gold master” artifacts into the output folder


unpack and copy the tarball files into the output_dir


maybe remove sourcemaps, or all static assets if an app is not installed


well before anything else, we need to ensure that the output_dir exists and is empty (if the baseline tarball has changed)

prune_unused_shared_packages(all_apps, apps_to_remove)#

manually remove unused webpack chunks from shared packages