Jak mogę używać pliku wymagań pip do odinstalowywania i instalowania pakietów?

90

Mam plik wymagań pip, który zmienia się podczas programowania.

Można pipgo odinstalować pakiety, które nie pojawiają się w pliku wymagań, a także zainstalować te, które się pojawiają? Czy istnieje standardowa metoda?

Dzięki temu plik wymagań pip stałby się kanoniczną listą pakietów - podejście „wtedy i tylko wtedy”.

Aktualizacja : zasugerowałem to jako nową funkcję na https://github.com/pypa/pip/issues/716

wodow
źródło
3
Czy NAPRAWDĘ chcesz, aby pip odinstalował dowolne pakiety tylko dlatego, że Twój program ich nie wymaga? Brzmi trochę niebezpiecznie ...
Scott Hunter
11
@ScottHunter Jeśli jesteś w virtualenv bez pakietów witryn, rozsądnie jest chcieć to zrobić.
Michael Mior
1
@ScottHunter Tak, jeśli używam kontrolowanego (wirtualnego) środowiska, w którym chcę mieć pewność, co tam jest - i nie ma tam nic innego, co mogłoby powodować problemy, np. Nieoczekiwane zależności.
wodow
@MichaelMior Jeśli to jest odpowiedź, dodaj ją jako odpowiedź, a ja ją zaakceptuję!
wodow
@wodow Done. Jedynym powodem, dla którego nie opublikowałem odpowiedzi, jest to, że prawdopodobnie istnieje bardziej pomocne rozwiązanie, które może doprowadzić Cię do tego, czego chcesz.
Michael Mior

Odpowiedzi:

16

Krótka odpowiedź brzmi: nie, nie możesz tego zrobić za pomocą pip.

Michael Mior
źródło
32
jak mówi Stephen poniżej:pip uninstall -r requirements.txt
Ommit
31
@Ommit To nie powoduje odinstalowania pakietów, które nie pojawiają się w pliku wymagań. Odinstalowuje wszystkie pakiety, które pojawiają się w pliku.
Michael Mior
3
@Micheal Mior, ach, nie zwróciłem uwagi na pierwotne pytanie. Mój błąd.
Ommit
4
Dodaj a -ydo polecenia @Ommit, aby uniknąć konieczności naciskania Y i wielokrotnego wprowadzania. Ucz się na moich błędach.
Greg Hilston
1
Wystarczy dodać: pip uninstall -r requirements.txtodinstaluje tylko wersje z twojego Requirements.txt. Jeśli boto3==1.10.0na przykład odinstalujesz , pip freezepokaże, boto3==1.0.1czy zainstalowałeś ją (lub jakąkolwiek starszą wersję) wcześniej.
Jordan Mackie,
125

Powinno to odinstalować wszystko, czego nie ma w Requirements.txt:

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

Chociaż nie będzie to działać poprawnie z pakietami zainstalowanymi z -e, np. Z repozytorium git lub podobnego. Aby je pominąć, po prostu odfiltruj pakiety zaczynające się od -eflagi:

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

Wtedy oczywiście:

pip install -r requirements.txt

Aktualizacja na rok 2016: Prawdopodobnie nie chcesz jednak faktycznie korzystać z powyższego podejścia. Sprawdź, pip-toolsapip-sync które osiągną to, co prawdopodobnie chcesz zrobić, w znacznie bardziej solidny sposób.

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

Aktualizacja na maj 2016 r .:

Możesz teraz również użyć pip uninstall -r requirements.txt, jednak robi to w zasadzie odwrotnie - odinstalowuje wszystko wrequirements.txt

Aktualizacja na maj 2019:

Sprawdź pipenv . W świecie zarządzania pakietami wydarzyło się wiele, co sprawia, że ​​tego rodzaju pytania są nieco przestarzałe. Jednak nadal całkiem szczęśliwie używam pip-tools.

Stephen Fuhry
źródło
5
To byłoby miłe. Wydaje mi się, że dobrym sposobem na wymuszenie na programistach wyraźnego określenia ich zależności przez zerwanie wszystkiego, jeśli zainstalują coś ręcznie na jednym hoście bez aktualizowania ich Requirements.txt. Byłbym zainteresowany, aby zobaczyć, jakiego rodzaju informacje zwrotne wygeneruje żądanie ściągnięcia dodające tę funkcję.
Stephen Fuhry
To jest poprawna odpowiedź! I umieścić w moim project.configpliku dla Django na Elastic Beanstalk: 05_pip_clean: command: "pip freeze | grep -v -f requirements.txt - | grep -v '^#' | xargs pip uninstall -y". Teraz mogę wycofać pakiety pip bez przebudowywania mojego środowiska, używając tylko komentarzy w requirements.txt. Oszczędza mi to prawdziwego przestoju. Dziękuję Ci!
e.thompsy
czy jest kiedykolwiek wyjście zamrożenia pip zaczynające się od #? Innymi słowy, czy potrzebne jest drugie grep?
xor
1
Nie jestem pewien, czy pip freezekomentuje, ale któregoś dnia mogą dodać go do API, a jeśli to zrobią, będzie ważny. Jeśli tego nie zrobią, powyższe jest niemożliwe. Myślnik pozwala na użycie stdin z poprzedniego polecenia, w tym przypadku myślnik mówi grepowi, aby porównał zawartość pip freezepip freeze
Require.txt
1
Bardzo polecam pip-tools. +1
ron rothman
16

To nie jest cecha pip, nie. Jeśli naprawdę chcesz czegoś takiego, możesz napisać skrypt porównujący dane wyjściowe pip freezez twoimi requirements.txt, ale prawdopodobnie byłoby to bardziej kłopotliwe niż warte.

Używając virtualenv, łatwiej i bardziej niezawodnie jest po prostu stworzyć czyste środowisko i (ponownie) zainstalować z requirements.txt, na przykład:

deactivate
rm -rf venv/
virtualenv venv/
source venv/bin/activate
pip install -r requirements.txt
dbr
źródło
6
Przydatne może być po prostu odinstalowanie pakietów, których nie ma w pliku wymagań, jeśli niektóre pakiety (PIL, lxml itp.) Wymagają długiej kompilacji - szczególnie jeśli ma to miejsce na serwerze działającym, który korzysta ze środowiska wirtualnego.
melinath
@melinath Jeśli nie ma ich w Twoim pliku wymagań i są już zainstalowane, kompilacja nie powinna się już więcej powtarzać.
Michael Mior
1
@MichaelMior - chyba że miałbyś, powiedzmy, wyczyścić cały virtualenv, jak sugeruje ta odpowiedź.
melinath
1
@melinath Ale jeśli wyczyścisz virtualenv, a pakiet nie jest wymagany (i nie znajduje się w Twoim requirements.txt), dlaczego miałby kiedykolwiek zostać ponownie zainstalowany?
Michael Mior
3
@MichaelMior Spróbuję wyraźniej określić mój oryginalny komentarz. Wygląda na to, że mogłeś źle zrozumieć, o czym mówiłem. Wyobraź sobie prosty plik wymagań, który zawiera PIL i lxml. Ale wtedy decydujesz, że nie potrzebujesz już lxml i usuwasz go z pliku wymagań. Jeśli zrobisz to, co sugeruje ta odpowiedź i wyczyścisz virtualenv, musisz ponownie zainstalować (i ponownie skompilować) PIL. Bardziej wydajna byłaby możliwość prostego odinstalowania lxml (tj. Wszystkich pakietów, których nie ma w pliku wymagań).
melinath
11

Możesz teraz przekazać -r requirements.txtargument do pip uninstall.

pip uninstall -r requirements.txt -y

Przynajmniej od pip8.1.2 pip help uninstallpokazuje:

...
Uninstall Options:
  -r, --requirement <file>    Uninstall all the packages listed in the given requirements file.  This option can be
                              used multiple times.
...
Shinto Joseph
źródło
3
Nie powoduje to odinstalowania pakietów, które nie pojawiają się w pliku. Odinstalowuje to pakiety, które nie pojawiają się w pliku.
Michael Mior
4

To jest stare pytanie (ale dobre) i od czasu jego zadania wiele się zmieniło.

W pip-syncinnej odpowiedzi jest odręczne odniesienie do , ale zasługuje na własną odpowiedź, ponieważ rozwiązuje dokładnie problem PO.

pip-sync pobiera requirements.txtplik jako dane wejściowe i „poprawia” Twoje bieżące środowisko Pythona, tak aby pasowało dokładnie do tego , co w nim jest requirements.txt. Obejmuje to usunięcie wszystkich pakietów, które są obecne w twoim środowisku env, ale ich nie ma requirements.txt.

Przykład: Załóżmy, że chcemy, aby nasza env zawiera (tylko) 3: biblioteki libA, libBi libC, tak jak poniżej:

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

Ale nasze środowisko zawiera obecnie libCi libD:

> pip freeze
libC==1.2
libD==1.3

Uruchomienie pip-sync spowoduje, że był to nasz pożądany stan końcowy:

> pip-sync requirements.txt
> pip freeze
libA==1.0
libB==1.1
libC==1.2
ron rothman
źródło
uważaj, jeśli masz zainstalowane globalnie pip-tools, nie zostanie ono odinstalowane w aktualnie aktywowanym virtualenv ... nadal dziwne, ale poza tym najprostsze narzędzie do zarządzania wymaganiami, jakie znam.
benzkji
3

Propozycja Stephena to fajny pomysł, ale niestety nie działa, jeśli umieścisz w swoim pliku tylko bezpośrednie wymagania, co dla mnie brzmi czysto.

Wszystkie zależności zostaną odinstalowane, w tym nawet distribute, pipsamoczynnie się zepsuje.

Utrzymywanie czystego pliku wymagań podczas śledzenia wersji środowiska wirtualnego

Oto jak próbuję śledzić wersje mojego wirtualnego środowiska. Staram się zachować minimum requirements.txt, w tym tylko bezpośrednie wymagania, nie wspominając nawet o ograniczeniach wersji, jeśli nie jestem pewien.

Ale poza tym zachowuję i dołączam do śledzenia wersji (powiedzmy git) rzeczywisty stan mojego virtualenv w venv.pippliku.

Oto przykładowy przepływ pracy:


skonfiguruj obszar roboczy virtualenv ze śledzeniem wersji:

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

zainicjalizuj system śledzenia wersji:

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

zainstaluj pakiet z zależnościami, umieść go w pliku wymagań:

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

Teraz zacznij budować swoją aplikację, a następnie zatwierdź i rozpocznij nową gałąź:

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

zainstaluj dodatkowy pakiet:

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

... baw się nim, a potem wróć do wcześniejszej wersji

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

Teraz odinstaluj obce pakiety:

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

Przypuszczam, że proces można zautomatyzować za pomocą haków git, ale nie odchodźmy od tematu.

Oczywiście sensowne jest wtedy użycie jakiegoś systemu buforowania pakietów lub lokalnego repozytorium, takiego jak pip2pi

Wyboista droga
źródło
2

Piggybacking off @ stephen-j-fuhry tutaj jest odpowiednikiem PowerShell, którego używam:

pip freeze | ? { $_ -notmatch ((gc req.txt) -join "|") }
egbutter
źródło
0

Chociaż to nie odpowiada bezpośrednio na pytanie, lepszą alternatywą dla requirements.txtteraz jest użycie Pipfile. Działa podobnie do Rubiego Gemfile. Obecnie musisz skorzystać z tego pipenvnarzędzia, ale miejmy nadzieję, że zostanie ono ostatecznie włączone do pip. Zapewnia to pipenv cleanpolecenie, które robi to, co chcesz.

(Zauważ, że możesz zaimportować istniejący requirements.txtz pipenv install -r requirements.txt. Po tym powinieneś mieć a Pipfilei requirements.txtmożna je usunąć.)

Michael Mior
źródło
-3

Jest to teraz możliwe za pomocą:

pip uninstall -r requirements.txt
Roberto Nunes
źródło
2
Nie powoduje to odinstalowania pakietów, które nie pojawiają się w pliku wymagań. Odinstalowuje to wszystkie pakiety, które nie pojawiają się w pliku.
Michael Mior