| Name | myst-libre JSON |
| Version |
0.2.19
JSON |
| download |
| home_page | None |
| Summary | A Python library for managing source code repositories, interacting with Docker registries, handling MyST markdown operations, and spawning JupyterHub instances locally. |
| upload_time | 2025-10-12 13:24:01 |
| maintainer | None |
| docs_url | None |
| author | None |
| requires_python | >=3.7 |
| license | MIT License
Copyright (c) 2024 Agah Karakuzu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
|
| keywords |
myst
docker
jupyterhub
markdown
repository
|
| VCS |
 |
| bugtrack_url |
|
| requirements |
No requirements were recorded.
|
| Travis-CI |
No Travis.
|
| coveralls test coverage |
No coveralls.
|
# MyST Libre
&color=white)
Following the [REES](https://repo2docker.readthedocs.io/en/latest/specification.html), `myst-libre` streamlines building [✨MyST articles✨](https://mystmd.org/) in containers.
* A repository containing MyST sources
* A Docker image (built by [`binderhub`](https://github.com/jupyterhub/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`](https://neurolibre.org).
## Installation
### External dependencies
> [!IMPORTANT]
> Ensure the following prerequisites are installed:
- Node.js (For MyST) [installation guide](https://mystmd.org/guide/installing-prerequisites)
- Docker [installation guide](https://docs.docker.com/get-docker/)
### Install myst-libre
```
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:
```env
DOCKER_PRIVATE_REGISTRY_USERNAME=your_username
DOCKER_PRIVATE_REGISTRY_PASSWORD=your_password
CURVENOTE_TOKEN=your_curvenote_api_token
```
The `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](https://curvenote.com/profile?settings=true&tab=profile-api&subtab=general).
## Quick Start
**Import libraries and define REES resources**
Minimal example to create a rees object:
```python
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 the `gh_user_repo_name` repository (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 from `registry_url` (optional, default: None)
- `bh_image_prefix`: Binderhub names the images with a prefix, e.g., `<prefix>agahkarakuzu-2dmriscope-7a73fb`, typically set as `binder-`. This will be used in the regex pattern to find the "binderhub built image name" in the `registry_url`. See [reference docs](https://binderhub.readthedocs.io/en/latest/zero-to-binderhub/setup-binderhub.html) for more details.
- `bh_project_name`: See [this issue ](https://github.com/jupyterhub/binderhub/issues/800) (optional, default: [`registry_url` without `http://` or `https://`])
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**
1. If the `myst.yml` file in the `gh_user_repo_name` repository contains `project/thebe/binder/repo`, this image is prioritized.
2. If `project/thebe/binder/repo` is not specified, the `gh_user_repo_name` is 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**
```python
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 [`repo2data`](https://github.com/SIMEXP/Repo2Data) manifest 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**
```python
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`✨.
## Table of Contents
- [Myst Libre](#myst-libre)
- [Table of Contents](#table-of-contents)
- [Installation](#installation)
- [Usage](#usage)
- [Authentication](#authentication)
- [Docker Registry Client](#docker-registry-client)
- [Build Source Manager](#build-source-manager)
- [JupyterHub Local Spawner](#jupyterhub-local-spawner)
- [MyST Markdown Client](#myst-markdown-client)
- [Module and Class Descriptions](#module-and-class-descriptions)
- [Contributing](#contributing)
- [License](#license)
## Usage
### Authentication
The `Authenticator` class handles loading authentication credentials from environment variables.
```python
from myst_libre.tools.authenticator import Authenticator
auth = Authenticator()
print(auth._auth)
```
### Docker Registry Client
The DockerRegistryClient class provides methods to interact with a Docker registry.
```python
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)
```
### Build Source Manager
The BuildSourceManager class manages source code repositories.
```python
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)
```
## Module and Class Descriptions
### AbstractClass
**Description**: Provides basic logging functionality and colored printing capabilities.
### Authenticator
**Description**: Handles authentication by loading credentials from environment variables.
**Inherited from**: AbstractClass
**Inputs**: Environment variables `DOCKER_PRIVATE_REGISTRY_USERNAME` and `DOCKER_PRIVATE_REGISTRY_PASSWORD`
### RestClient
**Description**: Provides a client for making REST API calls.
**Inherited from**: Authenticator
### DockerRegistryClient
**Description**: Manages interactions with a Docker registry.
**Inherited from**: Authenticator
**Inputs**:
- `registry_url`: URL of the Docker registry
- `gh_user_repo_name`: GitHub user/repository name
- `auth`: Authentication credentials
### BuildSourceManager
**Description**: Manages source code repositories.
**Inherited from**: AbstractClass
**Inputs**:
- `gh_user_repo_name`: GitHub user/repository name
- `gh_repo_commit_hash`: Commit hash of the repository
### JupyterHubLocalSpawner
**Description**: Manages JupyterHub instances locally.
**Inherited from**: AbstractClass
**Inputs**:
- `rees`: Instance of the REES class
- `registry_url`: URL of the Docker registry
- `gh_user_repo_name`: GitHub user/repository name
- `auth`: Authentication credentials
- `binder_image_tag`: Docker image tag
- `build_src_commit_hash`: Commit hash of the repository
- `container_data_mount_dir`: Directory to mount data in the container
- `container_build_source_mount_dir`: Directory to mount build source in the container
- `host_data_parent_dir`: Host directory for data
- `host_build_source_parent_dir`: Host directory for build source
### MystMD
**Description**: Manages MyST markdown operations such as building and converting files.
**Inherited from**: AbstractClass
**Inputs**:
- `build_dir`: Directory where the build will take place
- `env_vars`: Environment variables needed for the build process
- `executable`: Name of the MyST executable (default is 'myst')
Raw data
{
"_id": null,
"home_page": null,
"name": "myst-libre",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "myst, docker, jupyterhub, markdown, repository",
"author": null,
"author_email": "agahkarakuzu <agahkarakuzu@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/b3/07/bbbf2146ccae38eb9e348e252af658b1406287cd49b63b27aa89cac2ba79/myst_libre-0.2.19.tar.gz",
"platform": null,
"description": "# MyST Libre\n\n&color=white)\n\nFollowing the [REES](https://repo2docker.readthedocs.io/en/latest/specification.html), `myst-libre` streamlines building [\u2728MyST articles\u2728](https://mystmd.org/) in containers.\n\n* A repository containing MyST sources\n* A Docker image (built by [`binderhub`](https://github.com/jupyterhub/binderhub)) in a public (or private) registry, including:\n * Dependencies to execute notebooks/markdown files in the MyST repository\n * JupyterHub (typically part of images built by `binderhub`)\n* Input data required by the executable content (optional)\n\nGiven these resources, myst-libre starts a Docker container, mounts the MyST repository and data (if available), and builds a MyST publication.\n\n> [!NOTE]\n> This project was started to support publishing MyST articles as living preprints on [`NeuroLibre`](https://neurolibre.org).\n\n## Installation\n\n### External dependencies \n\n> [!IMPORTANT]\n> Ensure the following prerequisites are installed:\n\n- Node.js (For MyST) [installation guide](https://mystmd.org/guide/installing-prerequisites)\n- Docker [installation guide](https://docs.docker.com/get-docker/)\n\n### Install myst-libre\n\n```\npip install myst-libre\n```\n\n**Set up environment variables:**\n\nIf you are using a private image registry and/or Curvenote CLI features, create a `.env` file in the project root and add the following:\n\n```env\nDOCKER_PRIVATE_REGISTRY_USERNAME=your_username\nDOCKER_PRIVATE_REGISTRY_PASSWORD=your_password\nCURVENOTE_TOKEN=your_curvenote_api_token\n```\n\nThe `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](https://curvenote.com/profile?settings=true&tab=profile-api&subtab=general).\n\n## Quick Start\n\n**Import libraries and define REES resources**\n\nMinimal example to create a rees object:\n\n```python\nfrom myst_libre.tools import JupyterHubLocalSpawner, MystMD\nfrom myst_libre.rees import REES\nfrom myst_libre.builders import MystBuilder\n\nrees = REES(dict(\n registry_url=\"https://your-registry.io\",\n gh_user_repo_name = \"owner/repository\"\n ))\n```\n\nOther optional parameters that can be passed to the REES constructor:\n\n\n- `gh_repo_commit_hash`: Full SHA commit hash of the `gh_user_repo_name` repository (optional, default: latest commit)\n- `binder_image_tag`: Full SHA commit hash at which a binder tag is available for the \"found image name\" (optional, default: latest)\n- `binder_image_name_override`: Override the \"found image name\" whose container will be used to build the MyST article (optional, default: None)\n- `dotenv`: Path to a directory containing the .env file for authentication credentials to pull images from `registry_url` (optional, default: None)\n- `bh_image_prefix`: Binderhub names the images with a prefix, e.g., `<prefix>agahkarakuzu-2dmriscope-7a73fb`, typically set as `binder-`. This will be used in the regex pattern to find the \"binderhub built image name\" in the `registry_url`. See [reference docs](https://binderhub.readthedocs.io/en/latest/zero-to-binderhub/setup-binderhub.html) for more details. \n- `bh_project_name`: See [this issue ](https://github.com/jupyterhub/binderhub/issues/800) (optional, default: [`registry_url` without `http://` or `https://`])\n\n\nNote that in this context what is meant by \"prefix\" is not the same as in the reference docs. (optional, default: `binder-`)\n\n**Image Selection Order**\n\n1. If the `myst.yml` file in the `gh_user_repo_name` repository contains `project/thebe/binder/repo`, this image is prioritized.\n2. If `project/thebe/binder/repo` is not specified, the `gh_user_repo_name` is used as the image name.\n\nNote 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`.\n\nIf you specify `binder_image_name_override`, it will be used as the repository name to locate the image.\n\nThis 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`.\n\nThe `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.\n\n**Fetch resources and spawn JupyterHub in the respective container**\n\n```python\nhub = JupyterHubLocalSpawner(rees_resources,\n host_build_source_parent_dir = '/tmp/myst_repos',\n container_build_source_mount_dir = '/home/jovyan', #default\n host_data_parent_dir = \"/tmp/myst_data\", #optional\n container_data_mount_dir = '/home/jovyan/data', #optional\n )\nhub.spawn_jupyter_hub()\n```\n\n* MyST repository will be cloned at:\n\n```\ntmp/\n\u2514\u2500\u2500 myst_repos/\n \u2514\u2500\u2500 owner/\n \u2514\u2500\u2500 repository/\n \u2514\u2500\u2500 full_commit_SHA_A/\n \u251c\u2500\u2500 myst.yml\n \u251c\u2500\u2500 _toc.yml\n \u251c\u2500\u2500 binder/\n \u2502 \u251c\u2500\u2500 requirements.txt (or other REES dependencies)\n \u2502 \u2514\u2500\u2500 data_requirement.json (optional)\n \u251c\u2500\u2500 content/\n \u2502 \u251c\u2500\u2500 my_notebook.ipynb\n \u2502 \u2514\u2500\u2500 my_myst_markdown.md\n \u251c\u2500\u2500 paper.md\n \u2514\u2500\u2500 paper.bib\n```\n\nRepository will be mounted to the container as `/tmp/myst_repos/owner/repository/full_commit_SHA_A:/home/jovyan`.\n\n* If a [`repo2data`](https://github.com/SIMEXP/Repo2Data) manifest is found in the repository, the data will be downloaded to and cached at:\n\n```\ntmp/\n\u2514\u2500\u2500 myst_data/\n \u2514\u2500\u2500 my-dataset\n```\n\notherwise, it can be manually defined for an existing data under `/tmp/myst_data` as follows:\n\n```\nrees_resources.dataset_name = \"my-dataset\"\n```\n\nIn 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.\n\n**Build your MyST article**\n\n```python\nMystBuilder(hub).build()\n```\n\n**Check out the built document**\n\nIn your terminal:\n\n```\nnpx serve /tmp/myst_repos/owner/repository/full_commit_SHA_A/_build/html\n```\n\nVisit \u2728`http://localhost:3000`\u2728.\n\n## Table of Contents\n\n- [Myst Libre](#myst-libre)\n - [Table of Contents](#table-of-contents)\n - [Installation](#installation)\n - [Usage](#usage)\n - [Authentication](#authentication)\n - [Docker Registry Client](#docker-registry-client)\n - [Build Source Manager](#build-source-manager)\n - [JupyterHub Local Spawner](#jupyterhub-local-spawner)\n - [MyST Markdown Client](#myst-markdown-client)\n - [Module and Class Descriptions](#module-and-class-descriptions)\n - [Contributing](#contributing)\n - [License](#license)\n\n## Usage\n\n### Authentication\n\nThe `Authenticator` class handles loading authentication credentials from environment variables.\n\n```python\nfrom myst_libre.tools.authenticator import Authenticator\n\nauth = Authenticator()\nprint(auth._auth)\n```\n\n\n### Docker Registry Client\n\nThe DockerRegistryClient class provides methods to interact with a Docker registry.\n\n```python\nfrom myst_libre.tools.docker_registry_client import DockerRegistryClient\n\nclient = DockerRegistryClient(registry_url='https://my-registry.example.com', gh_user_repo_name='user/repo')\ntoken = client.get_token()\nprint(token)\n```\n\n### Build Source Manager\n\nThe BuildSourceManager class manages source code repositories.\n\n```python\nfrom myst_libre.tools.build_source_manager import BuildSourceManager\n\nmanager = BuildSourceManager(gh_user_repo_name='user/repo', gh_repo_commit_hash='commit_hash')\nmanager.git_clone_repo('/path/to/clone')\nproject_name = manager.get_project_name()\nprint(project_name)\n```\n\n## Module and Class Descriptions\n\n### AbstractClass\n**Description**: Provides basic logging functionality and colored printing capabilities.\n\n### Authenticator\n**Description**: Handles authentication by loading credentials from environment variables. \n**Inherited from**: AbstractClass \n**Inputs**: Environment variables `DOCKER_PRIVATE_REGISTRY_USERNAME` and `DOCKER_PRIVATE_REGISTRY_PASSWORD`\n\n### RestClient\n**Description**: Provides a client for making REST API calls. \n**Inherited from**: Authenticator\n\n### DockerRegistryClient\n**Description**: Manages interactions with a Docker registry. \n**Inherited from**: Authenticator \n**Inputs**:\n- `registry_url`: URL of the Docker registry\n- `gh_user_repo_name`: GitHub user/repository name\n- `auth`: Authentication credentials\n\n### BuildSourceManager\n**Description**: Manages source code repositories. \n**Inherited from**: AbstractClass \n**Inputs**:\n- `gh_user_repo_name`: GitHub user/repository name\n- `gh_repo_commit_hash`: Commit hash of the repository\n\n### JupyterHubLocalSpawner\n**Description**: Manages JupyterHub instances locally. \n**Inherited from**: AbstractClass \n**Inputs**:\n- `rees`: Instance of the REES class\n- `registry_url`: URL of the Docker registry\n- `gh_user_repo_name`: GitHub user/repository name\n- `auth`: Authentication credentials\n- `binder_image_tag`: Docker image tag\n- `build_src_commit_hash`: Commit hash of the repository\n- `container_data_mount_dir`: Directory to mount data in the container\n- `container_build_source_mount_dir`: Directory to mount build source in the container\n- `host_data_parent_dir`: Host directory for data\n- `host_build_source_parent_dir`: Host directory for build source\n\n### MystMD\n**Description**: Manages MyST markdown operations such as building and converting files. \n**Inherited from**: AbstractClass \n**Inputs**:\n- `build_dir`: Directory where the build will take place\n- `env_vars`: Environment variables needed for the build process\n- `executable`: Name of the MyST executable (default is 'myst')\n",
"bugtrack_url": null,
"license": "MIT License\n \n Copyright (c) 2024 Agah Karakuzu\n \n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n \n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n \n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n ",
"summary": "A Python library for managing source code repositories, interacting with Docker registries, handling MyST markdown operations, and spawning JupyterHub instances locally.",
"version": "0.2.19",
"project_urls": {
"Homepage": "https://github.com/neurolibre/myst_libre"
},
"split_keywords": [
"myst",
" docker",
" jupyterhub",
" markdown",
" repository"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "1cc1e2afcb538edb3dd5fea3bc574a1d586ab60bfa51d82770b028c8c12d3957",
"md5": "0749683f29969f90c9f85383f2715d43",
"sha256": "b9cc4cd28b7d64a290b75f2c1a5af066218e43fb2824b8b88a53e08401358e2f"
},
"downloads": -1,
"filename": "myst_libre-0.2.19-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0749683f29969f90c9f85383f2715d43",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 29015,
"upload_time": "2025-10-12T13:23:59",
"upload_time_iso_8601": "2025-10-12T13:23:59.602531Z",
"url": "https://files.pythonhosted.org/packages/1c/c1/e2afcb538edb3dd5fea3bc574a1d586ab60bfa51d82770b028c8c12d3957/myst_libre-0.2.19-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "b307bbbf2146ccae38eb9e348e252af658b1406287cd49b63b27aa89cac2ba79",
"md5": "18ecd9426461ce666584e12e040b33ce",
"sha256": "71268144ec96653c4860cf9772f12e43680d2f44f15be64ecdf4d03dde64c769"
},
"downloads": -1,
"filename": "myst_libre-0.2.19.tar.gz",
"has_sig": false,
"md5_digest": "18ecd9426461ce666584e12e040b33ce",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 29313,
"upload_time": "2025-10-12T13:24:01",
"upload_time_iso_8601": "2025-10-12T13:24:01.158246Z",
"url": "https://files.pythonhosted.org/packages/b3/07/bbbf2146ccae38eb9e348e252af658b1406287cd49b63b27aa89cac2ba79/myst_libre-0.2.19.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-12 13:24:01",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "neurolibre",
"github_project": "myst_libre",
"github_not_found": true,
"lcname": "myst-libre"
}