Bagaimana saya bisa menggunakan file persyaratan pip untuk menghapus instalasi serta menginstal paket?

90

Saya memiliki file persyaratan pip yang berubah selama pengembangan.

Dapatkah pipdibuat untuk menghapus paket yang tidak muncul di file persyaratan serta menginstal yang muncul? Apakah ada metode standar?

Ini akan memungkinkan file persyaratan pip menjadi daftar paket kanonik - pendekatan 'jika dan hanya jika'.

Pembaruan : Saya menyarankannya sebagai fitur baru di https://github.com/pypa/pip/issues/716

wodow
sumber
3
Apakah Anda BENAR-BENAR ingin pip menghapus paket sewenang-wenang hanya karena program Anda tidak memerlukannya? Kedengarannya sedikit berbahaya ...
Scott Hunter
11
@ScottHunter Jika Anda berada di virtualenv tanpa paket situs, wajar jika Anda ingin melakukannya.
Michael Mior
1
@ScottHunter Ya jika menggunakan lingkungan terkontrol (virtual) di mana saya ingin memastikan apa yang ada di sana - dan tidak ada hal lain yang mungkin menyebabkan masalah, misalnya ketergantungan yang tidak terduga.
wodow
@MichaelMior Jika itu jawabannya maka tolong tambahkan sebagai jawaban dan saya akan menerimanya!
wodow
@wodow Selesai. Satu-satunya alasan saya tidak memposting sebagai jawaban adalah karena mungkin ada solusi yang lebih bermanfaat yang dapat membawa Anda ke apa yang Anda inginkan.
Michael Mior

Jawaban:

16

Jawaban singkatnya adalah tidak, Anda tidak dapat melakukannya dengan pip.

Michael Mior
sumber
32
seperti yang dikatakan Stephen di bawah ini:pip uninstall -r requirements.txt
Ommit
31
@Ommit Ini tidak menghapus paket yang tidak muncul di file persyaratan. Ini mencopot semua paket yang muncul di file.
Michael Mior
3
@Micheal Mior, ah, saya tidak terlalu memperhatikan pertanyaan asli. Salahku.
Ommit
4
Tambahkan perintah -yke @Ommit untuk menghindari menekan Y dan enter berkali-kali. Belajar dari kesalahan saya.
Greg Hilston
1
Hanya untuk menambahkan: pip uninstall -r requirements.txthanya akan menghapus versi di Requirement.txt Anda. Jika Anda menghapus instalan boto3==1.10.0misalnya, pip freezeakan muncul boto3==1.0.1jika Anda telah menginstalnya (atau versi yang lebih lama) sebelumnya.
Jordan Mackie
125

Ini harus menghapus semua yang tidak ada di dalam Requirement.txt:

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

Meskipun ini tidak akan berfungsi dengan baik dengan paket yang diinstal dengan -e, yaitu dari repositori git atau serupa. Untuk melewati itu, cukup filter paket yang dimulai dengan -ebendera:

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

Maka, jelas:

pip install -r requirements.txt

Pembaruan untuk 2016: Anda mungkin tidak benar-benar ingin menggunakan pendekatan di atas. Lihat pip-toolsdanpip-sync mana yang mencapai apa yang mungkin ingin Anda lakukan dengan cara yang jauh lebih kuat.

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

Pembaruan untuk Mei 2016:

Anda sekarang juga dapat menggunakan pip uninstall -r requirements.txt, namun ini pada dasarnya menghasilkan yang sebaliknya - semua yang ada di dalamnya dicopotrequirements.txt

Pembaruan untuk Mei, 2019:

Lihat pipenv . Banyak hal telah terjadi di dunia manajemen paket yang membuat pertanyaan semacam ini agak usang. Saya sebenarnya masih cukup senang menggunakan pip-tools.

Stephen Fuhry
sumber
5
Itu akan menyenangkan. Bagi saya, sepertinya cara yang baik untuk memaksa dev agar eksplisit tentang dependensi mereka dengan memutus semuanya jika mereka menginstal sesuatu pada satu host secara manual tanpa memperbarui persyaratan.txt mereka. Saya tertarik untuk melihat umpan balik seperti apa yang akan dihasilkan oleh permintaan tarik yang menambahkan fungsionalitas itu.
Stephen Fuhry
Ini jawaban yang benar! Saya menempatkan ini dalam saya project.configfile untuk Django pada elastis Pohon Kacang: 05_pip_clean: command: "pip freeze | grep -v -f requirements.txt - | grep -v '^#' | xargs pip uninstall -y". Sekarang saya dapat mengembalikan paket pip tanpa membangun kembali lingkungan saya hanya dengan menggunakan komentar di requirements.txt. Ini menghemat waktu henti saya yang sebenarnya. Terima kasih!
e.thompsy
apakah pernah ada keluaran dari pembekuan pip yang dimulai dengan #? Dengan kata lain, apakah grep kedua diperlukan?
xor
1
Tidak yakin apakah pip freezemembuat komentar, tetapi suatu hari mereka dapat menambahkannya ke API, dan jika mereka melakukannya, itu akan valid. Jika tidak, maka di atas adalah no-op. Tanda hubung memungkinkan Anda menggunakan stdin dari perintah sebelumnya, dalam hal ini, tanda hubung memberi tahu grep untuk membandingkan konten persyaratan.txt dengan keluaran pip freeze(keluaran pip freezedalam konteks ini sama dengan stdin)
Stephen Fuhry
1
Saya sangat merekomendasikan alat pip. +1
ron rothman
16

Ini bukan fitur dari pip, tidak. Jika Anda benar-benar menginginkan hal seperti itu, Anda dapat menulis skrip untuk membandingkan hasilnya pip freezedengan Anda requirements.txt, tetapi kemungkinan akan lebih merepotkan daripada nilainya.

Menggunakan virtualenv, lebih mudah dan lebih dapat diandalkan untuk hanya membuat lingkungan yang bersih dan menginstal (ulang) requirements.txt, seperti:

deactivate
rm -rf venv/
virtualenv venv/
source venv/bin/activate
pip install -r requirements.txt
dbr
sumber
6
Mungkin berguna untuk menghapus paket yang tidak ada dalam file persyaratan jika beberapa paket (PIL, lxml, dll) memerlukan kompilasi yang panjang - terutama jika ini terjadi di server langsung yang menggunakan lingkungan virtual.
melinath
@melinath Jika mereka tidak ada dalam file persyaratan Anda dan mereka sudah diinstal, maka kompilasi seharusnya tidak perlu terjadi lagi.
Michael Mior
1
@MichaelMior - kecuali jika Anda, katakanlah, menghapus seluruh virtualenv, seperti yang disarankan jawaban ini.
melinath
1
@melinath Tetapi jika Anda menghapus virtualenv dan paket tidak diperlukan (dan bukan di Anda requirements.txt), mengapa itu akan diinstal lagi?
Michael Mior
3
@MichaelMior Saya akan mencoba menyatakan komentar asli saya dengan lebih eksplisit. Sepertinya Anda telah salah memahami maksud yang saya sampaikan. Bayangkan file persyaratan sederhana yang berisi PIL dan lxml. Tetapi kemudian Anda memutuskan bahwa Anda tidak membutuhkan lxml lagi, dan Anda menghapusnya dari file persyaratan. Jika Anda melakukan seperti yang disarankan jawaban ini, dan menghapus virtualenv, Anda harus menginstal ulang (dan mengkompilasi ulang) PIL. Akan lebih efisien jika memiliki opsi untuk menghapus lxml (yaitu semua paket yang tidak ada dalam file persyaratan.)
melinath
11

Sekarang Anda dapat meneruskan -r requirements.txtargumen ke pip uninstall.

pip uninstall -r requirements.txt -y

Setidaknya pada pip8.1.2, pip help uninstallmenunjukkan:

...
Uninstall Options:
  -r, --requirement <file>    Uninstall all the packages listed in the given requirements file.  This option can be
                              used multiple times.
...
Shinto Joseph
sumber
3
Ini tidak menghapus paket yang tidak muncul di file. Ini meng-uninstall paket yang tidak muncul dalam file.
Michael Mior
4

Ini adalah pertanyaan lama (tapi bagus), dan banyak hal telah berubah secara substansial sejak ditanyakan.

Ada rujukan begitu saja pip-syncdi jawaban lain, tetapi layak mendapatkan jawabannya sendiri, karena itu memecahkan masalah OP dengan tepat.

pip-sync mengambil requirements.txtfile sebagai masukan, dan "trues up" lingkungan Python Anda saat ini sehingga cocok persis apa yang ada di requirements.txt. Ini termasuk menghapus semua paket yang ada di env Anda tetapi tidak ada di requirements.txt.

Contoh: Misalkan kita ingin env kami mengandung (hanya) 3 perpustakaan: libA, libB, dan libC, seperti:

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

Tetapi env kami saat ini berisi libCdan libD:

> pip freeze
libC==1.2
libD==1.3

Menjalankan pip-sync akan menghasilkan ini, yang merupakan status akhir yang kami inginkan:

> pip-sync requirements.txt
> pip freeze
libA==1.0
libB==1.1
libC==1.2
ron rothman
sumber
berhati-hatilah, jika Anda memiliki pip-tools yang terinstal secara global, itu tidak akan dihapus di virtualenv Anda yang saat ini diaktifkan ... masih aneh, tetapi selain itu alat manajemen persyaratan paling mudah yang saya tahu.
benzkji
3

Proposal Stephen adalah ide yang bagus, tapi sayangnya itu tidak berhasil jika Anda hanya memasukkan persyaratan langsung dalam file Anda, yang terdengar lebih bersih bagi saya.

Semua dependensi akan dicopot, termasuk bahkan distribute, mogok pipsendiri.

Mempertahankan file persyaratan bersih saat pelacakan versi lingkungan virtual

Inilah cara saya mencoba melacak versi lingkungan virtual saya. Saya mencoba mempertahankan minimal requirements.txt, termasuk hanya persyaratan langsung, dan bahkan tidak menyebutkan batasan versi di mana saya tidak yakin.

Tapi selain itu, saya menyimpan, dan menyertakan dalam pelacakan versi (katakanlah git), status sebenarnya dari virtualenv saya dalam sebuah venv.pipfile.

Berikut ini contoh alur kerja:


menyiapkan ruang kerja virtualenv, dengan pelacakan versi:

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

menginisialisasi sistem pelacakan versi:

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

instal paket dengan dependensi, sertakan dalam file persyaratan:

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

Sekarang mulai buat aplikasi Anda, lalu komit dan mulai cabang baru:

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

instal paket tambahan:

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

... mainkan, lalu kembali ke versi sebelumnya

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

Sekarang hapus instalan paket asing:

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

Saya kira prosesnya dapat diotomatiskan dengan git hooks, tetapi jangan keluar topik.

Tentu saja, masuk akal untuk menggunakan beberapa sistem cache paket atau repositori lokal seperti pip2pi

Jalan berbatu
sumber
2

Piggybacking off @ stephen-j-fuhry di sini adalah padanan PowerShell yang saya gunakan:

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

Meskipun ini tidak menjawab pertanyaan secara langsung, alternatif yang lebih baik untuk requirements.txtsaat ini adalah menggunakan Pipfile. Ini berfungsi mirip dengan Ruby Gemfile. Saat ini, Anda perlu menggunakan pipenvalat tersebut tetapi mudah-mudahan alat ini pada akhirnya akan digabungkan pip. Ini memberikan pipenv cleanperintah yang melakukan apa yang Anda inginkan.

(Perhatikan bahwa Anda dapat mengimpor requirements.txtdengan pipenv install -r requirements.txt. Setelah ini Anda harus memiliki Pipfiledan requirements.txtdapat dihapus.)

Michael Mior
sumber
-3

Sekarang dimungkinkan menggunakan:

pip uninstall -r requirements.txt
Roberto Nunes
sumber
2
Ini tidak menghapus paket yang tidak muncul di file persyaratan. Ini meng-uninstall semua paket yang tidak muncul dalam file.
Michael Mior