- template-python-project
- Development environment
- Dependency management
- Installation
- Testing
- Debugging files and tests files using VSCode
- Documentation
- Packaging and publishing
- Continuous integration
- Miscellaneous
This repository may serve as a template for scientific projects developed in Python using poetry
.
If you have Anaconda
or Miniconda
installed,
-
DISABLE the auto-activation of the base environment
conda config --set auto_activate_base false
-
ALWAYS DEACTIVATE your conda environment before running any of the following commands
conda deactivate
Visual Studio Code (VSCode) is recommended to simplify your coding experience.
The .vscode directory contains a list of suggested extensions together with the corresponding settings. You can place it at the root of your project workspace.
See also the vscode-workflow repository.
poetry
Python Packaging And Dependency Management Made Easy
poetry>=1.2
is recommended for its simplicity to manage Python projects in many ways and make them meet the Python packaging standards.
-
Read WARNING for conda users,
-
Check your
poetry
versionpoetry --version
If you get an error, please check python-poetry/poetry/issues/507
To easily switch between Python versions, it is recommended to use pyenv
or similar tools.
# cd REPOSITORY_NAME pyenv install 3.9.8 pyenv local 3.9.8 # Activate Python 3.9.8 for the current project
See also the Real Python's tutorial "Intro to pyenv
".
A virtual environment is a self-contained directory tree that contains a Python installation for a particular version of Python, plus a number of additional packages.
It is always good practice to work in a virtual environment, isolated from your other Python projects.
With poetry
creating/activating a virtual environment is fairly simple with the poetry shell
command
Please read WARNING for conda users)
# conda deactivate # for conda users
poetry shell # create/activate virtual environment (see poetry.toml)
exit # to exit the virtual environment
Note
In this template project, as defined in the poetry.toml file, the command poetry shell
will create a new/activate the virtual environment named (.venv)
at the root of the project in a .venv
folder
See also poetry
's documentation.
If you don’t want poetry
to manage my virtual environments. Can I disable it?
Prepend poetry run
to your classical commands (e.g. poetry run pytest
) to make sure they are executed in the dedicated virtual environment.
See examples in the following sections
poetry
is recommended for its dependency management capabilities.
poetry
makes use of a single file: the pyproject.toml
file.
Nowadays, since PEP 517, PEP 518, PEP 660, PEP 621, the pyproject.toml
file is used to define and manage your project metadata, build system, dependencies, packaging options, third party packages configurations, etc.
In particular, it replaces the need for , setup.py
, setup.cfg
, requirements.txt
~~pytest.ini~~
files.
On top of installing a given dependency (like pip
would do), poetry
also resolves dependencies' version (like conda
would do, but faster).
The result of the resolution procedure is stored in the poetry.lock
file.
This guarantees full reproducibility of your project setup!
Anyone who sets up the project with
poetry
when the filepoetry.lock
is present uses the exact same versions of the dependencies that you are using.
Use the command poetry add
and check the result in the section [tool.poetry.dependencies]
of the pyproject.toml
file
poetry add PACKAGENAME
# poetry add "PACKAGENAME[EXTRANAME1,EXTRANAME2]"
poetry remove PACKAGENAME
With
poetry
you can organize your dependencies in groups to manage them in a more granular way
To do this, use the command poetry add PACKAGENAME --group GROUPNAME
and check the result in the corresponding section [tool.poetry.group.GROUPNAME.dependencies]
of the pyproject.toml
file.
For example, to add pytest
to the dev
(development) group use
poetry add pytest --group dev
poetry remove pytest --group dev
If you wish to make a group of dependencies optional, add the following to the pyproject.toml
file
[tool.poetry.group.GROUPNAME]
optional = true
# [tool.poetry.group.GROUPNAME.dependencies]
See also install group dependencies.
Single dependecies can also be made optional
poetry add PACKAGENAME1 --optional
poetry add PACKAGENAME2 --optional
and then combined to define package extra dependencies in the pyproject.toml
.
[tool.poetry.extras]
EXTRANAME = ["PACKAGENAME1", "PACKAGENAME2"]
See also Install the package with extra dependencies.
Use the command poetry add
which, to some extend, is similar to pip install
.
By default, Poetry discovers and installs packages from PyPI. This represents most cases and will likely be enough for most users.
If the target package is available from a different source than PyPI, you can configure poetry and add this new source, see the documentation
When the target project is available on PyPI
poetry add PACKAGENAME
# pip install PACKAGENAME
poetry add "PACKAGENAME[EXTRANAME1,EXTRANAME2]"
# pip install "PACKAGENAME[EXTRANAME1,EXTRANAME2]"
poetry add --editable "PACKAGENAME[EXTRANAME1,EXTRANAME2]"
# pip install --editable "PACKAGENAME[EXTRANAME1,EXTRANAME2]"
When the target project is available online
poetry add git+https://github.com/USERNAME/REPOSITORY_NAME.git
# pip install git+https://github.com/USERNAME/REPOSITORY_NAME.git
poetry add --editable git+https://github.com/USERNAME/REPOSITORY_NAME.git
# pip install --editable git+https://github.com/USERNAME/REPOSITORY_NAME.git
When the target project is located in a specific directory or file poetry add --editable ./my-package/
poetry add PATH_TO_PACKAGE
# pip install PATH_TO_PACKAGE
poetry add --editable PATH_TO_PACKAGE
# pip install --editable PATH_TO_PACKAGE
By default, dependencies across all non-optional groups will be installed when executing poetry install
.
By default, the command poetry install
installs the package in editable mode.
git clone https://github.com/USERNAME/REPOSITORY_NAME.git
cd REPOSITORY_NAME
poetry shell # create/activate virtual environment (see poetry.toml)
poetry install # main + non-optional group dependencies
poetry install --without GROUPNAME # main + non-optional - GROUPNAME dependencies
Optional group dependencies, see Define optional groups, can be installed using the --with
, --only
flags
poetry install --with GROUPNAME1 --without GROUPNAME2
poetry install --only GROUPNAME3
Consider using pip>=21.3.1
, when installing packages defined by a pyproject.toml
file.
git clone https://github.com/USERNAME/REPOSITORY_NAME.git
cd REPOSITORY_NAME
# activate your virtual environment # e.g. conda activate ENVIRONMENT_NAME
pip install --editable .
# pip install --editable ".[EXTRANAME1, EXTRANAME2]" # to install extra dependencies
See also the pip install
optional commands.
-
With
poetry
, dependencies defined as extra dependencies in the[tool.poetry.extras]
section of thepyproject.toml
, simply runpoetry install --extras "EXTRANAME1 EXTRANAME2" # poetry install -E EXTRANAME1 -E EXTRANAME2
See also
poetry
's documentation. -
With
pip
, dependencies defined as extra dependencies in the[project.optional-dependencies]
section of thepyproject.toml
, simply runpip install ".[EXTRANAME1, EXTRANAME2]"
See also
pip install
optional commands.
The
pytest
framework makes it easy to write small tests, yet scales to support complex functional testing.
The unit tests of the package are declared in tests/test_*.py
files as test_*
functions with a simple assert
statement.
The configuration of pytest
is defined in the [tool.pytest.ini_options]
section of the pyproject.toml
file.
Run the package test suite with
# poetry shell # create/activate virtual environment (see poetry.toml)
# poetry install --with dev # install main and development dependencies [tool.poetry.group.dev.dependencies]
poetry run pytest
See the Testing section of the VSCode documentation.
The configuration file .vscode/launch.json contains two configurations for debugging
- Python generic files
- Python unit-test files
For more details, see the VSCode documentation
Sphinx is a tool that makes it easy to create intelligent and beautiful documentation.
Sphinx is in charge of building the documentation and generating HTML output, but also PDF, epub, ...
The source files of the documentation are simply .rst
(reStructuredText) or .md
(Markdown) files. However we suggest using the reST markup to keep the same syntax and format as used for writing Python docstings.
Install the documentation dependencies defined under [tool.poetry.group.docs.dependencies]
in pyproject.toml
poetry shell # create/activate virtual environment (see poetry.toml)
poetry install --with docs
# poetry install --only docs
The configuration file is located at docs/conf.py
.
- Edit the metadata of the package documentation defined in
docs/conf.py
, - See also the sphinx documentation
To generate the documentation locally, i.e., on your machine,
# poetry shell # create/activate virtual environment (see poetry.toml)
# poetry install --with docs
poetry run sphinx-build -b html docs docs/_build/html
and navigate the documentation
open docs/_build/html/index.html
Important: Any change made in the source .py
files or the docs/conf.py
file require rebuilding the documentation.
Choose either
- GitHub pages (default), or
- Read the Docs.
The documentation can be built according to the GitHub workflow .github/workflows/docs.yml and deployed from the gh-pages
branch via GitHub pages at https://USERNAME.github.io/template-python-project
.
To make this work automatically, follow the simple steps below (only once!)
-
Push you latest changes
- the
gh-pages
branch will be automatically created/updated once the GitHub workflow .github/workflows/docs.yml is triggered
- the
-
On your GitHub repository
- Go to Settings -> Pages -> Source
- select branch:
gh-pages
- select folder:
/root
- select branch:
- Go to Settings -> Pages -> Source
Read the Docs simplifies software documentation by automating building, versioning, and hosting of your docs for you.
After linking your project with Read the Docs, you can configure Read the Docs to build and deploy the documentation of the package at https://repository-name.readthedocs.io/en/latest/, either automatically or manually.
See also the .readthedocs.yaml
configuration file.
poetry
is also of great help to simplify the packaging process.
Before publication, poetry
can package your project
poetry build
See also PyPA's build
package.
It is good practice to first publish on TestPyPI and check the results before publishing on the official PyPI, see PyPI section.
Let's configure poetry
to publish your package on TestPyPI
poetry config repositories.testpypi https://test.pypi.org/legacy/
poetry config http-basic.testpypi __token__ MY_TOKEN
# poetry build
poetry publish --repository testpypi
-
Check the results https://test.pypi.org/project/packagename/
-
Check your package installation from TestPyPI
# create a new virtual environment and run # conda create -n test-install-testpypi python=3.8 pip # conda activate test-install-testpypi pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ packagename
See also PyPA twine
package.
PyPI is the official Python Package Index
-
poetry config pypi-token.pypi MY_TOKEN # poetry build poetry publish
-
Check the results https://pypi.org/project/packagename/
-
Check your package installation from PyPI
# create a new virtual environment and run # conda create -n test-install-pypi python=3.8 pip # conda activate test-install-pypi pip install packagename
See also PyPA twine
package.
GitHub Actions makes it easy to automate all your software workflows, now with world-class CI/CD. Build, test, and deploy your code right from GitHub. Make code reviews, branch management, and issue triaging work the way you want.
GitHub workflows declared as .github/workflows/*.yml
files.
See the corresponding sections in the
.github/workflows/ci.yml
- See the corresponding section in the
.github/workflows/ci.yml
- codecov
- codecov-action
Consider reading