How to Build a pyproject.toml File
Tags: python, pyproject, pypi, tutorial
Published: 2022-09-22 15:21:14

In this tutorial I'll be walking you through how to build a simple `pyproject.toml` file. I'll be including a sample `pyproject.toml` as well as include links to some resources I found very helpful when learning how to construct my own `pyproject.toml`. First, I'll be showing you the full `pyproject.toml` then I'll break down the purpose of each section of the file. `Setuptools` has a [fantastic page](https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html) that explains more about `pyproject.toml` and how it can be used with `setuptools`.


## Sample `pyproject.toml`
```
# tells pip what build tool to use to build your package
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

# tells pip how to build your pypi webpage & what dependencies to install
[project]
name = "sample_pkg"
dynamic = ["readme"]
version = "0.0.30"
authors = [
  { name="Sharon Fitzpatrick", email="sharon.fitzpatrick23@gmail.com" }]
description = "A tool that performs xyz"
dependencies = ["matplotlib",
  "numpy<1.23.0"]
license = { file="LICENSE" }
requires-python = ">=3.8"
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]

# (BETA) tells setuptools you will be using a readme file for the long description field for your pypi profile.
[tool.setuptools.dynamic]
readme = {file = ["README.md"]}

# (OPTIONAL) tells pypi that these urls are where your project's source code and issue tracker reside
[project.urls]
"Homepage" = "https://github.com/pypa/packaging.python.org"
"Bug Tracker" = "https://github.com/pypa/packaging.python.org/issues"
```


## [build-system]
- Tells pip what build tool to use to build your pip package. You can choose build tools like `poetry`,`hatchling`,`setuptools`, etc. to build your package. Without the `build-system` pip would have to guess what tools you used to create your package.
If you want to learn more about the `pyproject.toml` file check [pip's documentation](https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml/)

### `requires = ["setuptools>=61.0"]`

- tells pip exactly what versions of `setuptools` are compatible to build the package

### `build-backend = "setuptools.build_meta"`

- tells pip that you will be using `setuptools` to build your package


## [project]
- This section tells pip the metadata for your package. The metadata for your package is information that describes your package like your package's name, version number, and dependencies.

###  `name = "sample_pkg"`

- Tells pip the name of your package. This must be a unique name on pypi.

###  `dynamic = ["readme"]`
- Tells setuptools that you will be creating the `long description` dynamically from the readme file. The `long description` is what is displayed on your pypi's project page.

### `version = "0.0.30"`
- Tells pip is the current version of the package

### `authors = [{ name="Sharon Fitzpatrick",email="sharon.fitzpatrick23@gmail.com" }]`
- Tells pip is the author of the package
- You must include both the authors name and email for this to work properly

###  `description = "A tool that performs xyz"`
- Tells pip a short description which will be displayed on your package's pypi page.

###  `dependencies = ["matplotlib","numpy<1.23.0"]`
- Tells pip what dependencies your package needs to run
- You can even specify the version of packages that are compatible with your package

###  `license = { file="LICENSE" }`
- Tells pip you will be using the file named LICENSE in your repository as your license

###  `requires-python = ">=3.8"`
- Tells pip what python version your package requires

###  `classifiers = ["Programming Language :: Python :: 3","License :: OSI Approved :: MIT License","Operating System :: OS Independent",]`
- Used by PyPi categorize each package's release, it describes who the package is for and what systems it can run on, and how mature package is. 
- You can find the [full list of classifiers from pypi](https://pypi.org/classifiers/).



## [tool.setuptools.dynamic]
- This section is specific to `setuptools` and still in beta. [Read more here.](https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html#:~:text=%22my_package%22%5D-,Dynamic%20Metadata,-%23)
- It tells `setuptools` that the following fields will be populated dynamically by files included into the repository

###  `readme = {file = ["README.md"]}`

- Tells `setuptools` you will be using a readme file for the long description field for your pypi profile.
- **NOTE:** your README file must be named exactly README. 
- **NOTE:** a GitHub styled `README.md` may not render correctly on `pypi` 


## [project.urls]
- This is an optional section that tells pypi the urls associated  with your package
###  "Homepage" = "https://github.com/pypa/packaging.python.org"
- This tells pypi where your package is from  (optional)
###  "Bug Tracker" = "https://github.com/pypa/packaging.python.org/issues"
-  This tells pypi where issues and bugs for your project are being tracked (optional)

## Ready to upload to PyPi?
Now that you know how to build your `pyproject.toml` file are you ready to upload your package to PyPi? I created a guide to show you how to [upload to PyPi the modern way](https://dev.to/2320sharon/the-modern-way-of-uploading-a-pypi-package-2gpd).