Verhindern Sie, dass Pip auf einem einzelnen Paket fehlschlägt, wenn Sie es mit der Datei require.txt installieren

138

Ich installiere Pakete von requirements.txt

pip install -r requirements.txt

Die requirements.txtDatei lautet:

Pillow
lxml
cssselect
jieba
beautifulsoup
nltk

lxmlist das einzige Paket, das nicht installiert werden kann, und dies führt dazu, dass alles fehlschlägt (erwartete Ergebnisse, wie von Larsks in den Kommentaren hervorgehoben). Doch nach lxmlnicht pipnoch läuft durch und lädt den Rest der Pakete.

Soweit ich weiß, schlägt der pip install -r requirements.txtBefehl fehl, wenn eines der in der requirements.txtInstallation aufgeführten Pakete nicht installiert werden kann.

Gibt es ein Argument, das ich beim Ausführen übergeben kann pip install -r requirements.txt, um es anzuweisen, zu installieren, was es kann, und die Pakete zu überspringen, die es nicht kann, oder zu beenden, sobald etwas fehlschlägt?

emh
quelle
3
Entfernen Sie lxml aus Ihren Anforderungen.txt
RickyA
1
Danke, das würde in diesem Fall funktionieren, aber gibt es im Allgemeinen einen Weg, dies zu umgehen? Oder ist es normal, nur den Befehl auszuführen, sicherzustellen, dass er fehlschlägt, und dann die Paketliste zu bereinigen?
Emh
5
Wenn ein Paket darin aufgeführt ist requirements.txt, ist es vermutlich erforderlich . Daher ist es sinnvoll, dass pipdies fehlschlägt, wenn das Paket nicht installiert werden kann. Wenn der Code trotzdem ohne dieses Paket ausgeführt wird, war dies kaum erforderlich. Das zufällige Bereinigen fehlgeschlagener Pakete requirements.txtscheint nur Probleme mit fehlenden Abhängigkeiten zu verursachen.
Larsks
1
@larsks Es kann sehr häufig vorkommen, dass mehrere Anforderungen.txt-Dateien für eine einzelne Entwicklungsumgebung oder ein einzelnes Entwicklungspaket vorhanden sind. Beispielsweise kann es eines mit optionalen Tools geben, mit denen die Testumgebung für Einheiten / Integrationen oder die Leistungsprofilerstellung verbessert werden können, die jedoch nicht unbedingt erforderlich sind. Sie möchten weiterhin eine einzelne Quelldatei versionieren, die diese Pakete und alle angehefteten Versionen ausdrückt, und sich auf denselben pip install -r <some file>Workflow verlassen, um die Erstellung der entsprechenden Umgebung zu standardisieren.
Ely
4
Angesichts dessen scheint es sehr taub zu sein, zu behaupten, dass pip keine Art von ordnungsgemäßem Fehler / optionalem Überspringverhalten unterstützen sollte, das eine Warnung druckt, aber installiert, was es kann. Dies ist eine sehr häufige Anforderung für genau diese Art der pip-basierten Installation aus einer Anforderungsdatei.
Ely

Antworten:

229

Das Ausführen jeder Zeile mit pip installkann eine Problemumgehung sein.

cat requirements.txt | xargs -n 1 pip install

Hinweis: Der -aParameter ist unter MacOS nicht verfügbar, daher ist die alte Katze portabler.

MZD
quelle
21
für Mac:cat requirements.txt | xargs -n 1 pip install
Walty Yeung
5
Ich musste tun: cat requirements.txt | cut -f1 -d"#" | sed '/^\s*$/d' | xargs -n 1 pip installalles in den Kommentaren entfernen und leere Zeilen loswerden.
Narek
1
Zumindest bei GNU xargsgibt es die -aFlag-Option, mit der xargsArgumente aus der Datei gelesen werden können xargs -n 1 -a requirements.txt pip install. Verhindert UUOC und übermäßige Installation
Sergiy Kolodyazhnyy
7
Für Windows :)FOR /F %k in (requirements.txt) DO pip install %k
wcyn
Überlegen Sie auch ohne -aFlagge, < requirements.txt xargs -n 1 pip installoder wenn Ihnen die Weiterleitung vorne nicht gefällt xargs -n 1 pip install < requirements.txt. :-)
torek
10

Diese Lösung verarbeitet Leerzeilen, Leerzeichenzeilen, # Kommentarzeilen, Leerzeichen-dann- # Kommentarzeilen in Ihrer Anforderung.txt.

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

Hutspitze zu dieser Antwort für die sed Magie.

Rubel
quelle
1
Funktioniert gut. Ich habe pip freezestatt verwendet cat requirements.txt.
Vishal
5

Für Windows:

Pip-Version> = 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)

Pip-Version <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
quelle
'main' ist kein Teil von pip. Error.
Pranzell
4

Die xargsLösung funktioniert, kann jedoch Portabilitätsprobleme (BSD / GNU) aufweisen und / oder umständlich sein, wenn Ihre Anforderungsdatei Kommentare oder Leerzeilen enthält.

Für den Anwendungsfall, in dem ein solches Verhalten erforderlich wäre, verwende ich beispielsweise zwei separate Anforderungsdateien, von denen eine nur die Kerninstallationen auflistet, die immer installiert werden müssen, und eine andere Datei mit Nicht-Kernabhängigkeiten, die in 90% der Fälle vorliegen wird für die meisten Fälle nicht benötigt. Das wäre ein Äquivalent zum RecommendsAbschnitt eines Debian-Pakets.

Ich verwende das folgende Shell-Skript (erforderlich sed), um optionale Abhängigkeiten zu installieren :

#!/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
quelle
0

Vielen Dank, Etienne Prothon für Windows-Fälle.

Nach dem Upgrade auf Pip 18 wird das Pip-Paket jedoch nicht öffentlich zugänglich gemacht. Möglicherweise müssen Sie den Code so ändern.

 # 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
quelle
-1

Für 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. Erstellen Sie ein lokales Verzeichnis und legen Sie Ihre requirements.txtDatei darin ab.
  2. Kopieren Sie den obigen Code und speichern Sie ihn als Python-Datei im selben Verzeichnis. Denken Sie daran, die .pyErweiterung zu verwenden , z.install_packages.py
  3. Führen Sie diese Datei mit einem cmd aus: python install_packages.py
  4. Alle genannten Pakete werden auf einmal installiert, ohne anzuhalten. :) :)

Sie können andere Parameter in der Installationsfunktion hinzufügen. Mögen: main(['install'] + [str(package)] + ['--update'])

Pranzell
quelle