Come posso utilizzare un file dei requisiti pip per disinstallare e installare i pacchetti?


93

Ho un file dei requisiti pip che cambia durante lo sviluppo.

Può pipessere fatto per disinstallare i pacchetti che non compaiono nel file dei requisiti e installare quelli che compaiono? Esiste un metodo standard?

Ciò consentirebbe al file dei requisiti pip di essere l'elenco canonico dei pacchetti - un approccio "se e solo se".

Aggiornamento : l'ho suggerito come nuova funzionalità su https://github.com/pypa/pip/issues/716


3
Vuoi VERAMENTE che pip disinstalli pacchetti arbitrari solo perché il tuo programma non li richiede? Sembra solo un po 'pericoloso ...
Scott Hunter

11
@ScottHunter Se ti trovi in ​​un virtualenv senza pacchetti del sito, è una cosa ragionevole da fare.
Michael Mior

1
@ScottHunter Sì se si utilizza un ambiente (virtuale) controllato in cui voglio essere certo di ciò che è presente - e non è presente nient'altro che possa causare problemi, ad esempio dipendenze impreviste.
wodow

@MichaelMior Se questa è la risposta, aggiungila come risposta e la accetterò!
wodow

@wodow Fatto. L'unico motivo per cui non ho pubblicato come risposta è perché probabilmente c'è una soluzione più utile che può portarti a ciò che desideri.
Michael Mior

Risposte:


17

La risposta breve è no, non puoi farlo con pip.


33
come dice Stephen di seguito:pip uninstall -r requirements.txt
Ommit il

32
@Ommit Questo non disinstalla i pacchetti che non appaiono nel file dei requisiti. Disinstalla tutti i pacchetti che appaiono nel file.
Michael Mior

3
@Micheal Mior, ah, non ho prestato abbastanza attenzione alla domanda originale. Colpa mia.
Ommit

5
Aggiungi un -yal comando @Ommit per evitare di dover premere Y e inserire molte volte. Impara dai miei errori.
Greg Hilston

2
Solo per aggiungere: pip uninstall -r requirements.txtdisinstallerà solo le versioni nel tuo requirements.txt. Se disinstalli, boto3==1.10.0ad esempio, pip freezeverrà mostrato boto3==1.0.1se lo hai installato (o qualsiasi versione precedente) in precedenza.
Jordan Mackie

126

Questo dovrebbe disinstallare tutto ciò che non è in requirements.txt:

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

Anche se questo non funzionerà perfettamente con i pacchetti installati con -e, cioè da un repository git o simili. Per ignorarli, filtra i pacchetti che iniziano con il -eflag:

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

Quindi, ovviamente:

pip install -r requirements.txt

Aggiornamento per il 2016: probabilmente non vuoi davvero utilizzare l'approccio di cui sopra, però. Controlla pip-toolsepip-sync quali realizzano ciò che probabilmente stai cercando di fare in un modo molto più robusto.

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

Aggiornamento per maggio 2016:

Ora puoi anche usarlo pip uninstall -r requirements.txt, tuttavia questo esegue sostanzialmente l'opposto: disinstalla tutto inrequirements.txt

Aggiornamento per maggio 2019:

Dai un'occhiata a pipenv . Sono successe molte cose nel mondo della gestione dei pacchetti che rendono questo tipo di domanda un po 'obsoleto. In realtà sto ancora abbastanza felicemente usando pip-tools, però.


5
Sarebbe carino. Mi sembra un buon modo per forzare gli sviluppatori ad essere espliciti sulle loro dipendenze rompendo tutto se installano qualcosa su un host manualmente senza aggiornare i loro requisiti.txt. Sarei interessato a vedere che tipo di feedback genererebbe una richiesta pull che aggiunge quella funzionalità.
Stephen Fuhry

Questa è la risposta corretta! Ho messo questo nel mio project.configprogramma per Django su Elastic Beanstalk: 05_pip_clean: command: "pip freeze | grep -v -f requirements.txt - | grep -v '^#' | xargs pip uninstall -y". Ora posso eseguire il rollback dei pacchetti pip senza ricostruire il mio ambiente semplicemente usando i commenti in requirements.txt. Questo mi fa risparmiare tempo di inattività. Grazie!
e.thompsy

c'è mai un output di pip freeze che inizia con #? In altre parole, è necessario il secondo grep?
xor

1
Non sono sicuro se pip freezefa commenti, ma un giorno potrebbero aggiungerlo all'API e, se lo fanno, sarà valido. Se non lo fanno, allora quanto sopra è un no-op. Il trattino ti consente di usare lo stdin del comando precedente, in questo caso il trattino dice a grep di confrontare il contenuto di requirements.txt con l'output di pip freeze(l'output di pip freezein questo contesto è sinonimo di stdin)
Stephen Fuhry

1
Consiglio vivamente pip-tools. +1
ron rothman

16

Non è una caratteristica di pip, no. Se vuoi davvero una cosa del genere, potresti scrivere uno script per confrontare l'output di pip freezecon il tuo requirements.txt, ma probabilmente sarebbe più complicato di quanto valga.

Utilizzando virtualenv, è più facile e più affidabile creare un ambiente pulito e (re) installare da requirements.txt, come:

deactivate
rm -rf venv/
virtualenv venv/
source venv/bin/activate
pip install -r requirements.txt

6
Potrebbe essere utile disinstallare semplicemente i pacchetti che non sono nel file dei requisiti se alcuni dei pacchetti (PIL, lxml, ecc.) Richiedono una lunga compilazione, specialmente se questo avviene su un server live che utilizza l'ambiente virtuale.
melinath

@melinath Se non sono nel file dei requisiti e sono già installati, la compilazione non dovrebbe mai ripetersi.
Michael Mior

1
@MichaelMior - a meno che tu non debba, ad esempio, cancellare l'intero virtualenv, come suggerisce questa risposta.
melinath

1
@melinath Ma se cancelli il virtualenv e il pacchetto non è richiesto (e non nel tuo requirements.txt), perché dovrebbe essere installato di nuovo?
Michael Mior

3
@MichaelMior proverò ad affermare il mio commento originale in modo più esplicito. Sembra che tu abbia frainteso il punto che stavo dicendo. Immagina un semplice file di requisiti che contenga PIL e lxml. Ma poi decidi di non aver più bisogno di lxml e lo rimuovi dal file dei requisiti. Se fai come suggerisce questa risposta e cancella il virtualenv, devi reinstallare (e ricompilare) PIL. Sarebbe più efficiente avere la possibilità di disinstallare semplicemente lxml (cioè tutti i pacchetti non nel file dei requisiti.)
melinath

11

Ora puoi passare l' -r requirements.txtargomento a pip uninstall.

pip uninstall -r requirements.txt -y

Almeno a partire dal 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.
...

3
Questo non disinstalla i pacchetti che non compaiono nel file. Si disinstalla i pacchetti che non appaiono nel file.
Michael Mior

4

Questa è una vecchia domanda (ma buona) e le cose sono cambiate sostanzialmente da quando è stata posta.

C'è un riferimento casuale a pip-syncun'altra risposta, ma merita la sua risposta, perché risolve precisamente il problema dell'OP.

pip-sync accetta un requirements.txtfile come input e "allinea" il tuo ambiente Python corrente in modo che corrisponda esattamente a ciò che contiene requirements.txt. Ciò include la rimozione di tutti i pacchetti presenti nell'env ma assenti da requirements.txt.

Esempio: Supponiamo che vogliamo che il nostro ENV per contenere (solo) 3 librerie: libA, libB, e libC, in questo modo:

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

Ma il nostro env attualmente contiene libCe libD:

> pip freeze
libC==1.2
libD==1.3

L'esecuzione di pip-sync risulterà in questo, che era il nostro stato finale desiderato:

> pip-sync requirements.txt
> pip freeze
libA==1.0
libB==1.1
libC==1.2

attenzione, se si dispone di un pip-tools installato a livello globale, non verrà disinstallato nel virtualenv attualmente attivato ... ancora strano, ma per il resto lo strumento di gestione dei requisiti più semplice che conosco.
benzkji

3

La proposta di Stephen è una bella idea, ma sfortunatamente non funziona se includi solo requisiti diretti nel tuo file, il che mi sembra più pulito.

Tutte le dipendenze verranno disinstallate, incluso anche distribute, scomponendosi pip.

Mantenere un file dei requisiti pulito durante il monitoraggio della versione in un ambiente virtuale

Ecco come cerco di monitorare la versione del mio ambiente virtuale. Cerco di mantenere un minimo requirements.txt, includendo solo i requisiti diretti, e senza nemmeno menzionare i vincoli di versione in cui non sono sicuro.

Ma inoltre, mantengo e includo nel monitoraggio della versione (ad esempio git), lo stato effettivo del mio virtualenv in un file venv.pip file.

Ecco un esempio di flusso di lavoro:


configurare lo spazio di lavoro virtualenv, con monitoraggio della versione:

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

inizializza il sistema di tracciamento della versione:

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

installa un pacchetto con dipendenze, includilo nel file dei requisiti:

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

Ora inizia a creare la tua app, quindi esegui il commit e avvia un nuovo ramo:

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

installa un pacchetto aggiuntivo:

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

... giocaci e poi torna alla versione precedente

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

Ora disinstalla i pacchetti estranei:

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

Suppongo che il processo possa essere automatizzato con git hook, ma non andiamo fuori tema.

Naturalmente, ha senso quindi utilizzare un sistema di cache dei pacchetti o un repository locale come pip2pi


2

Piggybacking off @ stephen-j-fuhry ecco un equivalente di PowerShell che uso:

pip freeze | ? { $_ -notmatch ((gc req.txt) -join "|") }

0

Anche se questo non risponde direttamente alla domanda, un'alternativa migliore a requirements.txtadesso è usare un file Pipfile. Funziona in modo simile a un Ruby Gemfile. Attualmente, è necessario utilizzare lo pipenvstrumento, ma si spera che questo venga eventualmente incorporato in pip. Questo fornisce il pipenv cleancomando che fa quello che vuoi.

(Nota che puoi importare un esistente requirements.txtcon pipenv install -r requirements.txt. Dopo questo dovresti avere un Pipfilee il requirements.txtpuò essere rimosso.)


-3

È ora possibile utilizzare:

pip uninstall -r requirements.txt

2
Questo non disinstalla i pacchetti che non appaiono nel file dei requisiti. Disinstalla tutti i pacchetti che lo fanno appaiono nel file.
Michael Mior
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.