Hentikan pip agar tidak gagal pada satu paket ketika menginstal dengan requirement.txt

138

Saya menginstal paket dari requirements.txt

pip install -r requirements.txt

The requirements.txtberkas berbunyi:

Pillow
lxml
cssselect
jieba
beautifulsoup
nltk

lxmladalah satu-satunya paket gagal untuk menginstal dan ini menyebabkan semuanya gagal (hasil yang diharapkan seperti yang ditunjukkan oleh larsk di komentar). Namun, setelah lxmlgagal pipmasih berjalan melalui dan mengunduh sisa paket.

Dari apa yang saya mengerti pip install -r requirements.txtperintah akan gagal jika ada paket yang terdaftar dalam requirements.txtgagal untuk menginstal.

Apakah ada argumen yang bisa saya sampaikan ketika menjalankan pip install -r requirements.txtuntuk mengatakannya untuk menginstal apa yang bisa dan melewatkan paket yang tidak bisa, atau untuk keluar segera setelah melihat sesuatu gagal?

emh
sumber
3
Hapus lxml dari requirement.txt Anda
RickyA
1
Terima kasih, itu akan berhasil dalam kasus ini, tetapi secara umum, apakah ada cara lain untuk mengatasi ini? Atau apakah normal hanya untuk menjalankan perintah, melihat itu gagal dan kemudian memangkas daftar paket?
emh
5
Jika suatu paket terdaftar di requirements.txtdalamnya mungkin diperlukan , maka masuk akal pipjika gagal jika paket tersebut tidak dapat diinstal. Jika kode tetap dijalankan tanpa paket itu maka itu hampir tidak menjadi persyaratan. Pemangkasan paket gagal secara acak requirements.txtsepertinya hanya akan menyebabkan masalah dengan dependensi yang hilang.
larsks
1
@ larsks sangat umum memiliki beberapa file requirement.txt untuk satu paket atau paket pengembangan. Misalnya, mungkin ada satu alat opsional penuh yang dapat digunakan untuk meningkatkan lingkungan uji unit / integrasi atau profil kinerja, tetapi yang tidak sepenuhnya diperlukan. Anda masih ingin mengontrol versi file sumber tunggal yang mengekspresikan paket-paket ini dan setiap versi yang disematkan, dan mengandalkan pip install -r <some file>alur kerja yang sama untuk membakukan pembuatan lingkungan yang sesuai.
ely
4
Mengingat ini, tampaknya sangat tuli untuk menyarankan pip seharusnya tidak mendukung beberapa jenis kegagalan anggun / perilaku lompatan opsional yang mencetak peringatan tetapi menginstal apa yang bisa. Itu adalah kebutuhan yang sangat umum untuk jenis instalasi berbasis pip dari file persyaratan.
ely

Jawaban:

230

Menjalankan setiap baris pip installmungkin merupakan solusi.

cat requirements.txt | xargs -n 1 pip install

Catatan: -aparameter tidak tersedia di MacOS, jadi kucing tua lebih mudah dibawa-bawa.

MZD
sumber
21
untuk mac:cat requirements.txt | xargs -n 1 pip install
Walty Yeung
5
Saya harus melakukan: cat requirements.txt | cut -f1 -d"#" | sed '/^\s*$/d' | xargs -n 1 pip installuntuk menghapus apa pun di komentar dan menyingkirkan baris kosong.
Narek
1
Paling tidak dengan GNU xargs, ada -aopsi flag, yang memungkinkan xargsmembaca argumen dari file, jadi ini bisa dilakukan sebagai xargs -n 1 -a requirements.txt pip install. Mencegah UUOC dan pipa ledeng yang berlebihan
Sergiy Kolodyazhnyy
7
Untuk windows :)FOR /F %k in (requirements.txt) DO pip install %k
wcyn
Bahkan tanpa -abendera, pertimbangkan < requirements.txt xargs -n 1 pip install, atau jika Anda tidak suka pengalihan di depan xargs -n 1 pip install < requirements.txt,. :-)
torek
10

Solusi ini menangani baris kosong, baris spasi putih, # baris komentar, baris spasi putih-kemudian # komentar di requirement.txt Anda.

cat requirements.txt | sed -e '/^\s*#.*$/d' -e '/^\s*$/d' | xargs -n 1 pip install

Kiat ujung atas jawaban ini untuk sihir sed.

rubel
sumber
1
Bekerja dengan baik. Saya menggunakan pip freezebukan cat requirements.txt.
Vishal
5

Untuk Windows:

versi pip> = 18

import sys
from pip._internal import main as pip_main

def install(package):
    pip_main(['install', package])

if __name__ == '__main__':
    with open(sys.argv[1]) as f:
        for line in f:
            install(line)

versi pip <18

import sys
import pip

def install(package):
    pip.main(['install', package])

if __name__ == '__main__':
    with open(sys.argv[1]) as f:
        for line in f:
            install(line)
Etienne Prothon
sumber
'main' bukan bagian dari pip. Kesalahan.
Pranzell
4

The xargskarya solusi, tetapi dapat memiliki masalah portabilitas (BSD / GNU) dan / atau menjadi rumit jika Anda memiliki komentar atau baris kosong dalam file kebutuhan Anda.

Adapun usecase di mana perilaku seperti itu akan diperlukan, saya menggunakan misalnya dua file persyaratan terpisah, satu yang hanya daftar dependensi inti yang harus selalu diinstal dan file lain dengan dependensi non-inti yang ada di 90% dari kasus tidak diperlukan untuk sebagian besar usecases. Itu akan menjadi setara dengan Recommendsbagian dari paket debian.

Saya menggunakan skrip shell berikut ( sedharus) untuk menginstal dependensi opsional :

#!/bin/sh

while read dependency; do
    dependency_stripped="$(echo "${dependency}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
    # Skip comments
    if [[ $dependency_stripped == \#* ]]; then
        continue
    # Skip blank lines
    elif [ -z "$dependency_stripped" ]; then
        continue
    else
        if pip install "$dependency_stripped"; then
            echo "$dependency_stripped is installed"
        else
            echo "Could not install $dependency_stripped, skipping"
        fi
    fi
done < recommends.txt
Leo Cavaille
sumber
0

Terima kasih, Etienne Prothon untuk kasing windows.

Tetapi, setelah memutakhirkan ke pip 18, paket pip tidak mengekspos utama ke publik. Jadi, Anda mungkin perlu mengubah kode seperti ini.

 # This code install line by line a list of pip package 
 import sys
 from pip._internal import main as pip_main

 def install(package):
    pip_main(['install', package])

 if __name__ == '__main__':
    with open(sys.argv[1]) as f:
        for line in f:
            install(line)
Jaeyoon Jeong
sumber
-1

Untuk Windows:

import os
from pip.__main__ import _main as main

error_log = open('error_log.txt', 'w')

def install(package):
    try:
        main(['install'] + [str(package)])
    except Exception as e:
        error_log.write(str(e))

if __name__ == '__main__':
    f = open('requirements1.txt', 'r')
    for line in f:
        install(line)
    f.close()
    error_log.close()
  1. Buat direktori lokal, dan letakkan requirements.txtfile Anda di dalamnya.
  2. Salin kode di atas dan simpan sebagai file python di direktori yang sama. Ingatlah untuk menggunakan .pyekstensi, misalnya,install_packages.py
  3. Jalankan file ini menggunakan cmd: python install_packages.py
  4. Semua paket yang disebutkan akan diinstal dalam sekali jalan tanpa henti sama sekali. :)

Anda dapat menambahkan parameter lain dalam fungsi instal. Suka: main(['install'] + [str(package)] + ['--update'])

Pranzell
sumber