| name | pyproject-toml |
| version | 1.0.0 |
| description | Configure Python projects with pyproject.toml for modern packaging, tools, and dependency management |
| author | workspace-hub |
| category | devtools |
| tags | ["python","pyproject","configuration","packaging","build-system"] |
| platforms | ["python"] |
pyproject.toml Configuration Skill
Master pyproject.toml for modern Python project configuration, build systems, tool settings, and dependency management.
When to Use This Skill
Use pyproject.toml configuration when you need:
- Project metadata - Name, version, description, authors
- Dependency management - Core and optional dependencies
- Build configuration - Setuptools, hatch, flit, or poetry
- Tool configuration - pytest, ruff, mypy, black, isort
- Entry points - CLI scripts and plugins
- Package discovery - Source directory configuration
Avoid when:
- Legacy projects requiring setup.py (rare, migrate instead)
- Non-Python projects
Core Structure
Complete pyproject.toml Template
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "my-project"
version = "0.1.0"
description = "A comprehensive Python project template"
readme = "README.md"
requires-python = ">=3.10"
license = {text = "MIT"}
authors = [
{name = "Your Name", email = "your.email@example.com"}
]
maintainers = [
{name = "Your Name", email = "your.email@example.com"}
]
keywords = ["python", "template", "project"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
,
]
= [
,
,
,
,
]
= [
,
,
,
,
,
,
]
= [
,
,
]
= [
,
,
]
= [
,
]
=
=
=
=
=
=
=
=
=
=
= { = }
=
= []
= []
= []
= [, , ]
= [
,
,
,
,
]
=
= []
= [, ]
= []
= []
= [
,
,
,
,
]
= [
,
,
,
]
= [
,
,
]
= []
=
=
= [
,
,
,
]
= []
= [
,
,
,
,
,
,
]
=
=
=
=
=
=
=
= [
,
,
,
,
,
,
]
= [
,
,
,
,
,
,
,
,
,
]
= [
,
,
,
]
= []
= []
= [, ]
= []
= []
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
= [
,
,
,
]
= [
,
,
,
,
]
=
=
= [, , ]
=
=
=
=
= []
= [, , ]
=
=
=
=
=
=
=
=
=
=
=
= [
,
,
]
= [
,
]
Section-by-Section Guide
1. Build System
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"
Alternative build backends:
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[build-system]
requires = ["flit_core>=3.4"]
build-backend = "flit_core.buildapi"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[build-system]
requires = ["pdm-backend"]
build-backend = "pdm.backend"
2. Project Metadata
[project]
name = "my-project"
version = "0.1.0"
description = "Short description"
readme = "README.md"
requires-python = ">=3.10"
license = {text = "MIT"}
authors = [
{name = "Name", email = "email@example.com"}
]
keywords = ["keyword1", "keyword2"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
]
3. Dependencies
[project]
dependencies = [
"pandas>=2.0.0",
"numpy>=1.24,<2.0",
"requests~=2.28",
"click==8.1.3",
"pyyaml",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0",
"ruff>=0.1.0",
]
viz = [
"plotly>=5.0",
"matplotlib>=3.7",
]
all = [
"my-project[dev,viz]",
]
4. Package Discovery
Src layout (recommended):
[tool.setuptools]
package-dir = {"" = "src"}
[tool.setuptools.packages.find]
where = ["src"]
include = ["my_project*"]
exclude = ["tests*"]
Flat layout:
[tool.setuptools.packages.find]
include = ["my_project*"]
exclude = ["tests*"]
Include data files:
[tool.setuptools.package-data]
my_project = [
"*.yaml",
"*.json",
"data/*.csv",
"templates/*.html",
]
5. Entry Points
CLI scripts:
[project.scripts]
my-cli = "my_project.cli:main"
my-tool = "my_project.tools:run"
Python code:
import click
@click.command()
@click.option("--name", default="World")
def main(name: str) -> None:
"""CLI entry point."""
click.echo(f"Hello, {name}!")
if __name__ == "__main__":
main()
Plugin system:
[project.entry-points."my_project.plugins"]
csv = "my_project.plugins.csv:CSVPlugin"
json = "my_project.plugins.json:JSONPlugin"
Tool-Specific Configurations
pytest
[tool.pytest.ini_options]
minversion = "7.0"
testpaths = ["tests"]
addopts = [
"-v",
"--tb=short",
"-ra",
"--strict-markers",
"--cov=src",
"--cov-report=html",
]
markers = [
"slow: slow tests",
"integration: integration tests",
]
ruff (Modern Linter)
[tool.ruff]
line-length = 88
target-version = "py310"
[tool.ruff.lint]
select = ["E", "W", "F", "I", "B", "C4", "UP"]
ignore = ["E501"]
[tool.ruff.format]
quote-style = "double"
mypy (Type Checker)
[tool.mypy]
python_version = "3.10"
strict = true
warn_return_any = true
[[tool.mypy.overrides]]
module = ["pandas.*", "numpy.*"]
ignore_missing_imports = true
Complete Examples
Example 1: Data Processing Library
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "data-processor"
version = "1.0.0"
description = "Data processing utilities for engineering workflows"
readme = "README.md"
requires-python = ">=3.10"
license = {text = "MIT"}
dependencies = [
"pandas>=2.0.0",
"numpy>=1.24.0",
"openpyxl>=3.1.0",
"pyyaml>=6.0",
]
[project.optional-dependencies]
viz = ["plotly>=5.15.0"]
dev = ["pytest>=7.0", "ruff>=0.1.0", "mypy>=1.4"]
[project.scripts]
data-process = "data_processor.cli:main"
[tool.setuptools.packages.find]
where = ["src"]
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = ["-v", "--cov=src"]
[tool.ruff]
line-length = 88
select = ["E", "W", "F", "I"]
Example 2: Web Scraping Package
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "energy-scraper"
version = "0.1.0"
description = "BSEE and SODIR data extraction utilities"
requires-python = ">=3.10"
dependencies = [
"scrapy>=2.12.0",
"selenium>=4.15.0",
"beautifulsoup4>=4.12.0",
"pandas>=2.0.0",
"pyyaml>=6.0",
"aiohttp>=3.9.0",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0",
"pytest-asyncio>=0.21",
"ruff>=0.1.0",
]
[project.scripts]
bsee-fetch = "energy_scraper.bsee:main"
sodir-fetch = "energy_scraper.sodir:main"
[tool.setuptools.packages.find]
where = ["src"]
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
Example 3: Workspace-Hub Standard Template
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "workspace-project"
version = "0.1.0"
description = "Standardized project configuration"
readme = "README.md"
requires-python = ">=3.10"
license = {text = "MIT"}
authors = [{name = "Development Team"}]
dependencies = [
"pandas>=2.0.0",
"numpy>=1.24.0",
"pyyaml>=6.0",
"plotly>=5.15.0",
"click>=8.0.0",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0.0",
"pytest-cov>=4.0.0",
"ruff>=0.1.0",
"mypy>=1.4.0",
"deepdiff>=6.0.0",
]
[tool.setuptools]
package-dir = {"" = "src"}
[tool.setuptools.packages.find]
where = ["src"]
[tool.uv]
dev-dependencies = [
"pytest>=7.0.0",
"pytest-cov>=4.0.0",
"ruff>=0.1.0",
]
[tool.pytest.ini_options]
testpaths = []
= [, , , ]
= []
=
=
=
=
= [, , , , , , ]
=
=
= [, , ]
=
=
=
=
=
=
Best Practices
1. Version Constraints
dependencies = [
"pandas>=2.0.0",
"numpy>=1.24,<2.0",
"requests~=2.28",
]
dependencies = [
"pandas==2.1.3",
"numpy",
]
2. Organize Optional Dependencies
[project.optional-dependencies]
dev = ["pytest", "ruff", "mypy"]
docs = ["mkdocs", "mkdocs-material"]
viz = ["plotly", "matplotlib"]
test = ["pytest", "pytest-cov"]
lint = ["ruff", "mypy"]
all = ["my-project[dev,docs,viz]"]
3. Use src Layout
my-project/
├── pyproject.toml
├── src/
│ └── my_project/
│ ├── __init__.py
│ └── core.py
└── tests/
└── test_core.py
4. Keep Tools Consistent
[tool.ruff]
line-length = 88
[tool.black]
line-length = 88
[tool.isort]
line_length = 88
Resources
Use this template for all Python projects in workspace-hub!