Como posso usar um arquivo de requisitos de pip para desinstalar e instalar pacotes?

93

Eu tenho um arquivo de requisitos de pip que muda durante o desenvolvimento.

Pode pipser feito para desinstalar os pacotes que não aparecem no arquivo de requisitos, bem como instalar aqueles que aparecem? Existe um método padrão?

Isso permitiria que o arquivo de requisitos de pip fosse a lista canônica de pacotes - uma abordagem 'se e somente se'.

Atualização : sugeri como um novo recurso em https://github.com/pypa/pip/issues/716

uau
fonte
3
Você REALMENTE deseja que o pip desinstale pacotes arbitrários só porque seu programa não os exige? Parece um pouco perigoso ...
Scott Hunter
11
@ScottHunter Se você estiver em um virtualenv sem pacotes de sites, é uma coisa razoável a se fazer.
Michael Mior
1
@ScottHunter Sim, se estiver usando um ambiente controlado (virtual) onde desejo ter certeza do que está lá - e não há nada mais presente que possa causar problemas, por exemplo, dependências inesperadas.
wodow 01 de
@MichaelMior Se essa é a resposta, por favor, adicione como uma resposta e eu aceitarei!
wodow 01 de
@wodow Feito. O único motivo pelo qual não postei como uma resposta é porque provavelmente há uma solução mais útil que pode levar você ao que deseja.
Michael Mior

Respostas:

17

A resposta curta é não, você não pode fazer isso com pip.

Michael Mior
fonte
33
como Stephen diz abaixo:pip uninstall -r requirements.txt
Ommit
32
@Ommit Isso não desinstala pacotes que não aparecem no arquivo de requisitos. Ele desinstala todos os pacotes que aparecem no arquivo.
Michael Mior
3
@Micheal Mior, ah, não prestei atenção o suficiente à pergunta original. Foi mal.
Ommit
5
Adicione um -yao comando @Ommit para evitar ter que pressionar Y e inserir muitas vezes. Aprenda com meus erros.
Greg Hilston,
2
Apenas para adicionar: pip uninstall -r requirements.txtirá apenas desinstalar as versões em seu requirements.txt. Se você desinstalar, boto3==1.10.0por exemplo, pip freezeaparecerá boto3==1.0.1se você o instalou (ou qualquer versão anterior) anteriormente.
Jordan Mackie
126

Isso deve desinstalar tudo que não esteja em requirements.txt:

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

Embora isso não funcione muito bem com pacotes instalados com -e, ou seja, de um repositório git ou similar. Para ignorá-los, basta filtrar os pacotes começando com o -esinalizador:

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

Então, obviamente:

pip install -r requirements.txt

Atualização para 2016: no entanto, você provavelmente não quer realmente usar a abordagem acima. Confira pip-toolsepip-sync quais realizam o que você provavelmente está procurando fazer de uma forma muito mais robusta.

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

Atualização de maio de 2016:

Agora você também pode usar pip uninstall -r requirements.txt, no entanto, isso faz basicamente o oposto - desinstala tudo emrequirements.txt

Atualização de maio de 2019:

Confira pipenv . Muita coisa aconteceu no mundo do gerenciamento de pacotes que torna esse tipo de questão um pouco obsoleto. Na verdade, ainda estou muito feliz usando as ferramentas pip.

Stephen Fuhry
fonte
5
Isso seria legal. Parece-me uma boa maneira de forçar os desenvolvedores a serem explícitos sobre suas dependências, quebrando tudo se eles instalarem algo em um host manualmente sem atualizar seus requisitos.txt. Eu estaria interessado em ver que tipo de feedback uma solicitação de pull adicionando essa funcionalidade geraria.
Stephen Fuhry
Essa é a resposta correta! Eu coloquei isso no meu project.configarquivo para o Django no Elastic Beanstalk: 05_pip_clean: command: "pip freeze | grep -v -f requirements.txt - | grep -v '^#' | xargs pip uninstall -y". Agora posso reverter pacotes pip sem reconstruir meu ambiente apenas usando comentários em requirements.txt. Isso está me economizando tempo de inatividade real. Obrigado!
e.thompsy
Existe alguma vez uma saída de pip freeze começando com #? Em outras palavras, o segundo grep é necessário?
xor
1
Não tenho certeza se pip freezefaz comentários, mas algum dia eles podem adicioná-lo à API e, se o fizerem, será válido. Se não o fizerem, então o acima é um ambiente autônomo. O traço permite que você use o stdin do comando anterior, neste caso, o traço diz ao grep para comparar o conteúdo de requirements.txt com a saída de pip freeze(a saída de pip freezeneste contexto é sinônimo de stdin)
Stephen Fuhry
1
Eu altamente recomendado pip-tools. +1
ron rothman
16

Não é uma característica do pip, não. Se você realmente deseja tal coisa, pode escrever um script para comparar a saída pip freezecom a sua requirements.txt, mas provavelmente seria mais trabalhoso do que vale a pena.

Usando virtualenv, é mais fácil e confiável apenas criar um ambiente limpo e (re) instalar requirements.txt, como:

deactivate
rm -rf venv/
virtualenv venv/
source venv/bin/activate
pip install -r requirements.txt
dbr
fonte
6
Pode ser útil desinstalar apenas os pacotes que não estão no arquivo de requisitos se alguns dos pacotes (PIL, lxml, etc) exigirem uma compilação longa - especialmente se isso estiver ocorrendo em um servidor ativo que está usando o ambiente virtual.
melinath
@melinath Se eles não estiverem em seu arquivo de requisitos e já estiverem instalados, a compilação nunca deverá acontecer novamente.
Michael Mior
1
@MichaelMior - a menos que você, digamos, limpe todo o virtualenv, como sugere esta resposta.
melinath
1
@melinath Mas se você limpar o virtualenv e o pacote não for necessário (e não no seu requirements.txt), por que ele seria instalado novamente?
Michael Mior
3
@MichaelMior tentarei declarar meu comentário original mais explicitamente Parece que você entendeu mal o que eu estava defendendo. Imagine um arquivo de requisitos simples que contém PIL e lxml. Mas então você decide que não precisa mais do lxml e o remove do arquivo de requisitos. Se você fizer o que esta resposta sugere e limpar o virtualenv, terá de reinstalar (e recompilar) o PIL. Seria mais eficiente ter a opção de simplesmente desinstalar o lxml (ou seja, todos os pacotes que não estão no arquivo de requisitos.)
melinath
11

Agora você pode passar o -r requirements.txtargumento para pip uninstall.

pip uninstall -r requirements.txt -y

Pelo menos a partir de pip8.1.2, pip help uninstallmostra:

...
Uninstall Options:
  -r, --requirement <file>    Uninstall all the packages listed in the given requirements file.  This option can be
                              used multiple times.
...
Shinto Joseph
fonte
3
Isso não desinstala pacotes que não aparecem no arquivo. Ele desinstala pacotes que não aparecem no arquivo.
Michael Mior
4

Esta é uma pergunta antiga (mas boa), e as coisas mudaram substancialmente desde que foi feita.

Há uma referência improvisada a pip-syncem outra resposta, mas merece sua própria resposta, porque resolve exatamente o problema do OP.

pip-sync pega um requirements.txtarquivo como entrada e "configura" seu ambiente Python atual para que corresponda exatamente ao que está nele requirements.txt. Isso inclui remover todos os pacotes que estão presentes em seu env, mas ausentes dele requirements.txt.

Exemplo: Suponha que queremos que o nosso env para conter (apenas) 3 bibliotecas: libA, libBe libC, assim:

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

Mas nosso env atualmente contém libCe libD:

> pip freeze
libC==1.2
libD==1.3

Executar pip-sync resultará nisso, que era nosso estado final desejado:

> pip-sync requirements.txt
> pip freeze
libA==1.0
libB==1.1
libC==1.2
Ron Rothman
fonte
cuidado, se você tiver pip-tools globalmente instalado, ele não será desinstalado em seu virtualenv ativado atualmente ... ainda estranho, mas de outra forma a ferramenta de gerenciamento de requisitos mais direta que conheço.
benzkji 01 de
3

A proposta de Stephen é uma boa ideia, mas infelizmente não funciona se você incluir apenas requisitos diretos em seu arquivo, o que parece mais claro para mim.

Todas as dependências serão desinstaladas, inclusive até mesmo distribute, quebrando- pipse.

Manter um arquivo de requisitos limpo enquanto rastreia a versão de um ambiente virtual

Aqui está como tento controlar a versão do meu ambiente virtual. Tento manter um mínimo requirements.txt, incluindo apenas os requisitos diretos, e nem mesmo mencionando as restrições de versão onde não tenho certeza.

Além disso, mantenho e incluo no rastreamento de versão (digamos git) o ​​status real do meu virtualenv em um venv.piparquivo.

Aqui está um exemplo de fluxo de trabalho:


configuração do espaço de trabalho virtualenv, com rastreamento de versão:

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

inicializar o sistema de rastreamento de versão:

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

instale um pacote com dependências, inclua-o no arquivo de requisitos:

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

Agora comece a construir seu aplicativo, em seguida, comprometa-se e inicie um novo branch:

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

instale um pacote extra:

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

... brincar com ele e depois voltar para a versão anterior

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

Agora desinstale pacotes estranhos:

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

Suponho que o processo pode ser automatizado com git hooks, mas não vamos sair do tópico.

Claro, faz sentido usar algum sistema de cache de pacote ou repositório local como pip2pi

Estrada rochosa
fonte
2

Aproveitando @ stephen-j-fuhry aqui está um equivalente PowerShell que eu uso:

pip freeze | ? { $_ -notmatch ((gc req.txt) -join "|") }
manteiga de ovo
fonte
0

Embora isso não responda diretamente à pergunta, uma alternativa melhor para requirements.txtagora é usar um Pipfile. Isso funciona de forma semelhante a um Ruby Gemfile. Atualmente, você precisa fazer uso da pipenvferramenta, mas espero que ela seja eventualmente incorporada pip. Isso fornece o pipenv cleancomando que faz o que você deseja.

(Observe que você pode importar um existente requirements.txtcom pipenv install -r requirements.txt. Depois disso, você deve ter um Pipfilee o requirements.txtpode ser removido.)

Michael Mior
fonte
-3

Agora é possível usar:

pip uninstall -r requirements.txt
Roberto Nunes
fonte
2
Isso não desinstala pacotes que não aparecem no arquivo de requisitos. Ele desinstala todos os pacotes que não aparecem no arquivo.
Michael Mior