Following the REES, myst-libre streamlines building ✨MyST articles✨ in containers.
- A repository containing MyST sources
- A Docker image (built by
binderhub) in a public (or private) registry, including:- Dependencies to execute notebooks/markdown files in the MyST repository
- JupyterHub (typically part of images built by
binderhub)
- Input data required by the executable content (optional)
Given these resources, myst-libre starts a Docker container, mounts the MyST repository and data (if available), and builds a MyST publication.
Note
This project was started to support publishing MyST articles as living preprints on NeuroLibre.
Important
Ensure the following prerequisites are installed:
- Node.js (For MyST) installation guide
- Docker installation guide
pip install myst-libre
Set up environment variables:
If you are using a private image registry and/or Curvenote CLI features, create a .env file in the project root and add the following:
DOCKER_PRIVATE_REGISTRY_USERNAME=your_username
DOCKER_PRIVATE_REGISTRY_PASSWORD=your_password
CURVENOTE_TOKEN=your_curvenote_api_tokenThe CURVENOTE_TOKEN is required for operations like curvenote submit, curvenote deploy, curvenote pull, etc. You can generate an API token from your Curvenote profile settings.
Import libraries and define REES resources
Minimal example to create a rees object:
from myst_libre.tools import JupyterHubLocalSpawner, MystMD
from myst_libre.rees import REES
from myst_libre.builders import MystBuilder
rees = REES(dict(
registry_url="https://your-registry.io",
gh_user_repo_name = "owner/repository"
))Other optional parameters that can be passed to the REES constructor:
gh_repo_commit_hash: Full SHA commit hash of thegh_user_repo_namerepository (optional, default: latest commit)binder_image_tag: Full SHA commit hash at which a binder tag is available for the "found image name" (optional, default: latest)binder_image_name_override: Override the "found image name" whose container will be used to build the MyST article (optional, default: None)dotenv: Path to a directory containing the .env file for authentication credentials to pull images fromregistry_url(optional, default: None)bh_image_prefix: Binderhub names the images with a prefix, e.g.,<prefix>agahkarakuzu-2dmriscope-7a73fb, typically set asbinder-. This will be used in the regex pattern to find the "binderhub built image name" in theregistry_url. See reference docs for more details.bh_project_name: See this issue (optional, default: [registry_urlwithouthttp://orhttps://])
Note that in this context what is meant by "prefix" is not the same as in the reference docs. (optional, default: binder-)
Image Selection Order
- If the
myst.ymlfile in thegh_user_repo_namerepository containsproject/thebe/binder/repo, this image is prioritized. - If
project/thebe/binder/repois not specified, thegh_user_repo_nameis used as the image name.
Note that if (2) is the case, your build command probably should not be myst build, but you can still use other builders, e.g., jupyter-book build.
If you specify binder_image_name_override, it will be used as the repository name to locate the image.
This allows you to build the MyST article using a runtime from a different repository than the one specified in gh_user_repo_name, as defined in myst.yml or overridden by binder_image_name_override.
The binder_image_tag set to latest refers to the most recent successful build of an image that meets the specified conditions. The repository content might be more recent than the binder_image_tag (e.g., gh_repo_commit_hash), but the same binder image can be reused.
Fetch resources and spawn JupyterHub in the respective container
hub = JupyterHubLocalSpawner(rees_resources,
host_build_source_parent_dir = '/tmp/myst_repos',
container_build_source_mount_dir = '/home/jovyan', #default
host_data_parent_dir = "/tmp/myst_data", #optional
container_data_mount_dir = '/home/jovyan/data', #optional
)
hub.spawn_jupyter_hub()- MyST repository will be cloned at:
tmp/
└── myst_repos/
└── owner/
└── repository/
└── full_commit_SHA_A/
├── myst.yml
├── _toc.yml
├── binder/
│ ├── requirements.txt (or other REES dependencies)
│ └── data_requirement.json (optional)
├── content/
│ ├── my_notebook.ipynb
│ └── my_myst_markdown.md
├── paper.md
└── paper.bib
Repository will be mounted to the container as /tmp/myst_repos/owner/repository/full_commit_SHA_A:/home/jovyan.
- If a
repo2datamanifest is found in the repository, the data will be downloaded to and cached at:
tmp/
└── myst_data/
└── my-dataset
otherwise, it can be manually defined for an existing data under /tmp/myst_data as follows:
rees_resources.dataset_name = "my-dataset"
In either case, data will be mounted as /tmp/myst_data/my-dataset:/home/jovyan/data/my-dataset. If no data is provided, this step will be skipped.
Build your MyST article
MystBuilder(hub).build()Check out the built document
In your terminal:
npx serve /tmp/myst_repos/owner/repository/full_commit_SHA_A/_build/html
Visit ✨http://localhost:3000✨.
The Authenticator class handles loading authentication credentials from environment variables.
from myst_libre.tools.authenticator import Authenticator
auth = Authenticator()
print(auth._auth)The DockerRegistryClient class provides methods to interact with a Docker registry.
from myst_libre.tools.docker_registry_client import DockerRegistryClient
client = DockerRegistryClient(registry_url='https://my-registry.example.com', gh_user_repo_name='user/repo')
token = client.get_token()
print(token)The BuildSourceManager class manages source code repositories.
from myst_libre.tools.build_source_manager import BuildSourceManager
manager = BuildSourceManager(gh_user_repo_name='user/repo', gh_repo_commit_hash='commit_hash')
manager.git_clone_repo('/path/to/clone')
project_name = manager.get_project_name()
print(project_name)Description: Provides basic logging functionality and colored printing capabilities.
Description: Handles authentication by loading credentials from environment variables.
Inherited from: AbstractClass
Inputs: Environment variables DOCKER_PRIVATE_REGISTRY_USERNAME and DOCKER_PRIVATE_REGISTRY_PASSWORD
Description: Provides a client for making REST API calls.
Inherited from: Authenticator
Description: Manages interactions with a Docker registry.
Inherited from: Authenticator
Inputs:
registry_url: URL of the Docker registrygh_user_repo_name: GitHub user/repository nameauth: Authentication credentials
Description: Manages source code repositories.
Inherited from: AbstractClass
Inputs:
gh_user_repo_name: GitHub user/repository namegh_repo_commit_hash: Commit hash of the repository
Description: Manages JupyterHub instances locally.
Inherited from: AbstractClass
Inputs:
rees: Instance of the REES classregistry_url: URL of the Docker registrygh_user_repo_name: GitHub user/repository nameauth: Authentication credentialsbinder_image_tag: Docker image tagbuild_src_commit_hash: Commit hash of the repositorycontainer_data_mount_dir: Directory to mount data in the containercontainer_build_source_mount_dir: Directory to mount build source in the containerhost_data_parent_dir: Host directory for datahost_build_source_parent_dir: Host directory for build source
Description: Manages MyST markdown operations such as building and converting files.
Inherited from: AbstractClass
Inputs:
build_dir: Directory where the build will take placeenv_vars: Environment variables needed for the build processexecutable: Name of the MyST executable (default is 'myst')