Catching up to modern Python packaging.
`pyproject.toml` is the file where you put your package metadata and configuration. This is where all the standard project metadata fields like name, version, and dependencies go. (In the old way, this information normally went in your `setup.py` script which used `setuptools`, or in files that used such as MANIFEST.in, or wherever your tooling of choice told you to put it.)
Other tools, whether they're involved in packaging or not, are allowed to have their own subsection of fields in this file for any project-specific configuration. (In the old way, there was no standard location for anything else - so usually each tool cluttered the top folder in a project with an additional file or directory.)
Besides the project metadata, there is a standard build system section in `pyproject.toml`, which is like your "entry point" into specifying how your project is built and packaged:
PEP-518 (which first introduced `pyproject.toml`) defined a way to tell `pip` and other tools what build dependencies the package has - what packages have to be installed before you can even build this package. (In the old way, keeping track of your build dependencies was entirely unstandardized - often people put them in a `requirements.txt` file along with other dev and test dependencies; and if a user wanted to install from source, `pip` was hard-coded to assume that the build dependencies were just `setuptools` and `wheel`.)
PEP-517 defined a way to tell `pip` and alternative tooling how to start the code that will build the package - similar to how compilers are split, tools like `pip` work like the "front end" that interprets command options and does the stuff that is the same no matter how you build the package, and then calls a build "back end" like `setuptools` which has various features to actually build the package. (In the old way, if a user wanted to install from source, `pip` was basically hard-coded to run the `setup.py` script as the build backend.)
Those two standard options give us the freedom to use whatever build and packaging tooling we want. If those tools need any other configuration, that can go in their own subsection of `pyproject.toml`.
Which brings us to all the build and packaging tool options. There are approximately too many. I've been glancing at the space for a couple years, done searches for what all the options are, poked around at the docs of the popular and new ones - there are several "good enough" choices. Gut feel? pdm.