============
Cookbook
============

.. _`Requirements Files`:

Requirements Files
******************

A key idea in pip is that package versions listed in requirement files (or as :ref:`pip install` arguments),
have precedence over those that are located during the normal dependency resolution process that uses "install_requires" metadata.

This allows users to be in control of specifying an environment of packages that are known to work together.

Instead of running something like ``pip install MyApp`` and getting whatever libraries come along,
you'd run ``pip install -r requirements.txt`` where "requirements.txt" contains something like::

    MyApp
    Framework==0.9.4
    Library>=0.2

Regardless of what MyApp lists in ``setup.py``, you'll get a specific version
of Framework (0.9.4) and at least the 0.2 version of
Library.  Additionally, you can add optional libraries and support tools that MyApp doesn't strictly
require, giving people a set of recommended libraries.

Requirement files are intended to exhaust an environment and to be *flat*.
Maybe ``MyApp`` requires ``Framework``, and ``Framework`` requires ``Library``.
It is encouraged to still list all these in a single requirement file.
It is the nature of Python programs that there are implicit bindings *directly*
between MyApp and Library.  For instance, Framework might expose one
of Library's objects, and so if Library is updated it might directly
break MyApp.  If that happens you can update the requirements file to
force an earlier version of Library, and you can do that without
having to re-release MyApp at all.

To create a new requirements file from a known working environment, use::

    $ pip freeze > stable-req.txt

This will write a listing of *all* installed libraries to ``stable-req.txt``
with exact versions for every library.

For more information, see:

* :ref:`Requirements File Format`
* :ref:`pip freeze`


.. _`Downloading Archives`:

Downloading archives
********************

pip allows you to *just* download the source archives for your requirements, without installing anything and without regard to what's already installed.

::

$ pip install --download <DIR> -r requirements.txt

or, for a specific package::

$ pip install --download <DIR> SomePackage


Unpacking archives
******************

pip allows you to *just* unpack archives to a build directory without installing them to site-packages.  This can be useful to troubleshoot install errors or to inspect what is being installed.

::

$ pip install --no-install SomePackage

If you're in a virtualenv, the build dir is ``<virtualenv path>/build``.  Otherwise, it's ``<OS temp dir>/pip-build-<username>``

Afterwards, to finish the job of installing unpacked archives, run::

$ pip install --no-download SomePackage



.. _`Fast & Local Installs`:

Fast & Local Installs
*********************

Often, you will want a fast install from local archives, without probing PyPI.

First, :ref:`download the archives <Downloading Archives>` that fulfill your requirements::

$ pip install --download <DIR> -r requirements.txt

Then, install using  :ref:`--find-links <--find-links>` and :ref:`--no-index <--no-index>`::

$ pip install --no-index --find-links=[file://]<DIR> -r requirements.txt



"Non-recursive" upgrades
************************

``pip install ---upgrade`` is currently written to perform a "recursive upgrade".

E.g. supposing:

* `SomePackage-1.0` requires `AnotherPackage>=1.0`
* `SomePackage-2.0` requires `AnotherPackage>=1.0` and `OneMorePoject==1.0`
* `SomePackage-1.0` and `AnotherPackage-1.0` are currently installed
* `SomePackage-2.0` and `AnotherPackage-2.0` are the latest versions available on PyPI.

Running ``pip install ---upgrade SomePackage`` would upgrade `SomePackage` *and* `AnotherPackage`
despite `AnotherPackage` already being satisifed.

If you would like to perform a "non-recursive upgrade" perform these 2 steps::

  pip install --upgrade --no-deps SomePackage
  pip install SomePackage

The first line will upgrade `SomePackage`, but not dependencies like `AnotherPackage`.  The 2nd line will fill in new dependencies like `OneMorePackage`.


Ensuring Repeatability
**********************

Three things are required to fully guarantee a repeatable installation using requirements files.

1. The requirements file was generated by ``pip freeze`` or you're sure it only contains requirements that specify a specific version.
2. The installation is performed using :ref:`--no-deps <install_--no-deps>`.  This guarantees that only what is explicitly listed in the requirements file is installed.
3. The installation is performed against an index or find-links location that is guaranteed to *not* allow archives to be changed and updated without a version increase.

