# `pipmaster`: The Python Package Management Toolkit
<!-- Badges -->
[](https://badge.fury.io/py/pipmaster)
[](https://pypi.org/project/pipmaster/)
[](https://github.com/ParisNeo/pipmaster/blob/main/LICENSE)
[](https://github.com/ParisNeo/pipmaster/actions/workflows/docs.yml)
[](https://github.com/ParisNeo/pipmaster)
[](https://parisneo.github.io/pipmaster/)
`pipmaster` is a comprehensive Python library for declarative and programmatic package management. It provides a robust, unified interface to multiple package management backends like **`pip`** and **`uv`**, allowing you to automate installations, updates, environment checks, and more, directly from your Python code. With both **synchronous and asynchronous APIs**, it's designed to be a game-changer for developers who need to guarantee that their applications and tools work out-of-the-box for end-users by programmatically ensuring all dependencies are correctly installed.
Think of it as the swiss army knife for your application's setup scripts, build automation, or any task that requires reliable dependency management.
**View the full documentation at [parisneo.github.io/pipmaster/](https://parisneo.github.io/pipmaster/).**
## Core Philosophy
* **Declarative & Idempotent:** Use `ensure_packages` or `ensure_requirements` to define the desired state of your environment. `pipmaster` handles the rest, performing a single, efficient installation for all missing or outdated packages. This declarative approach means you can run your setup logic repeatedly without side effects, guaranteeing a consistent environment every time.
* **Programmatic Control:** Stop shelling out to `pip` with `os.system`. Manage your dependencies gracefully within your application logic, setup scripts, or automation tasks.
* **Multi-Backend Ready:** Seamlessly use the standard `pip` or switch to the high-performance `uv` backend. `conda` support is planned for the future.
* **Environment-Aware:** Target any Python virtual environment on your system simply by providing its path, making it perfect for managing complex projects or build servers.
* **Asynchronous First:** A complete `async` API is available for modern, non-blocking applications.
* **Safe and Informative:** A built-in `dry_run` mode lets you preview changes without modifying your system, and the `verbose` option provides detailed output for debugging.
## Feature Overview
| Feature | `pip` Backend | `uv` Backend (Experimental) | `async` Support |
| -------------------------------------------- | :-----------: | :-------------------------: | :-------------: |
| **Ensure Package State (`ensure_packages`)** | ✅ | ❌ | ✅ |
| **Ensure from `requirements.txt`** | ✅ | ❌ | ✅ |
| Install / Upgrade Packages | ✅ | ✅ | ✅ |
| Uninstall Packages | ✅ | ✅ | ✅ |
| Check for Vulnerabilities (`pip-audit`) | ✅ | N/A | ✅ |
| Check Installed Status (`is_installed`) | ✅ | N/A | (Sync) |
| Create Virtual Environments | N/A | ✅ | N/A |
| Run Ephemeral Tools (`uvx`) | N/A | ✅ | N/A |
| Dry Run Mode | ✅ | ❌ | ✅ |
## Installation
`pipmaster` requires Python 3.8 or higher.
```bash
pip install pipmaster
```
### Optional Features
`pipmaster` offers optional features that require extra dependencies. Install them as needed:
* **Vulnerability Auditing:** Enables the `check_vulnerabilities` function using `pip-audit`.
```bash
pip install pipmaster[audit]
```
* **Development Environment:** For contributing to `pipmaster`, this includes all tools for testing, linting, and building documentation.
```bash
git clone https://github.com/ParisNeo/pipmaster.git
cd pipmaster
pip install -e .[dev]
```
* **All Extras:**
```bash
pip install pipmaster[all]
```
## The Game-Changer: Ensuring Dependencies Automatically
Forget manual setup instructions. The `ensure_*` methods are the heart of `pipmaster`, designed to be a game-changer for any Python application that needs to **just work out of the box**. By embedding dependency checks directly into your application's startup logic, you provide a seamless experience for your users. `pipmaster` programmatically verifies that all required packages are present and meet version specifications, installing or updating them only when necessary. This is the key to creating robust, self-sufficient applications that eliminate "dependency hell" for the end-user.
These methods are **idempotent** and **efficient**. You can call them every time your application runs; they'll quickly check the environment and trigger a single, batch installation command only for the packages that are missing or outdated. This is far superior to manually running `pip install` commands.
### Declarative Dependencies in Code with `ensure_packages`
For ultimate control, define dependencies directly in your Python code. This is perfect for applications or libraries that need to bundle their dependency logic. `ensure_packages` intelligently handles a single package string, a list of packages, or a dictionary for more complex versioning.
```python
import pipmaster as pm
# 1. Ensure a SINGLE package is installed (using a string)
print("--- Ensuring 'rich' is installed ---")
pm.ensure_packages("rich", verbose=True)
# 2. Ensure a LIST of packages are installed
print("\n--- Ensuring a list of packages ---")
pm.ensure_packages(["pandas", "numpy>=1.20"], verbose=True)
# 3. Ensure a DICTIONARY of requirements are met
print("\n--- Ensuring a dictionary of requirements ---")
requirements = {
"requests": ">=2.25.0",
"tqdm": None # We need it, but any installed version is fine
}
if pm.ensure_packages(requirements, verbose=True):
print("\nAll dictionary requirements are met!")
```
### Effortless Syncing with `ensure_requirements`
If you already use `requirements.txt` files, `ensure_requirements` is your one-line solution. `pipmaster` will parse the file—including advanced options like `--index-url` or `--extra-index-url`—and bring your environment into compliance. It's the perfect way to automate the standard `pip install -r requirements.txt` workflow.
```python
import pipmaster as pm
# Assuming you have a 'requirements.txt' in your project root:
# --extra-index-url https://custom-repo.org/simple
# rich # For nice terminal output
# pandas==2.1.0
print("\n--- Ensuring dependencies from requirements.txt ---")
# Create a dummy file for the example
with open("requirements-demo.txt", "w") as f:
f.write("rich\n")
if pm.ensure_requirements("requirements-demo.txt", verbose=True):
print("\nAll dependencies from file are met!")
```
## Advanced Usage & Recipes
### Recipe 1: Synchronous vs. Asynchronous API
`pipmaster` provides a complete asynchronous API. Simply prefix function calls with `async_` and `await` them.
```python
import pipmaster as pm
import asyncio
# Synchronous call
pm.ensure_packages("httpx")
# Asynchronous equivalent
async def main():
await pm.async_ensure_packages("httpx")
# Also works with requirements files
# await pm.async_ensure_requirements("requirements.txt")
asyncio.run(main())
```
### Recipe 2: Using a Specific Backend (`pip` vs. `uv`)
While module-level functions default to the current environment's `pip`, you can get a dedicated manager to control a specific backend or environment.
#### `pip` Backend
```python
from pipmaster import get_pip_manager
# Target a specific Python environment
other_env_path = "/path/to/venv/bin/python" # Or "C:/path/to/venv/Scripts/python.exe"
# pip_manager = get_pip_manager(python_executable=other_env_path)
# pip_manager.install("requests")
```
#### `uv` Backend
This requires `uv` to be installed and available on your system's PATH.
```python
from pipmaster import get_uv_manager
import os
import shutil
temp_env_path = "./my_uv_test_env"
try:
uv_manager = get_uv_manager()
print(f"\n--- Creating new uv environment at {temp_env_path} ---")
if uv_manager.create_env(path=temp_env_path):
print("Environment created successfully.")
uv_manager.install("numpy")
print("Numpy installed in the new environment.")
print("\n--- Running black --version with uv's tool runner ---")
uv_manager.run_with_uvx(["black", "--version"], verbose=True)
except FileNotFoundError:
print("Skipping uv examples: 'uv' executable not found in PATH.")
finally:
if os.path.exists(temp_env_path):
shutil.rmtree(temp_env_path)
```
### Recipe 3: Inspecting the Environment
Check the status of packages without changing anything. These functions are synchronous as they rely on the fast `importlib.metadata` library.
```python
import pipmaster as pm
if pm.is_installed("requests"):
print("Requests is installed.")
if pm.is_installed("packaging", version_specifier=">=21.0"):
print("A compatible version of 'packaging' is installed.")
numpy_version = pm.get_installed_version("numpy")
if numpy_version:
print(f"Installed numpy version: {numpy_version}")
package_info = pm.get_package_info("pipmaster")
if package_info:
print("\n--- pipmaster info ---\n" + package_info)
```
### Recipe 4: Safety Features (Dry Run & Auditing)
Preview changes and check for security vulnerabilities.
```python
import pipmaster as pm
print("\n--- Dry Run Examples ---")
pm.install("requests", dry_run=True, verbose=True)
pm.ensure_packages({"numpy": ">=1.20"}, dry_run=True, verbose=True)
pm.ensure_requirements("requirements-demo.txt", dry_run=True, verbose=True) # Using the file from before
print("\n--- Vulnerability Check ---")
try:
vulnerabilities_found, report = pm.check_vulnerabilities()
if vulnerabilities_found:
print("WARNING: Vulnerabilities found in environment!")
else:
print("No known vulnerabilities found.")
except FileNotFoundError:
print("Skipping check: pip-audit not found. Install with 'pip install pipmaster[audit]'")
```
## Contributing
Contributions are welcome! If you find a bug, have a feature request, or want to contribute code:
1. **Search Issues:** Check the GitHub Issues page to see if a similar issue or request already exists.
2. **Open an Issue:** If not, open a new issue describing the bug or feature.
3. **Fork & Pull Request:** For code contributions, please fork the repository, create a new branch for your changes, and submit a pull request. Ensure your code includes tests and follows the project's style guidelines.
## License
This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details.
Raw data
{
"_id": null,
"home_page": null,
"name": "pipmaster",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "pip, package manager, installer, dependency, venv, environment",
"author": null,
"author_email": "ParisNeo <parisneoai@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/f1/b4/8602218a5a157346d74ba7d04b07b18f69c3300162716a455609f1f7b66c/pipmaster-1.0.3.tar.gz",
"platform": null,
"description": "# `pipmaster`: The Python Package Management Toolkit\r\n\r\n<!-- Badges -->\r\n[](https://badge.fury.io/py/pipmaster)\r\n[](https://pypi.org/project/pipmaster/)\r\n[](https://github.com/ParisNeo/pipmaster/blob/main/LICENSE)\r\n[](https://github.com/ParisNeo/pipmaster/actions/workflows/docs.yml)\r\n[](https://github.com/ParisNeo/pipmaster)\r\n[](https://parisneo.github.io/pipmaster/) \r\n\r\n`pipmaster` is a comprehensive Python library for declarative and programmatic package management. It provides a robust, unified interface to multiple package management backends like **`pip`** and **`uv`**, allowing you to automate installations, updates, environment checks, and more, directly from your Python code. With both **synchronous and asynchronous APIs**, it's designed to be a game-changer for developers who need to guarantee that their applications and tools work out-of-the-box for end-users by programmatically ensuring all dependencies are correctly installed.\r\n\r\nThink of it as the swiss army knife for your application's setup scripts, build automation, or any task that requires reliable dependency management.\r\n\r\n**View the full documentation at [parisneo.github.io/pipmaster/](https://parisneo.github.io/pipmaster/).**\r\n\r\n## Core Philosophy\r\n\r\n* **Declarative & Idempotent:** Use `ensure_packages` or `ensure_requirements` to define the desired state of your environment. `pipmaster` handles the rest, performing a single, efficient installation for all missing or outdated packages. This declarative approach means you can run your setup logic repeatedly without side effects, guaranteeing a consistent environment every time.\r\n* **Programmatic Control:** Stop shelling out to `pip` with `os.system`. Manage your dependencies gracefully within your application logic, setup scripts, or automation tasks.\r\n* **Multi-Backend Ready:** Seamlessly use the standard `pip` or switch to the high-performance `uv` backend. `conda` support is planned for the future.\r\n* **Environment-Aware:** Target any Python virtual environment on your system simply by providing its path, making it perfect for managing complex projects or build servers.\r\n* **Asynchronous First:** A complete `async` API is available for modern, non-blocking applications.\r\n* **Safe and Informative:** A built-in `dry_run` mode lets you preview changes without modifying your system, and the `verbose` option provides detailed output for debugging.\r\n\r\n## Feature Overview\r\n\r\n| Feature | `pip` Backend | `uv` Backend (Experimental) | `async` Support |\r\n| -------------------------------------------- | :-----------: | :-------------------------: | :-------------: |\r\n| **Ensure Package State (`ensure_packages`)** | \u2705 | \u274c | \u2705 |\r\n| **Ensure from `requirements.txt`** | \u2705 | \u274c | \u2705 |\r\n| Install / Upgrade Packages | \u2705 | \u2705 | \u2705 |\r\n| Uninstall Packages | \u2705 | \u2705 | \u2705 |\r\n| Check for Vulnerabilities (`pip-audit`) | \u2705 | N/A | \u2705 |\r\n| Check Installed Status (`is_installed`) | \u2705 | N/A | (Sync) |\r\n| Create Virtual Environments | N/A | \u2705 | N/A |\r\n| Run Ephemeral Tools (`uvx`) | N/A | \u2705 | N/A |\r\n| Dry Run Mode | \u2705 | \u274c | \u2705 |\r\n\r\n## Installation\r\n\r\n`pipmaster` requires Python 3.8 or higher.\r\n\r\n```bash\r\npip install pipmaster\r\n```\r\n\r\n### Optional Features\r\n\r\n`pipmaster` offers optional features that require extra dependencies. Install them as needed:\r\n\r\n* **Vulnerability Auditing:** Enables the `check_vulnerabilities` function using `pip-audit`.\r\n ```bash\r\n pip install pipmaster[audit]\r\n ```\r\n\r\n* **Development Environment:** For contributing to `pipmaster`, this includes all tools for testing, linting, and building documentation.\r\n ```bash\r\n git clone https://github.com/ParisNeo/pipmaster.git\r\n cd pipmaster\r\n pip install -e .[dev]\r\n ```\r\n* **All Extras:**\r\n ```bash\r\n pip install pipmaster[all]\r\n ```\r\n\r\n## The Game-Changer: Ensuring Dependencies Automatically\r\n\r\nForget manual setup instructions. The `ensure_*` methods are the heart of `pipmaster`, designed to be a game-changer for any Python application that needs to **just work out of the box**. By embedding dependency checks directly into your application's startup logic, you provide a seamless experience for your users. `pipmaster` programmatically verifies that all required packages are present and meet version specifications, installing or updating them only when necessary. This is the key to creating robust, self-sufficient applications that eliminate \"dependency hell\" for the end-user.\r\n\r\nThese methods are **idempotent** and **efficient**. You can call them every time your application runs; they'll quickly check the environment and trigger a single, batch installation command only for the packages that are missing or outdated. This is far superior to manually running `pip install` commands.\r\n\r\n### Declarative Dependencies in Code with `ensure_packages`\r\n\r\nFor ultimate control, define dependencies directly in your Python code. This is perfect for applications or libraries that need to bundle their dependency logic. `ensure_packages` intelligently handles a single package string, a list of packages, or a dictionary for more complex versioning.\r\n\r\n```python\r\nimport pipmaster as pm\r\n\r\n# 1. Ensure a SINGLE package is installed (using a string)\r\nprint(\"--- Ensuring 'rich' is installed ---\")\r\npm.ensure_packages(\"rich\", verbose=True)\r\n\r\n# 2. Ensure a LIST of packages are installed\r\nprint(\"\\n--- Ensuring a list of packages ---\")\r\npm.ensure_packages([\"pandas\", \"numpy>=1.20\"], verbose=True)\r\n\r\n# 3. Ensure a DICTIONARY of requirements are met\r\nprint(\"\\n--- Ensuring a dictionary of requirements ---\")\r\nrequirements = {\r\n \"requests\": \">=2.25.0\",\r\n \"tqdm\": None # We need it, but any installed version is fine\r\n}\r\nif pm.ensure_packages(requirements, verbose=True):\r\n print(\"\\nAll dictionary requirements are met!\")\r\n```\r\n\r\n### Effortless Syncing with `ensure_requirements`\r\n\r\nIf you already use `requirements.txt` files, `ensure_requirements` is your one-line solution. `pipmaster` will parse the file\u2014including advanced options like `--index-url` or `--extra-index-url`\u2014and bring your environment into compliance. It's the perfect way to automate the standard `pip install -r requirements.txt` workflow.\r\n\r\n```python\r\nimport pipmaster as pm\r\n\r\n# Assuming you have a 'requirements.txt' in your project root:\r\n# --extra-index-url https://custom-repo.org/simple\r\n# rich # For nice terminal output\r\n# pandas==2.1.0\r\n\r\nprint(\"\\n--- Ensuring dependencies from requirements.txt ---\")\r\n# Create a dummy file for the example\r\nwith open(\"requirements-demo.txt\", \"w\") as f:\r\n f.write(\"rich\\n\")\r\nif pm.ensure_requirements(\"requirements-demo.txt\", verbose=True):\r\n print(\"\\nAll dependencies from file are met!\")\r\n```\r\n\r\n## Advanced Usage & Recipes\r\n\r\n### Recipe 1: Synchronous vs. Asynchronous API\r\n\r\n`pipmaster` provides a complete asynchronous API. Simply prefix function calls with `async_` and `await` them.\r\n\r\n```python\r\nimport pipmaster as pm\r\nimport asyncio\r\n\r\n# Synchronous call\r\npm.ensure_packages(\"httpx\")\r\n\r\n# Asynchronous equivalent\r\nasync def main():\r\n await pm.async_ensure_packages(\"httpx\")\r\n # Also works with requirements files\r\n # await pm.async_ensure_requirements(\"requirements.txt\")\r\n\r\nasyncio.run(main())\r\n```\r\n\r\n### Recipe 2: Using a Specific Backend (`pip` vs. `uv`)\r\n\r\nWhile module-level functions default to the current environment's `pip`, you can get a dedicated manager to control a specific backend or environment.\r\n\r\n#### `pip` Backend\r\n\r\n```python\r\nfrom pipmaster import get_pip_manager\r\n\r\n# Target a specific Python environment\r\nother_env_path = \"/path/to/venv/bin/python\" # Or \"C:/path/to/venv/Scripts/python.exe\"\r\n# pip_manager = get_pip_manager(python_executable=other_env_path)\r\n# pip_manager.install(\"requests\")\r\n```\r\n\r\n#### `uv` Backend\r\n\r\nThis requires `uv` to be installed and available on your system's PATH.\r\n\r\n```python\r\nfrom pipmaster import get_uv_manager\r\nimport os\r\nimport shutil\r\n\r\ntemp_env_path = \"./my_uv_test_env\"\r\n\r\ntry:\r\n uv_manager = get_uv_manager()\r\n\r\n print(f\"\\n--- Creating new uv environment at {temp_env_path} ---\")\r\n if uv_manager.create_env(path=temp_env_path):\r\n print(\"Environment created successfully.\")\r\n uv_manager.install(\"numpy\")\r\n print(\"Numpy installed in the new environment.\")\r\n\r\n print(\"\\n--- Running black --version with uv's tool runner ---\")\r\n uv_manager.run_with_uvx([\"black\", \"--version\"], verbose=True)\r\n\r\nexcept FileNotFoundError:\r\n print(\"Skipping uv examples: 'uv' executable not found in PATH.\")\r\nfinally:\r\n if os.path.exists(temp_env_path):\r\n shutil.rmtree(temp_env_path)\r\n```\r\n\r\n### Recipe 3: Inspecting the Environment\r\n\r\nCheck the status of packages without changing anything. These functions are synchronous as they rely on the fast `importlib.metadata` library.\r\n\r\n```python\r\nimport pipmaster as pm\r\n\r\nif pm.is_installed(\"requests\"):\r\n print(\"Requests is installed.\")\r\n\r\nif pm.is_installed(\"packaging\", version_specifier=\">=21.0\"):\r\n print(\"A compatible version of 'packaging' is installed.\")\r\n\r\nnumpy_version = pm.get_installed_version(\"numpy\")\r\nif numpy_version:\r\n print(f\"Installed numpy version: {numpy_version}\")\r\n\r\npackage_info = pm.get_package_info(\"pipmaster\")\r\nif package_info:\r\n print(\"\\n--- pipmaster info ---\\n\" + package_info)\r\n```\r\n\r\n### Recipe 4: Safety Features (Dry Run & Auditing)\r\n\r\nPreview changes and check for security vulnerabilities.\r\n\r\n```python\r\nimport pipmaster as pm\r\n\r\nprint(\"\\n--- Dry Run Examples ---\")\r\npm.install(\"requests\", dry_run=True, verbose=True)\r\npm.ensure_packages({\"numpy\": \">=1.20\"}, dry_run=True, verbose=True)\r\npm.ensure_requirements(\"requirements-demo.txt\", dry_run=True, verbose=True) # Using the file from before\r\n\r\nprint(\"\\n--- Vulnerability Check ---\")\r\ntry:\r\n vulnerabilities_found, report = pm.check_vulnerabilities()\r\n if vulnerabilities_found:\r\n print(\"WARNING: Vulnerabilities found in environment!\")\r\n else:\r\n print(\"No known vulnerabilities found.\")\r\nexcept FileNotFoundError:\r\n print(\"Skipping check: pip-audit not found. Install with 'pip install pipmaster[audit]'\")\r\n\r\n```\r\n\r\n## Contributing\r\n\r\nContributions are welcome! If you find a bug, have a feature request, or want to contribute code:\r\n\r\n1. **Search Issues:** Check the GitHub Issues page to see if a similar issue or request already exists.\r\n2. **Open an Issue:** If not, open a new issue describing the bug or feature.\r\n3. **Fork & Pull Request:** For code contributions, please fork the repository, create a new branch for your changes, and submit a pull request. Ensure your code includes tests and follows the project's style guidelines.\r\n\r\n## License\r\n\r\nThis project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details.\r\n",
"bugtrack_url": null,
"license": null,
"summary": "A versatile Python package manager utility for simplifying package installation, updates, checks, and environment management.",
"version": "1.0.3",
"project_urls": {
"Homepage": "https://github.com/ParisNeo/pipmaster",
"Issues": "https://github.com/ParisNeo/pipmaster/issues",
"Repository": "https://github.com/ParisNeo/pipmaster"
},
"split_keywords": [
"pip",
" package manager",
" installer",
" dependency",
" venv",
" environment"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "8e9bf7b22b49d6b4e928d291b8fba234216664e3679db142246c30e2ab6308e5",
"md5": "95dddbf417202acd0b40d804a8244dcc",
"sha256": "1542f4a37b517898c51f718ff08ab7e2c7b391f1a9ac734954b7caefb4c9616a"
},
"downloads": -1,
"filename": "pipmaster-1.0.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "95dddbf417202acd0b40d804a8244dcc",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 27173,
"upload_time": "2025-08-28T18:39:08",
"upload_time_iso_8601": "2025-08-28T18:39:08.574692Z",
"url": "https://files.pythonhosted.org/packages/8e/9b/f7b22b49d6b4e928d291b8fba234216664e3679db142246c30e2ab6308e5/pipmaster-1.0.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "f1b48602218a5a157346d74ba7d04b07b18f69c3300162716a455609f1f7b66c",
"md5": "2c075be3398ae68c05f3213d261ee17d",
"sha256": "3353694b3b8164086419bcc5cebdb5c37e4c9a223f25b94b421b3bd1b865fb8b"
},
"downloads": -1,
"filename": "pipmaster-1.0.3.tar.gz",
"has_sig": false,
"md5_digest": "2c075be3398ae68c05f3213d261ee17d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 36346,
"upload_time": "2025-08-28T18:39:11",
"upload_time_iso_8601": "2025-08-28T18:39:11.241281Z",
"url": "https://files.pythonhosted.org/packages/f1/b4/8602218a5a157346d74ba7d04b07b18f69c3300162716a455609f1f7b66c/pipmaster-1.0.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-28 18:39:11",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ParisNeo",
"github_project": "pipmaster",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "packaging",
"specs": [
[
">=",
"21.0"
]
]
},
{
"name": "ascii_colors",
"specs": [
[
">=",
"0.10.1"
]
]
}
],
"lcname": "pipmaster"
}