Wie kann ich eine Pip-Anforderungsdatei verwenden, um Pakete zu deinstallieren und zu installieren?

85

Ich habe eine Pip-Anforderungsdatei, die sich während der Entwicklung ändert.

Kann pipman Pakete deinstallieren , die nicht in der Anforderungsdatei enthalten sind, und diejenigen installieren, die angezeigt werden? Gibt es eine Standardmethode?

Dies würde es der Pip-Anforderungsdatei ermöglichen, die kanonische Liste von Paketen zu sein - ein "wenn und nur wenn" -Ansatz.

Update : Ich habe es als neue Funktion unter https://github.com/pypa/pip/issues/716 vorgeschlagen

Wodow
quelle
3
Möchten Sie WIRKLICH, dass pip beliebige Pakete deinstalliert, nur weil Ihr Programm sie nicht benötigt? Klingt nur ein wenig gefährlich ...
Scott Hunter
10
@ScottHunter Wenn Sie sich in einer virtuellen Umgebung ohne Site-Pakete befinden, ist dies eine vernünftige Sache.
Michael Mior
1
@ScottHunter Ja, wenn Sie eine kontrollierte (virtuelle) Umgebung verwenden, in der ich sicher sein möchte, was vorhanden ist - und dort ist nichts anderes vorhanden, das möglicherweise Probleme verursachen könnte, z. B. unerwartete Abhängigkeiten.
Wodow
@MichaelMior Wenn das die Antwort ist, dann füge sie bitte als Antwort hinzu und ich werde sie akzeptieren!
Wodow
@wodow Fertig. Der einzige Grund, warum ich nicht als Antwort gepostet habe, ist, dass es wahrscheinlich eine hilfreichere Lösung gibt, die Sie zu dem bringt, was Sie wollen.
Michael Mior

Antworten:

16

Die kurze Antwort lautet nein, das kann man mit pip nicht machen.

Michael Mior
quelle
30
wie Stephen unten sagt:pip uninstall -r requirements.txt
Ommit
28
@Ommit Hiermit werden keine Pakete deinstalliert, die nicht in der Anforderungsdatei enthalten sind. Es deinstalliert alle Pakete, die in der Datei erscheinen.
Michael Mior
2
@ Michael Mior, ah, ich habe der ursprünglichen Frage nicht genau genug Aufmerksamkeit geschenkt. Mein Fehler.
Lassen Sie den
4
Fügen -ySie dem Befehl von @Ommit ein hinzu, um zu vermeiden, dass Sie Y drücken und viele Male eingeben müssen. Lerne aus meinen Fehlern.
Greg Hilston
1
Nur zum Hinzufügen: pip uninstall -r requirements.txtDeinstalliert nur die Versionen in Ihrer Anforderung.txt. Wenn Sie beispielsweise deinstallieren boto3==1.10.0, pip freezewird angezeigt, boto3==1.0.1ob Sie es (oder eine ältere Version) zuvor installiert haben.
Jordan Mackie
119

Dies sollte alles deinstallieren, was nicht in der Datei require.txt enthalten ist:

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

Obwohl dies mit Paketen, die mit installiert wurden -e, dh aus einem Git-Repository oder ähnlichem, nicht ganz richtig funktioniert . Um diese zu überspringen, filtern Sie einfach Pakete heraus, die mit dem -eFlag beginnen:

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

Dann natürlich:

pip install -r requirements.txt

Update für 2016: Sie möchten den oben genannten Ansatz jedoch wahrscheinlich nicht wirklich anwenden. Check out pip-toolsundpip-sync das erreichen , was Sie wahrscheinlich in einer viel robusteren Art und Weise zu tun suchen.

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

Update für Mai 2016:

Sie können jetzt auch verwenden pip uninstall -r requirements.txt, dies bewirkt jedoch im Grunde das Gegenteil - es deinstalliert alles inrequirements.txt

Update für Mai 2019:

Schauen Sie sich pipenv an . In der Welt des Paketmanagements ist viel passiert, was diese Art von Frage etwas überflüssig macht. Eigentlich benutze ich Pip-Tools aber immer noch recht gerne.

Stephen Fuhry
quelle
5
Das wäre nett. Scheint mir eine gute Möglichkeit zu sein, Entwickler dazu zu zwingen, ihre Abhängigkeiten explizit anzugeben, indem sie alles kaputt machen, wenn sie etwas manuell auf einem Host installieren, ohne ihre Anforderungen zu aktualisieren. Es würde mich interessieren, welche Art von Feedback eine Pull-Anfrage, die diese Funktionalität hinzufügt, erzeugen würde.
Stephen Fuhry
Das ist die richtige Antwort! Ich habe dies in meine project.configDatei für Django auf Elastic Beanstalk aufgenommen : 05_pip_clean: command: "pip freeze | grep -v -f requirements.txt - | grep -v '^#' | xargs pip uninstall -y". Jetzt kann ich Pip-Pakete zurücksetzen, ohne meine Umgebung neu zu erstellen, indem ich nur Kommentare in verwende requirements.txt. Das erspart mir echte Ausfallzeiten. Danke dir!
e.thompsy
Gibt es jemals eine Ausgabe von Pip Freeze, beginnend mit #? Mit anderen Worten, ist der zweite Grep notwendig?
xor
@xxor Gute Frage! Ich bin mir nicht sicher, ob pip freezejemals ein #am Anfang einer Zeile ausgegeben wird. Ich sehe in der Pip-Quelle nichts Offensichtliches, was darauf hindeutet, dass dies auch der Fall ist ( github.com/pypa/pip/blob/develop/pip/operations/freeze.py ), da die Anforderungsdateispezifikation dies zulässt, und Ich habe Leute gesehen, die es benutzt haben, ich habe es aufgenommen! pip.pypa.io/en/latest/reference/…
Stephen Fuhry
1
Ich habe Pip-Tools sehr empfohlen. +1
Ron Rothman
15

Es ist kein Merkmal von pip, nein. Wenn Sie so etwas wirklich wollen, können Sie ein Skript schreiben, um die Ausgabe pip freezemit Ihrer zu vergleichen requirements.txt, aber es wäre wahrscheinlich mühsamer als es wert ist.

Mit virtualenvist es einfacher und zuverlässiger, einfach eine saubere Umgebung zu erstellen und (neu) zu installieren von requirements.txt:

deactivate
rm -rf venv/
virtualenv venv/
source venv/bin/activate
pip install -r requirements.txt
dbr
quelle
6
Es kann nützlich sein, nur Pakete zu deinstallieren, die nicht in der Anforderungsdatei enthalten sind, wenn einige der Pakete (PIL, lxml usw.) eine lange Kompilierung erfordern - insbesondere, wenn dies auf einem Live-Server erfolgt, der die virtuelle Umgebung verwendet.
Melinath
@melinath Wenn sie nicht in Ihrer Anforderungsdatei enthalten sind und bereits installiert sind, sollte die Kompilierung nie wieder stattfinden müssen.
Michael Mior
1
@MichaelMior - es sei denn, Sie würden beispielsweise die gesamte virtuelle Umgebung löschen, wie diese Antwort nahelegt.
Melinath
1
@melinath Aber wenn Sie die virtuelle Umgebung löschen und das Paket nicht benötigt wird (und nicht in Ihrem requirements.txt), warum sollte es jemals wieder installiert werden?
Michael Mior
3
@ MichaelMior Ich werde versuchen, meinen ursprünglichen Kommentar expliziter anzugeben. Es scheint, als hätten Sie den Punkt, den ich angesprochen habe, falsch verstanden. Stellen Sie sich eine einfache Anforderungsdatei vor, die PIL und lxml enthält. Aber dann entscheiden Sie, dass Sie lxml nicht mehr benötigen, und entfernen es aus der Anforderungsdatei. Wenn Sie wie in dieser Antwort angegeben vorgehen und die virtuelle Umgebung löschen, müssen Sie PIL neu installieren (und neu kompilieren). Es wäre effizienter, die Option zu haben, lxml einfach zu deinstallieren (dh alle Pakete, die nicht in der Anforderungsdatei enthalten sind)
melinath
10

Sie können das -r requirements.txtArgument jetzt an übergeben pip uninstall.

pip uninstall -r requirements.txt -y

Zumindest ab pip8.1.2 pip help uninstallzeigt:

...
Uninstall Options:
  -r, --requirement <file>    Uninstall all the packages listed in the given requirements file.  This option can be
                              used multiple times.
...
Shinto Joseph
quelle
3
Dadurch werden keine Pakete deinstalliert, die nicht in der Datei enthalten sind. Es deinstalliert Pakete , die Sie in der Datei angezeigt.
Michael Mior
4

Dies ist eine alte (aber gute) Frage, und die Dinge haben sich seit ihrer Beantwortung erheblich geändert.

Es gibt einen spontanen Verweis auf eine pip-syncandere Antwort, der jedoch eine eigene Antwort verdient, da er genau das Problem des OP löst.

pip-sync verwendet eine requirements.txtDatei als Eingabe und "korrigiert" Ihre aktuelle Python-Umgebung so, dass sie genau mit dem übereinstimmt , was darin enthalten ist requirements.txt. Dies umfasst das Entfernen von Paketen, die in Ihrer Umgebung vorhanden sind, aber nicht vorhanden sind requirements.txt.

Beispiel: Angenommen , wir unsere env (nur) 3 Bibliotheken enthalten sollen: libA, libB, und libC, etwa so:

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

Aber unsere Umgebung enthält derzeit libCund libD:

> pip freeze
libC==1.2
libD==1.3

Das Ausführen von pip-sync führt dazu, dass dies unser gewünschter Endzustand war:

> pip-sync requirements.txt
> pip freeze
libA==1.0
libB==1.1
libC==1.2
Ron Rothman
quelle
Vorsicht, wenn Sie ein global installiertes Pip-Tool haben, wird es nicht in Ihrer aktuell aktivierten virtuellen Umgebung deinstalliert ... immer noch seltsam, aber ansonsten das einfachste Anforderungsmanagement-Tool, das ich kenne.
Benzkji
3

Stephens Vorschlag ist eine nette Idee, aber leider funktioniert es nicht, wenn Sie nur direkte Anforderungen in Ihre Datei aufnehmen, was für mich sauberer klingt.

Alle Abhängigkeiten werden deinstalliert, auch gerade distribute, und brechen sich pipselbst auf.

Verwalten einer sauberen Anforderungsdatei während der Versionsverfolgung einer virtuellen Umgebung

So versuche ich, meine virtuelle Umgebung zu versionieren. Ich versuche, ein Minimum beizubehalten requirements.txt, einschließlich der direkten Anforderungen, und erwähne nicht einmal Versionsbeschränkungen, bei denen ich mir nicht sicher bin.

Außerdem behalte ich den tatsächlichen Status meiner virtuellen Umgebung in einer venv.pipDatei und beziehe sie in die Versionsverfolgung (z. B. git) ein .

Hier ist ein Beispielworkflow:


Richten Sie den virtuellen Arbeitsbereich mit Versionsverfolgung ein:

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

Versionsverfolgungssystem initialisieren:

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

Installieren Sie ein Paket mit Abhängigkeiten und fügen Sie es in die Anforderungsdatei ein:

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

Beginnen Sie nun mit dem Erstellen Ihrer App, legen Sie fest und starten Sie einen neuen Zweig:

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

Installieren Sie ein zusätzliches Paket:

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

... damit spielen und dann zur früheren Version zurückkehren

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

Deinstallieren Sie nun fremde Pakete:

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

Ich nehme an, der Prozess kann mit Git-Hooks automatisiert werden, aber lassen Sie uns nicht vom Thema abgehen.

Natürlich ist es dann sinnvoll, ein Paket-Caching-System oder ein lokales Repository wie pip2pi zu verwenden

Steinige Straße
quelle
2

Huckepack von @ stephen-j-gefahreny hier ist ein Powershell-Äquivalent, das ich benutze:

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

Während dies die Frage nicht direkt beantwortet, requirements.txtist die Verwendung von a eine bessere Alternative zu jetzt Pipfile. Dies funktioniert ähnlich wie bei einem Ruby Gemfile. Derzeit müssen Sie das pipenvTool verwenden, aber hoffentlich wird dies irgendwann integriert pip. Dies liefert den pipenv cleanBefehl, der macht, was Sie wollen.

(Beachten Sie, dass Sie ein vorhandenes requirements.txtmit importieren können pipenv install -r requirements.txt. Danach sollten Sie ein haben Pipfileund das requirements.txtkann entfernt werden.)

Michael Mior
quelle
-4

Es ist jetzt möglich mit:

pip uninstall -r requirements.txt
Roberto Nunes
quelle
2
Dadurch werden keine Pakete deinstalliert, die nicht in der Anforderungsdatei enthalten sind. Es deinstalliert alle Pakete , die Sie in der Datei angezeigt.
Michael Mior