Impedire il fallimento del pip su un singolo pacchetto durante l'installazione con Requisito.txt


138

Sto installando i pacchetti da requirements.txt

pip install -r requirements.txt

Il requirements.txtfile dice:

Pillow
lxml
cssselect
jieba
beautifulsoup
nltk

lxmlè l'unico pacchetto che non riesce a installare e questo porta a tutto ciò che fallisce (risultati attesi, come sottolineato da Larsks nei commenti). Tuttavia, dopo lxmlnon riesce pipancora scorre e scarica il resto dei pacchetti.

Da quello che ho capito il pip install -r requirements.txtcomando fallirà se uno dei pacchetti elencati nel requirements.txtnon riesce a installare.

C'è qualche argomento che posso passare durante l'esecuzione pip install -r requirements.txtper dirgli di installare ciò che può e saltare i pacchetti che non può o di uscire non appena vede qualcosa che non riesce?


3
Rimuovere lxml dal vostro requisito.txt
RickyA

1
Grazie, funzionerebbe in questo caso, ma in generale, c'è un modo per aggirare questo? O è normale solo eseguire il comando, vedere che non riesce e quindi eliminare l'elenco dei pacchetti?
emh

5
Se un pacchetto è elencato in requirements.txtesso è presumibilmente necessario , quindi ha senso che pipfallisca se il pacchetto non può essere installato. Se il codice viene eseguito comunque senza quel pacchetto, difficilmente era un requisito. La potatura casuale dei pacchetti falliti requirements.txtsembra causare problemi con dipendenze mancanti.
Larks

1
@larsks può essere molto comune avere più file requisito.txt per un singolo ambiente di sviluppo o pacchetto. Ad esempio, potrebbe esserci uno pieno di strumenti opzionali che possono essere utilizzati per migliorare l'ambiente di test unità / integrazione o la profilazione delle prestazioni, ma che non sono strettamente richiesti. Volete ancora controllare la versione di un singolo file sorgente che esprime questi pacchetti e tutte le versioni aggiunte e fare affidamento sullo stesso pip install -r <some file>flusso di lavoro per standardizzare la creazione dell'ambiente appropriato.
ely,

4
Detto questo, sembra molto sordo suggerire che pip non dovrebbe supportare alcun tipo di errore grazioso / comportamento di salto opzionale che stampa un avviso ma installa ciò che può. È un'esigenza molto comune esattamente per questo tipo di installazione basata su pip da un file di requisiti.
ely,

Risposte:


230

L'esecuzione di ogni riga con pip installpuò essere una soluzione alternativa.

cat requirements.txt | xargs -n 1 pip install

Nota: il -aparametro non è disponibile in MacOS, quindi il vecchio gatto è più portatile.


21
per mac:cat requirements.txt | xargs -n 1 pip install
Walty Yeung

5
Dovevo fare: cat requirements.txt | cut -f1 -d"#" | sed '/^\s*$/d' | xargs -n 1 pip installrimuovere qualsiasi cosa nei commenti e liberarmi delle righe vuote.
Narek,

1
Almeno con GNU xargs, c'è l' -aopzione flag, che consente di xargsleggere argomenti dal file, quindi questo può essere fatto come xargs -n 1 -a requirements.txt pip install. Previene l' UUOC e l'impianto idraulico eccessivo
Sergiy Kolodyazhnyy,

7
Per windows :)FOR /F %k in (requirements.txt) DO pip install %k
wcyn,

Anche senza la -abandiera, prendere in considerazione < requirements.txt xargs -n 1 pip install, o se non ti piace il redirect al fronte, xargs -n 1 pip install < requirements.txt. :-)
torek il

10

Questa soluzione gestisce righe vuote, righe di spazi bianchi, # righe di commento, righe di spazi bianchi quindi # nel vostro requisito.txt.

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

Punta del cappello a questa risposta per la magia sed.


1
Funziona bene. Ho usato pip freezeinvece di cat requirements.txt.
Vishal,

5

Per Windows:

versione 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)

versione 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)

'main' non fa parte di pip. Errore.
Pranzell,

4

La xargssoluzione funziona ma può avere problemi di portabilità (BSD / GNU) e / o essere ingombrante se nel file dei requisiti sono presenti commenti o righe vuote.

Per quanto riguarda il caso in cui un tale comportamento sarebbe richiesto, ad esempio uso due file di requisiti separati, uno che elenca solo dipendenze core che devono essere sempre installate e un altro file con dipendenze non core che si trovano nel 90% dei casi non necessario per la maggior parte dei casi d'uso. Sarebbe un equivalente della Recommendssezione di un pacchetto debian.

Uso il seguente script di shell (richiede sed) per installare dipendenze opzionali :

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

0

Grazie, Etienne Prothon per i casi Windows.

Ma, dopo l'aggiornamento a pip 18, il pacchetto pip non espone main al pubblico. Quindi potrebbe essere necessario modificare il codice in questo modo.

 # 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)

-1

Per 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. Crea una directory locale e inserisci il tuo requirements.txtfile.
  2. Copia il codice sopra e salvalo come file Python nella stessa directory. Ricorda di usare l' .pyestensione, ad esempio,install_packages.py
  3. Esegui questo file usando un cmd: python install_packages.py
  4. Tutti i pacchetti citati verranno installati in una volta sola senza fermarsi affatto. :)

È possibile aggiungere altri parametri nella funzione di installazione. Piace: main(['install'] + [str(package)] + ['--update'])

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.