Use un archivo pyproject.toml para la configuración y metadatos de su paquete#
pyproject.toml takeaways
Existen solo dos tablas que son necesarias para un paquete de Python instalable: [build-system] y [project]. La tabla [project] almacena los metadatos de su paquete.
There are two required fields in the [project] table: name= and version=.
Add metadata to the classifiers section of your
pyproject.tomlfile to make it easier for users to find your project on PyPI.Cuando esté agregando clasificadores a la tabla [project], solo use valores válidos de la página de clasificadores de PyPI. Un valor inválido aquí generará un error cuando construya su paquete o publique en PyPI.
There is no specific order for tables in the
pyproject.tomlfile. However, fields need to be placed within the correct table sections. For examplerequires =always needs to be associated with the [build-system] table.
Aceca del archivo pyproject.toml#
Every modern Python package should include a pyproject.toml file. For pure Python packages, this file replaces the setup.py and/or setup.cfg file to describe project metadata.
If your project isn’t pure Python, you might still require a setup.py file to build the non-Python extensions. However, a pyproject.toml file should still be used to store your project’s metadata.
Tutorial
If you are migrating from a setup.py or setup.cfg file, and want help, check out this tutorial. specify build requirements and metadata is called a pyproject.toml
Aceca del formato .toml#
The pyproject.toml file is written in TOML (Tom’s Obvious, Minimal Language) format. TOML is an easy-to-read structure based on key/value pairs. Each section in the pyproject.toml file contains a [table identifier].
Below that table identifier are key/value pairs that
support configuration for that particular table.
Bajo
[build-system]se espera una tabla en el lenguaje TOML.Within the
build-systemtable,requires =is a key.El valor asociado para
requireses un array que contiene el valor"hatchling".
[build-system]
requires = ["hatchling"]
¿Cómo se usa el pyproject.toml cuando se construye un paquete?#
Cuando publique en PyPI, notará que cada paquete tiene metadatos listados. Echemos un vistazo a xclim, uno de nuestros paquetes de pyOpenSci. Observe que en la página de inicio de PyPI ve algunos metadatos sobre el paquete, incluido Python, información del mantenedor y más. PyPI puede poblar estos metadatos porque fueron definidos utilizando la sintaxis correcta y clasificadores por los mantenedores de Xclim, archivo pyproject.toml. Estos metadatos cuando se construye el paquete xclim, se traducen en un archivo de distribución que permite a PyPI leer los metadatos e imprimirlos en su sitio web.
Cuando agregue la sección de clasificación a su pyproject.toml y se construya su paquete, la herramienta de construcción organiza los metadatos en un formato que PyPI puede entender y representar en la página de inicio de PyPI. Estos clasificadores también permiten a los usuarios ordenar los paquetes por la versión de Python que admiten, categorías y más.#
Beneficios de usar un archivo pyproject.toml#
Incluir los metadatos de su paquete en un formato pyproject.toml separado y legible para humanos también permite a alguien ver los metadatos del proyecto en un repositorio de GitHub.
Setup.py sigue siendo útil para construcciones de paquetes complejas
Usar setup.py para gestionar construcciones de paquetes y metadatos puede causar problemas con el desarrollo de paquetes. En algunos casos donde la construcción de un paquete de Python es compleja, puede ser necesario un archivo setup.py. Si bien esta guía no cubrirá construcciones complejas, proporcionaremos recursos para trabajar con construcciones complejas en el futuro.
Optional vs. required pyproject.toml file fields#
Cuando cree su archivo pyproject.toml, hay numerosos campos de metadatos que puede usar. A continuación, sugerimos campos específicos para comenzar que admiten la publicación en PyPI y que los usuarios encuentren su paquete.
Una descripción general de todos los elementos de metadatos del proyecto se puede encontrar aquí.
Required fields for the [project] table#
As mentioned above, your pyproject.toml file needs to have a name and version field in order to properly build your package:
name: This is the name of your project provided as a stringversion: This is the version of your project. If you are using a SCM tool for versioning (using git tags to determine versions), then the version may be dynamic (more on that below).
Campos opcionales para incluir en la tabla [project]#
Le sugerimos que también agregue las claves de metadatos a continuación, ya queayudarán a los usuarios a encontrar su paquete en PyPI. Estos campos dejarán claro cómo está estructurado su paquete, qué plataformas admite y qué dependencias requiere su paquete.
Description: esta es una descripción corta de una línea de su paquete.
Readme: Un enlace a su archivo README.md se utiliza para la descripción larga. Esta información se publicará en la página de inicio de su paquete en PyPI.
Requires-python (usado por pip): este es un campo que es utilizado por pip. Aquí le dice al instalador si está utilizando Python 2.x o 3.x. La mayoría de los proyectos estarán utilizando 3.x.
License: la licencia que está utilizando
Authors: estos son los autores originales del paquete. A veces los autores son diferentes de los mantenedores. Otras veces pueden ser los mismos.
Maintainers: puede optar por completar esto o no. Puede completar esto utilizando una lista con un subelemento para cada nombre de autor o una cadena de texto conmantenedor, correo electrónico
authors = [
{name = "Some Maintainer", email = "some-email@pyopensci.org"},
]
project.dependencies: The dependency group is optional because not all packages require dependencies. However, if your project has specific dependencies, include this section in your
pyproject.toml. Dependencies declared in the pyproject.toml file will be installed by uv or pip when your project is installed.project.optional-dependencies: Optional or feature dependencies will be installed if someone runs
python -m pip install projectname[feature]. Use this array to declare dependencies that add specific features to your package that are not installed by default when a user runsuv syncorpython -m pip install packagename.dependency-groups: Dependency groups organize packages and tools that a contributor or developer would need to work on your package. These dependencies may include tools for building and running tests, linters, and code formatters. This is an optional but highly suggested way to organize and install dependencies. This section can replace a requirements.txt file. Learn more about adding these to your package in the PyPA guide here.
keywords: Estas son las palabras clave que aparecerán en la página de inicio de su paquete en PyPI. Piense en ellas como palabras que la gente podría usar para buscar su paquete.
classifiers: The classifiers section of your metadata is also important for the landing page of your package in PyPI and for filtering of packages in PyPI. A list of all options for classifiers can be found here. Some of the classifiers that you should consider including
Development Status
Intended Audience
Topic
Programming language
Opcciones avanzadas en el archivo pyproject.toml#
[project.scripts](Puntos de entrada): Los puntos de entrada son opcionales. Si tiene una herramienta de línea de comandos que ejecuta un script específico alojado en su paquete, puede incluir un punto de entrada para llamar a ese script directamente en la línea de comandos (en lugar de en la shell de Python).Here is an example ofa package that has entry point scripts. Notice that there are several core scripts defined in that package that perform sets of tasks. The pyOpenSci is using those scripts to process their metadata.
Use Dynamic Fields If you have fields that are dynamically populated. For example, you may wish to automatically update your package’s version using Git tags (SCM/version control-based versioning). Example: dynamic = [«version»]
Añadir dependencias a su archivo pyproject.toml#
Required dependencies#
A requirements.txt file has been traditionally used to specify dependencies, but modern practice puts these
in the pyproject.toml file. Required dependencies are specified under the [project] section as a list of strings:
[project]
...
...
...
dependencies = [
"dependency-package-name-1",
"dependency-package-name-2",
"pandas",
"xarray",
"geopandas",
"matplotlib"
]
Optional dependencies#
Optional dependencies are specified under the [project.optional-dependencies] section and are intended to give users
options for including additional dependencies with their installation. Optional dependencies are collected together
as a list of strings and assigned to a name:
[project.optional-dependencies]
plot = ["bokeh"]
test = ["pytest", "pytest-cov"]
docs = ["sphinx", "pydata-sphinx-theme"]
Named dependency lists can be invoked by users on installation to include those specific dependencies on installation. Here is an example installing the test and docs dependencies using pip:
python -m pip install examplePy[test,docs]
Other installation tools tend to follow a similar pattern where optional dependencies are concatenated as a list to the package name.
Dependency Groups#
Dependency groups are a way to group package requirements in the pyproject.toml file but exclude them in the
project metadata when it is built. Because it is not included in the project metadadata, users will not be able to
invoke dependency groups when installing from a package index such as PyPI, but they can be accessed by developers
who have all the project data (e.g. through cloning a repository). Optional dependencies are intended for package
consumers and dependency groups are intended for package maintainers and contributors.
To add development dependencies to your build, add a [dependency-groups] array to your pyproject.toml file.
Then specify dependency groups as follows:
[dependency-groups]
test = [
"pytest",
"pytest-cov"
]
lint = [
"black",
"flake8",
"ruff"
]
docs = [
"sphinx",
"pydata-sphinx-theme"
]
One of the capabilities that dependency groups have is the ability to make composition groups.
For example, dev dependency group could be composed of a test dependency group and a lint dependency group:
[dependency-groups]
...
...
...
dev = [
{include-group = "test"},
{include-group = "lint"}
]
To access groups using pip (requires pip 25.1 or higher), you can invoke them during installation like this:
python -m pip install --group dev
Dependencias recursivas
También puede configurar conjuntos de dependencias recursivas. Vea esta publicación en el blog para más información.
Ejemplo de pyproject.toml para construir usando hatchling#
A continuación se muestra un ejemplo de configuración de construcción para un proyecto de Python. Esta configuración de paquete de ejemplo utiliza hatchling para construir los archivos sdist y wheels del paquete.
# pyproject.toml example build setup to use hatchling and hatch_vcs
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "examplePy"
authors = [
{name = "Some Maintainer", email = "some-email@pyopensci.org"},
]
maintainers = [
{name = "All the contributors"},
]
description = "An example Python package used to support Python packaging tutorials"
keywords = ["pyOpenSci", "python packaging"]
readme = "README.md"
license = "BSD-3-Clause"
classifiers = [
# How mature is this project? Common values are
"Development Status :: 4 - Beta",
# Indicate who your project is intended for
"Intended Audience :: Developers",
"Topic :: Software Development :: Build Tools",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
]
dependencies = [
"dependency-package-name-1",
"dependency-package-name-2",
"pandas",
"xarray",
"geopandas",
"matplotlib"
]
[dependency-groups]
test = [
"pytest",
"pytest-cov"
]
lint = [
"black",
"flake8",
"ruff"
]
docs = [
"sphinx",
"pydata-sphinx-theme"
]
dev = [
{include-group = "test"},
{include-group = "lint"}
]
Nótese que las dependencias se especifican en este archivo.
Ejemlo de pyproject.toml para construir usando setuptools#
Los metadatos del paquete, incluidos los autores, palabras clave, etc., también son fáciles de leer. A continuación, puede ver el mismo archivo TOML que utiliza un sistema de construcción diferente (setuptools). ¡Observe lo simple que es cambiar las herramientas necesarias para construir este paquete!
En esta configuración de paquete de ejemplo, usas:
setuptools para construir los archivos sdist y wheels del paquete
setuptools_scm para gestionar las actualizaciones de la versión del paquete utilizando etiquetas de control de versiones
En este ejemplo a continuación [build-system] es la primera tabla de valores. Tiene dos claves que especifican la API del backend de construcción y el paquete que contiene:
requires =build-back-end =
[project]
name = "examplePy"
authors = [
{name = "Some Maintainer", email = "some-email@pyopensci.org"},
]
maintainers = [
{name = "All the contributors"},
]
description = "A setuptools example Python package used to support Python packaging tutorials"
keywords = ["pyOpenSci", "python packaging"]
readme = "README.md"
license = "BSD-3-Clause"
classifiers = [
"Programming Language :: Python :: 3",
"Operating System :: OS Independent",
"Intended Audience :: Science/Research",
]
dependencies = []
dynamic = [
"version",
]
[build-system]
requires = [
"setuptools>=80",
"setuptools-scm",
"wheel",
]
build-backend = "setuptools.build_meta"
[tool.setuptools]
# Allow the package to be used directly from a zip archive.
zip-safe = true
# Do not automatically include non-Python package data in the wheel.
include-package-data = false
[tool.setuptools_scm]
write_to = "src/examplePy/_version.py"
version_scheme = "release-branch-semver"
[project.optional-dependencies]
test = [
"pytest",
"numpy",
"pandas",
"ruff",
]
contrib = [
"pre-commit>=4.1.0",
]