The requirements.txt file

One standard that emerged from the PIP community is to use a requirements.txt file,which lists all the project dependencies, but also proposes an extended syntax to install editable dependencies. Refer to https://pip.readthedocs.io/en/stable/reference/pip_install/#requirements-file-format.

The following is an example of such a file:

arrow 
python-dateutil
pytz
requests
six
stravalib
units

Using this file has been widely adopted by the community, because it makes it easier to document your dependencies. You can create as many requirements files as you want in a project, and have your users call the pip install -r thefile.txt command to install the packages described in them.

For instance, you could have a dev-requirements.txt file, which contains extra tools for development, and a prod-requirements.txt, which has production-specific things. The format allows inheritance to help you manage requirements files' collections.

But using requirements files adds a new problem. It duplicates some of the information contained in ;thesetup.py file's install_requires section.

To solve this new issue, some developers make a distinction between dependencies defined for their Python libraries and the one defined for their Python applications.

They use install_requires in their library's setup.py file, and the PIP requirement file in their application deployments. In other words, a Python application won't have a setup.py file's install_requires option filled with its dependencies.

But that means the application installation will require a specific installation process, where the dependencies are first installed via the requirements file. It also means that we'd lose the benefits of having requirements files for libraries .

And we've said earlier in the chapter, we do not want to make our life complicated by having two different ways to describe Python projects dependencies, since the distinction between an application and a library can be quite vague.

To avoid duplicating the information in both places, there are some tools in the community, which offer some syncing automation between setup.py and requirements files.

The pip-tools (https://github.com/jazzband/pip-tools) tool is one of them, and it generates a requirements.txt file (or any other filename) via a pip-compile CLI, as follows:

$ pip install pip-tools 
...
$ pip-compile
#
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --output-file requirements.txt setup.py
#
arrow==0.10.0 # via stravalib
python-dateutil==2.6.0 # via arrow
pytz==2017.2 # via stravalib
requests==2.13.0 # via stravalib
six==1.10.0 # via python-dateutil, stravalib
stravalib==0.6.6
units==0.7 # via stravalib

Notice that the generated file contains versions for each package. This is called version pinning and is done by looking at the versions locally installed.

When declaring dependencies, it's good practice to pin all the dependencies before you release your project. That will ensure that you document the versions that were used and tested for the release.

If you don't use pip-tools, PIP has a built-in command called freeze, which you can use to generate a list of all the current versions that are installed in your Python. This is done as follows:

$ pip freeze 

cffi==1.9.1
click==6.6
cryptography==1.7.2
dominate==2.3.1
flake8==3.2.1
Flask==0.11.1
...

The only problem when you pin your dependencies is when another project has the same dependencies, but is pinned with other versions. PIP will complain and fail to meet both the requirements sets and you won't be able to install everything.

The simplest way to fix this issue is to leave the dependencies unpinned in the setup.py file and pinned in the requirements.txt file. That way, PIP can install the latest version for each package, and when you deploy, specifically in stage or production, you can refresh the versions by running the pip install -r requirements.txt command. PIP will then upgrade/downgrade all the dependencies to match the versions, and in case you need to, you can tweak them in the requirements file.

To summarize, defining dependencies should be done in each project's setup.py file, and requirements files can be provided with pinned dependencies as long as you have a reproducible process to generate them from the setup.py file to avoid duplication.

The last mandatory file your projects should have is the MANIFEST.in file.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset