81

I'm working with fabric(0.9.4)+pip(0.8.2) and I need to install some python modules for multiple servers. All servers have old version of setuptools (0.6c8) which needs to be upgraded for pymongo module. Pymongo requires setuptools>=0.6c9.

My problem is that pip starts installation with pymongo instead of setuptools which causes pip to stop. Shuffling module order in requirements file doesn't seem to help.

requirements.txt:

setuptools>=0.6c9
pymongo==1.9
simplejson==2.1.3

Is there a way to specify install order for pip as it doesn't seem to do it properly by itself?

This can be resolved with two separate requirements files but it would be nice if I didn't need to maintain multiple requirements files now or in the future.

Problem persists with pip 0.8.3.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Seppo Erviälä
  • 7,160
  • 7
  • 35
  • 40
  • As far as i know there is no way to set an order in the requirement file of pip. – mouad Mar 22 '11 at 16:17
  • If you look into the code of pip.py there is a class call `RequirementSet` where it save the requirement, and this class use a dictionary to save the requirements , i think this is way you can't set an order , but i will love to know if i'm wrong :) – mouad Mar 22 '11 at 16:27
  • This was fixed in pip 6.1.0 – see my answer for details. – Piotr Dobrogost Mar 18 '16 at 14:26
  • The answer (still) is *no*. And here is why: https://github.com/pypa/pip/issues/2362 – Ufos Sep 04 '18 at 14:06

10 Answers10

40

You can just use:

cat requirements.txt | xargs pip install
lucasr300
  • 618
  • 1
  • 6
  • 13
  • 10
    This is [Useless Use of Cat (UUoC)](http://porkmail.org/era/unix/award.html). In addition, you must add `-L 1` to ensure that only one line is used.`xargs -L 1 pip install < requirements.txt` – Sebastian Schrader Jul 27 '16 at 22:53
  • 4
    Sometimes there are comments in `requirements.txt` (lines starting with `#` are considered comments by `pip`). In such cases, you might prefer to use: `grep -v '^#' requirements.txt | xargs pip install` – jorgeh Apr 25 '18 at 17:10
23

To allow all types of entries (for example packages from git repositories) in requirements.txt you need to use the following set of commands

cat requirements.txt | xargs -n 1 -L 1 pip install

-n 1 and -L 1 options are necessary to install packages one by one and treat every line in the requirements.txt file as a separate item.

  • How is this supposed to *allow packages from git repositories* yet alone *all types of entries* (one example being `PIL==1.1.7 --allow-external PIL --allow-unverified PIL`)? – Piotr Dobrogost Mar 24 '16 at 21:41
18

This is a silly hack, but might just work. Write a bash script that reads from your requirements file line by line and runs the pip command on it.

#!/bin/bash
for line in $(cat requirements.txt)
do
  pip install $line -E /path/to/virtualenv
done
Dmitry
  • 2,989
  • 2
  • 24
  • 34
rubayeet
  • 9,269
  • 8
  • 46
  • 55
15

Sadly the upgrade suggestion won't work. If you read the other details in https://github.com/pypa/pip/issues/24 you will see why

pip will build all packages first, before attempting to install them. So with a requirements file like the following

numpy==1.7.1
scipy==0.13.2
statsmodels==0.5.0

The build of statsmodels will fail with the following statement

ImportError: statsmodels requires numpy

The workaround given for manually calling pip for each entry in the requirements file (via a shell script) seems to be the only current solution.

Kevin Campbell
  • 629
  • 7
  • 5
  • 3
    With addition of topological sort to pip ([Issue #2478: Topological installation order](https://github.com/pypa/pip/pull/2616)) that's no longer the case – pip installs each package's dependencies first and then the package itself. – Piotr Dobrogost May 22 '16 at 15:08
  • I've still found this to be problematic with pip 21.3 when installing into a venv and a suitable build dependency is already installed on the host. For example, with a fresh venv but a host-installed numpy lurking around, if a `requirements.txt` file specifies `numpy` and something that has a compiled extension (like `transformations`) then `transformations` will be built against the host's numpy headers rather than those installed by `numpy`, resulting in a broken extension if the API versions don't match. Perhaps it's an issue with the way `transformations` is built, I'm not sure. – davidA Jan 10 '22 at 22:58
  • To continue my previous comment: if `transformations` is then force-reinstalled (after `numpy` from `requirements.txt` is installed), then the building of the extension picks up the new numpy's headers and builds with the correct API. To date, I haven't found a way around this except to create multiple `requirements.txt` for staged installations. – davidA Jan 10 '22 at 23:00
7

Pymongo requires setuptools>=0.6c9

How do you know? Requires to build or to install? You don't say what version of Pymongo you were trying to install but looking at setup.py file for current (3.2.2) version there's no specification of neither what Pymongo requires to run setup.py (setup_requires) nor what it requires to install (install_requires). With no such information pip can't ensure specific version of setuptools. If Pymongo requires specific version of setuptools to run its setup.py (as opposed to requiring setuptools to run setup function itself) then the other problem is that until recently there was no way to specify this. Now there's specification – PEP 518 – Specifying Minimum Build System Requirements for Python Projects, which should be shortly implemented in pip – Implement PEP 518 support #3691.

As to order of installation, this was fixed in pip 6.1.0;

From pip install – Installation Order section of pip's documentation:

As of v6.1.0, pip installs dependencies before their dependents, i.e. in "topological order". This is the only commitment pip currently makes related to order.

And later:

Prior to v6.1.0, pip made no commitments about install order.

However, without proper specification of requirements by Pymongo it won't help either.

Piotr Dobrogost
  • 41,292
  • 40
  • 236
  • 366
5

Following on from @lukasrms's solution - I had to do this to get pip to install my requirements one-at-a-time:

cat requirements.txt | xargs -n 1 pip install
Leo
  • 1,539
  • 17
  • 15
  • This works but causes a problem if you have `PIL==1.1.7 --allow-external PIL --allow-unverified PIL` as an entry in requirements.txt – Venkat Kotra Mar 04 '15 at 11:54
5

If you have comments in your requirements file you'll want to use:

grep -v "^#" requirements.txt | xargs pip install
Andy
  • 49,085
  • 60
  • 166
  • 233
Jason V.
  • 406
  • 6
  • 7
1

I ended up running pip inside virtualenv instead of using "pip -E" because with -E pip could still see servers site-packages and that obviously messed up some of the installs.

I also had trouble with servers without virtualenvs. Even if I installed setuptools with separate pip command pymongo would refuse to be installed.

I resolved this by installing setuptools separately with easy_install as this seems to be problem between pip and setuptools.

snippets from fabfile.py:

env.activate = "source %s/bin/activate" % virtualenv_path

_virtualenv("easy_install -U setuptools")
_virtualenv("pip install -r requirements.txt")

def _virtualenv(command)
    if env.virtualenv:
        sudo(env.activate + "&&" + command)
    else:
        sudo(command)

I had these problems with pip 0.8.3 and 0.8.2.

Seppo Erviälä
  • 7,160
  • 7
  • 35
  • 40
0

Sorry, my first answer was wrong, because I had setuptools>=0.6c9.

It seems it is not possible because pymongo's setup.py needs setuptools>=0.6c9, but pip has only downloaded setuptools>=0.6c9, and not installed yet.

Someone discussed about it in the issue I pointed before.

I have my own created an issue some weeks ago about it: Do not run egg_info to each package in requirements list before installing the previous packages.

Sorry for the noisy.


First answer:

Upgrade your pip to 0.8.3 version, it has a bugfix to installation order.

Now if you upgrade everything works :-)

Check the news here: http://www.pip-installer.org/en/0.8.3/news.html

Hugo Lopes Tavares
  • 28,528
  • 5
  • 47
  • 45
0

Here is what worked nicely for me:

for name in "^numpy" "^scipy" "^cython" "^scikit"
do
    grep -r -h $name $requirements_dir | awk '{print($1)}' | xargs pip install
done

With that solution you don't modify the original requirement files, but you attempt to install packages in a correct order in advance.

Dawid
  • 1
  • 1