Registry / devops / pyproject-api

pyproject-api

JSON →
library1.11.0pypypi✓ verified 27d ago

pyproject-api is a Python library that provides an abstract API for interacting with `pyproject.toml`-based projects. It standardizes the communication with various build backends (like setuptools, Hatchling, Flit) as defined by PEP 517 and PEP 660, allowing tools to build, inspect, and manage Python packages without direct knowledge of the underlying build system. The library is actively maintained by the tox-dev team and is currently at version 1.10.0, with regular releases to support new Python versions and address issues.

pip install pyproject-api
INSTALL
IMPORT
SIG · PYPROJECT-API
P
pyproject-api
devopspythonv1.11.0
Install
1.7s avg
Import
182ms
Disk
17MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.11.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.190s · 18.9MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.7s · import 0.174s · 19MB
17MB installed
● package 17MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Frontend
from pyproject_api import Frontend
The primary class for interacting with a pyproject.toml based project and its build backend.
BackendFailed
from pyproject_api import BackendFailed
Exception raised when the underlying build backend fails.

This quickstart demonstrates how to use `pyproject_api.Frontend` to programmatically interact with a project structured around `pyproject.toml`. It sets up a minimal project with a dummy build backend, then uses `Frontend` to query build requirements and simulate building a wheel. The `backend_paths` argument is essential for `pyproject-api` to locate and import your custom build backend module.

import sys from pathlib import Path import tempfile import shutil # Create a temporary project directory temp_dir = Path(tempfile.mkdtemp()) project_root = temp_dir / "my_project" project_root.mkdir() # Create a minimal pyproject.toml pyproject_toml_content = ''' [build-system] requires = ["my-dummy-backend"] build-backend = "my_dummy_backend:MyDummyBackend" [project] name = "my-example-package" version = "0.0.1" ''' (project_root / "pyproject.toml").write_text(pyproject_toml_content) # Create a dummy build backend module (my_dummy_backend.py) backend_module_content = ''' from pathlib import Path class MyDummyBackend: def __init__(self, directory): # pyproject-api passes the project directory self.directory = Path(directory) self.name = "my-example-package" def get_requires_for_build_wheel(self, config_settings=None): return [] def build_wheel(self, wheel_directory, config_settings=None, metadata_directory=None): # Simulate building a wheel file wheel_name = f"{self.name}-0.0.1-py3-none-any.whl" (Path(wheel_directory) / wheel_name).touch() return wheel_name ''' (project_root / "my_dummy_backend.py").write_text(backend_module_content) from pyproject_api import Frontend, BackendFailed print(f"Created temporary project at: {project_root}") try: # Initialize the Frontend to interact with our dummy project # backend_paths is crucial to make 'my_dummy_backend' importable frontend = Frontend( root=project_root, backend_paths=[project_root], backend_module="my_dummy_backend", backend_obj="MyDummyBackend", # The class name to instantiate requires=[], # Our dummy backend doesn't have build requirements itself reuse_backend=False ) # Get build requirements (should be empty for our dummy backend) build_requirements = frontend.get_requires_for_build_wheel() print(f"Build requirements reported by backend: {build_requirements.requires}") # Build a wheel build_dir = temp_dir / "dist" build_dir.mkdir() print(f"Attempting to build wheel into: {build_dir}") wheel_result = frontend.build_wheel(build_dir) print(f"Successfully built wheel: {wheel_result.path.name}") print(f"Wheel file location: {wheel_result.path}") except BackendFailed as e: print(f"Backend operation failed: {e.exc_msg}") print(f"Backend stdout: {e.out}") print(f"Backend stderr: {e.err}") except Exception as e: print(f"An unexpected error occurred: {e}") finally: # Clean up the temporary directory if temp_dir.exists(): shutil.rmtree(temp_dir) print(f"Cleaned up temporary directory: {temp_dir}")
Debug
Known issues
breakingPython 3.9 support was dropped in version 1.10.0. Python 3.8 support was dropped in version 1.9.0. The library now requires Python 3.10 or newer.
fix
Upgrade your Python environment to 3.10 or higher. For older Python versions, use pyproject-api <1.9.0 for Python 3.9, or pyproject-api <1.8.0 for Python 3.8.
affects: >=1.9.0
gotchapyproject-api provides an API to interact with build backends, but it does not include the build backends themselves. You must ensure that the build backend specified in `pyproject.toml` (e.g., `setuptools`, `hatchling`, `flit_core`) is correctly declared in `build-system.requires` and is installable/provisionable within the environment where `pyproject-api` operates.
fix
Always include the necessary build backend in your `pyproject.toml`'s `[build-system] requires` section. If an operation fails with `BackendFailed`, verify the backend's presence and functionality.
affects: all
gotchaMisconfigured or invalid `pyproject.toml` files can lead to obscure errors, as the issues might originate from the build backend and be re-reported through `pyproject-api` without clear context on the initial problem within the TOML structure itself.
fix
Thoroughly validate your `pyproject.toml` content against PEP specifications (PEP 517, PEP 518, PEP 621) and the requirements of your chosen build backend. Use tools like `validate-pyproject` or `check-wheel-contents` for pre-build validation.
affects: all
breakingThe class `pyproject_api.Frontend` was made an Abstract Base Class (ABC) in version 1.7.0. Attempting to instantiate `pyproject_api.Frontend` directly in versions 1.7.0 or newer will raise a `TypeError` with the message 'Can't instantiate abstract class Frontend without an implementation for abstract method '_send_msg''.
fix
If your code directly instantiates `pyproject_api.Frontend`, update it to use a concrete subclass such as `pyproject_api.pip_frontend.PipFrontend` (if `pip` is installed), or implement your own custom subclass that provides an implementation for the abstract method `_send_msg`. Alternatively, if direct instantiation of the base `Frontend` class is required for compatibility with older code, pin `pyproject-api < 1.7.0`.
affects: >=1.7.0
Upgrade
Version history
1.11.0latest on PyPI · released Jul 21, 2026
Audit
Dependencies
pythonrequiredRequires Python 3.10 or newer.
Agent activity
18 hits · last 30 days
node
14
Resources
pyproject-api — pip install pyproject-api · libregistry