A typical directory tree of a python project might look like this.
.
├── src
│ ├── __init__.py
│ ├── main.py
│ ├── module1
│ │ ├── __init__.py
│ │ └── foo.py
│ └── module2
│ ├── __init__.py
│ └── bar.py
├── setup.py
└── venv
└── ...
setup.py
contains package metadata like name, version, description, etc.
In some cases, it is useful to have these values inside the application code. For example with FastAPI, you can provide them to the constructor of the API object so that they are shown in the auto-generated docs. Or with Click, you can add a version option.
To avoid duplication, these values should be defined only once and used in both places. However, I have never found a good way, to share these values between setup.py
and application code.
Importing one from the other does not seem to work, because they are not part of the same package structure.
What is best practice in this case?
In the code (run-time code, not setup.py
) use importlib.metadata
(or its back-port importlib-metadata
). The only thing you need to duplicate is the name of the project (the name of the "distribution package").
For example with a project named MyLibrary
:
import importlib.metadata
PROJECT_NAME = 'MyLibrary'
_DISTRIBUTION_METADATA = importlib.metadata.metadata(PROJECT_NAME)
SUMMARY = _DISTRIBUTION_METADATA['Summary']
VERSION = _DISTRIBUTION_METADATA['Version']
Aside: If it is not possible to hard-code the name of the distribution package, there are ways to find it: https://stackoverflow.com/a/63849982