Skip to content

Commit 94324bc

Browse files
committed
Add dependency section to guide
1 parent 0f33652 commit 94324bc

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Python package dependency declaration
2+
3+
## How to declare documentation, test and other deps
4+
5+
It is currently recommended that you store all dependency information in a **pyproject.toml** file.
6+
This ensures that all of the metadata associated with your package is declared in a single place, making it simpler for users and contributors to understand your package infrastructure.
7+
8+
Dependencies for building your documentation, running your tests and building your package's distribution files can be stored in a `[optional.dependencies]` table within the **pyproject.toml** file.
9+
10+
```{admonition} What happened to the requirements.txt file for dependencies?
11+
:class: note
12+
13+
The requirements.txt file used to be the default way to store dependencies. However in recent years, the ecosystem has moved to storing all of this information in a single **pyproject.toml** file.
14+
```
15+
16+
To declare dependencies in your **pyproject.toml** file:
17+
18+
1. Add a [optional.dependencies] table to your **pyproject.toml** file.
19+
2. Create named groups of dependencies using the syntax:
20+
21+
`group-name = ["dep1", "dep2"]`
22+
23+
```{tip}
24+
25+
If you have dependencies that need to be installed
26+
directly from github using a `git+https` installation
27+
approach then you may still need to use a requirements.txt or a conda environment file for your dependency installs.
28+
29+
```
30+
31+
Below we've created 3 sets of optional dependencies named: tests, docs and lint:
32+
33+
```toml
34+
[project.optional-dependencies]
35+
tests = [
36+
"pytest",
37+
"pytest-cov"
38+
]
39+
docs = ["sphinx", "pydata_sphinx_theme"]
40+
lint = [
41+
"black",
42+
"flake8"
43+
]
44+
45+
```
46+
47+
[Learn more: View PyPA's overview of declaring optional dependencies](https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#dependencies-optional-dependencies)
48+
49+
## How to install dependencies from your pyproject.toml
50+
51+
You can then install the dependencies via individual groups using:
52+
53+
`pip install yourPackage.[docs]`
54+
55+
or you could install just the dependencies for your tests using:
56+
57+
`pip install yourPackage.[tests]`
58+
59+
You can install all dependencies in the `[optional.dependencies]` table using:
60+
61+
`yourPackage.[all]`
62+
63+
```{admonition} For zsh shell users
64+
:class: tip
65+
66+
Some versions of shell don't support the square bracket syntax. In those cases you will need to add
67+
quotes to your install call like this:
68+
69+
`pip install 'yourPackage.[tests]'`
70+
71+
```
72+
73+
### Combining sets of dependencies
74+
75+
Above we reviewed how to install dependencies from your pyproject toml. In some cases you may want to group sets of dependencies like so:
76+
77+
```toml
78+
[project.optional-dependencies]
79+
tests = ["pytest", "pytest-cov"]
80+
docs = ["sphinx", "pydata_sphinx_theme"]
81+
dev = [
82+
"packageName[tests, docs]",
83+
"build",
84+
"twine"
85+
]
86+
```
87+
88+
You can also install subsets of dependencies like this:
89+
90+
`pip install .[tests, docs]`
91+
92+
```{tip}
93+
When you install dependencies using the above syntax:
94+
95+
`pip install .[tests, docs]`
96+
97+
pip will also install both your package and its core dependencies.
98+
```
99+
100+
## Where does conda fit in ?
101+
102+
The above workflow assumes that you want to publish your package on PyPI. And then you plan to publish to conda-forge (optionally), [by submitting a recipe using greyskull](https://www.pyopensci.org/python-package-guide/package-structure-code/publish-python-package-pypi-conda.html).
103+
104+
If you want to support conda users, you may want to also maintain a conda environment that they can use to install your package. Maintaning a conda environment will also help you test that your package installs as you expect into a conda environment.
105+
106+
## Read the Docs & Python Environments
107+
108+
TODO: we will link to this config section from the RTD page as well...
109+
110+
If you are using readthedocs to build your documentation, then you may need to install your dependencies using a **readthedocs.yaml** file.
111+
112+
Below is an example of installing the **docs** section of your dependency table in the pyproject.toml file within a readthedocs.yaml file.
113+
114+
```yaml
115+
python:
116+
install:
117+
- method: pip
118+
path: .
119+
extra_requirements:
120+
- docs # you can add any of the subgroups of dependencies from your pyproject.toml file to this list.
121+
```
122+
123+
```{tip}
124+
125+
[Learn more about creating a readthedocs.yaml file here. ](https://docs.readthedocs.io/en/stable/config-file/index.html)
126+
```
127+
128+
## If you are using a front-end build tool like PDM, Hatch or Poetry
129+
130+
The above should work if you are using a vanilla packaging approach with a tool such as the [PyPA build tool](https://pypa-build.readthedocs.io/en/stable/) and any back-end that works with `build`.
131+
132+
If you are using another front-end build tool such as PDM, Hatch or Poetry to manage dependencies, then your approach to installing dependencies may be different. Each tool has its own, slightly different way of declaring dependencies in the **pyproject.toml** file. You can learn more about [configuing RTD for tools such as Poetry and PDM here.](https://docs.readthedocs.io/en/stable/build-customization.html#install-dependencies-with-poetry)
133+
134+
```{admonition} A note for conda users
135+
:class: tip
136+
137+
If you use a conda environment for developing your tool, keep in mind that when you install your package using `pip install -e .` (or using pip in general), dependencies will be installed from PyPI rather than conda.
138+
139+
Thus, if you are running a conda environment, installing your package in editable mode risks dependency conflicts. This is particularly important if you have a spatial package that required GDAL or has a GDAL supported dependency.
140+
141+
Alternatively, you can install your package using `pip install -e . --no-deps` to only install the package. And install the rest of your depenedncies using a conda environment file.
142+
```

0 commit comments

Comments
 (0)