Как я могу использовать файл требований pip для удаления и установки пакетов?

90

У меня есть файл требований к пипу, который меняется во время разработки.

Можно pipли удалить пакеты, которые не указаны в файле требований, а также установить те, которые появляются? Есть стандартный метод?

Это позволит файлу требований к pip быть каноническим списком пакетов - подход «если и только если».

Обновление : я предложил это как новую функцию на https://github.com/pypa/pip/issues/716

воду
источник
3
Вы ДЕЙСТВИТЕЛЬНО хотите, чтобы pip удалял произвольные пакеты только потому, что они не требуются вашей программе? Звучит немного опасно ...
Скотт Хантер
11
@ScottHunter. Если вы находитесь в виртуальном окружении без пакетов сайта, это разумное решение.
Майкл Миор 01
1
@ScottHunter Да, если я использую управляемую (виртуальную) среду, в которой я хочу быть уверенным в том, что там есть - и в этом нет ничего, что могло бы вызвать проблемы, например, неожиданные зависимости.
wodow
@MichaelMior Если это ответ, пожалуйста, добавьте его в качестве ответа, и я приму его!
wodow
@wodow Готово. Единственная причина, по которой я не опубликовал в качестве ответа, заключается в том, что, вероятно, есть более полезное решение, которое поможет вам добиться того, чего вы хотите.
Майкл Миор 01

Ответы:

16

Короткий ответ - нет, вы не можете сделать это с помощью pip.

Майкл Майор
источник
32
как говорит Стивен ниже:pip uninstall -r requirements.txt
Оммит
31
@Ommit При этом не удаляются пакеты, которые не указаны в файле требований. Он удаляет все пакеты, которые присутствуют в файле.
Майкл Миор,
3
@Micheal Mior, а, я не уделил достаточно внимания исходному вопросу. Виноват.
Оммит 08
4
Добавьте -yв команду @Ommit, чтобы не нажимать Y и вводить много раз. Учитесь на моих ошибках.
Грег Хилстон
1
Просто добавлю: pip uninstall -r requirements.txtудалит только версии из вашего файла requirements.txt. Если вы удалите, boto3==1.10.0например, pip freezeпокажет boto3==1.0.1, устанавливали ли вы его (или любую старую версию) ранее.
Jordan Mackie
125

Это должно удалить все, чего нет в файле requirements.txt:

pip freeze | grep -v -f requirements.txt - | grep -v '^#' | xargs pip uninstall -y

Хотя это не будет работать правильно с пакетами, установленными -e, например, из репозитория git или аналогичного. Чтобы их пропустить, просто отфильтруйте пакеты, начинающиеся с -eфлага:

pip freeze | grep -v -f requirements.txt - | grep -v '^#' | grep -v '^-e ' | xargs pip uninstall -y

Тогда очевидно:

pip install -r requirements.txt

Обновление за 2016 год: вы, вероятно, действительно не хотите использовать описанный выше подход. Проверьте, pip-toolsиpip-sync какой из них выполняет то, что вы, вероятно, хотите сделать, гораздо более надежным способом.

https://github.com/nvie/pip-tools

Обновление за май 2016 г .:

Теперь вы также можете использовать pip uninstall -r requirements.txt, однако это дает в основном обратное - он удаляет все вrequirements.txt

Обновление за май 2019 г .:

Проверьте pipenv . Многое произошло в мире управления пакетами, поэтому вопросы такого рода немного устарели. На самом деле я все еще с удовольствием использую pip-tools.

Стивен Фури
источник
5
Это было бы чудесно. Мне кажется, это хороший способ заставить разработчиков явно указывать свои зависимости, ломая все, если они устанавливают что-то на один хост вручную, не обновляя свой файл requirements.txt. Мне было бы интересно узнать, какую обратную связь генерирует запрос на перенос, добавляющий эту функциональность.
Стивен Фури
Это правильный ответ! Я положил это в мой project.configфайл для Django на Elastic Beanstalk: 05_pip_clean: command: "pip freeze | grep -v -f requirements.txt - | grep -v '^#' | xargs pip uninstall -y". Теперь я могу откатывать пакеты pip без перестройки среды, просто используя комментарии в requirements.txt. Это экономит мне реальное время простоя. Спасибо!
e.thompsy
есть ли когда-нибудь вывод зависания pip, начинающийся с #? Другими словами, нужен ли второй grep?
xor
1
Не уверен, что pip freezeделает комментарии, но когда-нибудь они могут добавить это в API, и если они это сделают, это будет действительным. Если они этого не сделают, то вышеперечисленное не работает. Строка позволяет использовать stdin из предыдущей команды, в этом случае черточка сообщает grep о необходимости сравнить содержимое pip freezepip freeze
файла
1
Я настоятельно рекомендую pip-tools. +1
Рон Ротман
16

Это не особенность pip, нет. Если вам действительно нужна такая вещь, вы можете написать сценарий для сравнения результатов pip freezeс вашим requirements.txt, но это, вероятно, будет больше хлопот, чем оно того стоит.

Используя virtualenv, проще и надежнее просто создать чистую среду и (пере) установить из requirements.txt, например:

deactivate
rm -rf venv/
virtualenv venv/
source venv/bin/activate
pip install -r requirements.txt
dbr
источник
6
Может быть полезно просто удалить пакеты, которых нет в файле требований, если некоторые из пакетов (PIL, lxml и т. Д.) Требуют длительной компиляции - особенно если это происходит на работающем сервере, который использует виртуальную среду.
melinath
@melinath Если их нет в вашем файле требований и они уже установлены, компиляция никогда не должна повториться.
Майкл Миор
1
@MichaelMior - если вы, скажем, не должны были стереть весь virtualenv, как предполагает этот ответ.
melinath
1
@melinath Но если вы удалите virtualenv, а пакет не требуется (и не у вас requirements.txt), зачем его снова устанавливать?
Майкл Миор
3
@MichaelMior Я постараюсь изложить свой первоначальный комментарий более подробно. Похоже, вы неправильно поняли то, о чем я говорил. Представьте себе простой файл требований, содержащий PIL и lxml. Но затем вы решаете, что вам больше не нужен lxml, и удаляете его из файла требований. Если вы сделаете то, что предлагает этот ответ, и удалите virtualenv, вам придется переустановить (и перекомпилировать) PIL. Было бы более эффективно иметь возможность просто удалить lxml (то есть все пакеты, не указанные в файле требований)
melinath
11

Теперь вы можете передать -r requirements.txtаргумент pip uninstall.

pip uninstall -r requirements.txt -y

По крайней мере, с pip8.1.2 pip help uninstallпоказывает:

...
Uninstall Options:
  -r, --requirement <file>    Uninstall all the packages listed in the given requirements file.  This option can be
                              used multiple times.
...
Синто Джозеф
источник
3
При этом не удаляются пакеты, которых нет в файле. Она удаляет пакеты , которые действительно появляются в файле.
Майкл Миор 06
4

Это старый вопрос (но хороший), и с тех пор, как он был задан, все существенно изменилось.

В pip-syncдругом ответе есть косвенная ссылка , но она заслуживает отдельного ответа, потому что она решает именно проблему OP.

pip-sync принимает requirements.txtфайл в качестве входных данных и «настраивает» вашу текущую среду Python так, чтобы она точно соответствовала тому, что в ней requirements.txt. Это включает в себя удаление всех пакетов, которые присутствуют в вашем окружении, но отсутствуют в requirements.txt.

Пример: Предположим , что мы хотим , чтобы наш окр содержать (только) 3 библиотеки: libA, libBи libC, как так:

> cat requirements.txt
libA==1.0
libB==1.1
libC==1.2

Но в настоящее время наш env содержит libCи libD:

> pip freeze
libC==1.2
libD==1.3

Выполнение pip-sync приведет к этому, что было нашим желаемым окончательным состоянием:

> pip-sync requirements.txt
> pip freeze
libA==1.0
libB==1.1
libC==1.2
Рон Ротман
источник
будьте осторожны, если у вас есть глобально установленные pip-tools, они не будут удалены в вашем активированном в данный момент virtualenv ... все еще странно, но в остальном это самый простой инструмент управления требованиями, который я знаю.
benzkji 01
3

Предложение Стивена - хорошая идея, но, к сожалению, она не сработает, если вы включите в свой файл только прямые требования, что мне кажется более понятным.

Все зависимости будут удалены, в том числе даже distribute, сломавшись pipсам.

Поддержание чистого файла требований при отслеживании версий в виртуальной среде

Вот как я пытаюсь отслеживать версии моей виртуальной среды. Я стараюсь поддерживать минимум requirements.txt, включая только прямые требования, и даже не упоминаю об ограничениях версий, где я не уверен.

Но, кроме того, я сохраняю и включаю в отслеживание версий (скажем, git) фактический статус моего virtualenv в venv.pipфайле.

Вот пример рабочего процесса:


настроить рабочее пространство virtualenv с отслеживанием версий:

mkdir /tmp/pip_uninstalling
cd /tmp/pip_uninstalling
virtualenv venv
. venv/bin/activate

инициализировать систему отслеживания версий:

git init
echo venv > .gitignore
pip freeze > venv.pip
git add .gitignore venv.pip
git commit -m "Python project with venv"

установить пакет с зависимостями, включить его в файл требований:

echo flask > requirements.txt
pip install -r requirements.txt
pip freeze > venv.pip

Теперь начните создавать свое приложение, затем выполните фиксацию и начните новую ветку:

vim myapp.py
git commit -am "Simple flask application"
git checkout -b "experiments"

установить дополнительный пакет:

echo flask-script >> requirements.txt
pip install -r requirements.txt
pip freeze > venv.pip

... поиграйте с ним, а затем вернитесь к более ранней версии

vim manage.py
git commit -am "Playing with flask-script"
git checkout master

Теперь удалите посторонние пакеты:

pip freeze | grep -v -f venv.pip | xargs pip uninstall -y

Полагаю, этот процесс можно автоматизировать с помощью git-хуков, но не будем отходить от темы.

Конечно, тогда имеет смысл использовать какую-то систему кеширования пакетов или локальный репозиторий, например pip2pi.

Каменистая дорога
источник
2

Копирование @ stephen-j-fuhry вот эквивалент PowerShell, который я использую:

pip freeze | ? { $_ -notmatch ((gc req.txt) -join "|") }
яичное масло
источник
0

Хотя это не дает прямого ответа на вопрос, лучшей альтернативой requirements.txtсейчас является использование Pipfile. Это работает аналогично Ruby Gemfile. В настоящее время вам необходимо использовать этот pipenvинструмент, но, надеюсь, в конечном итоге он будет включен в pip. Это дает pipenv cleanкоманду, которая делает то, что вы хотите.

(Обратите внимание, что вы можете импортировать существующий requirements.txtс помощью pipenv install -r requirements.txt. После этого у вас должен быть значок, Pipfileи его requirements.txtможно удалить.)

Майкл Майор
источник
-3

Теперь можно использовать:

pip uninstall -r requirements.txt
Роберто Нуньес
источник
2
При этом не удаляются пакеты, которых нет в файле требований. Она удаляет все пакеты , которые действительно появляются в файле.
Майкл Миор,