430 Stimmen

Referenz requirements.txt für den install_requires kwarg in der Datei setuptools setup.py

Ich habe eine requirements.txt Datei, die ich mit Travis-CI verwende. Es scheint albern, die Anforderungen in beiden Dateien zu duplizieren requirements.txt y setup.py Ich hatte gehofft, ein Dateihandle an die Funktion install_requires kwarg in setuptools.setup .

Ist dies möglich? Wenn ja, wie sollte ich vorgehen?

Hier ist mein requirements.txt Datei:

guessit>=0.5.2
tvdb_api>=1.8.2
hachoir-metadata>=1.3.3
hachoir-core>=1.3.3
hachoir-parser>=1.3.4

371voto

Jonathan Hanson Punkte 3893

Auf den ersten Blick scheint es so, dass requirements.txt y setup.py sind alberne Duplikate, aber es ist wichtig zu verstehen, dass die Form zwar ähnlich ist, aber die beabsichtigte Funktion sehr unterschiedlich ist.

Das Ziel eines Paketautors ist es, mit der Angabe von Abhängigkeiten zu sagen: "Wo auch immer Sie dieses Paket installieren, dies sind die anderen Pakete, die Sie benötigen, damit dieses Paket funktioniert."

Im Gegensatz dazu hat der Deployment-Autor (das kann dieselbe Person zu einem anderen Zeitpunkt sein) eine andere Aufgabe, indem er sagt: "Hier ist die Liste der Pakete, die wir zusammengestellt und getestet haben und die ich jetzt installieren muss".

Der Paketautor schreibt für eine Vielzahl von Szenarien, da er seine Arbeit zur Verfügung stellt, damit sie in einer Art und Weise genutzt werden kann, die er nicht kennt, und er hat keine Möglichkeit zu wissen, welche Pakete neben seinem Paket installiert werden. Um ein guter Nachbar zu sein und Versionskonflikte mit anderen Paketen zu vermeiden, müssen sie eine möglichst große Bandbreite an Abhängigkeitsversionen angeben. Das ist es, was install_requires in setup.py tut.

Der Verfasser der Bereitstellung schreibt für ein ganz anderes, sehr spezifisches Ziel: eine einzelne Instanz einer installierten Anwendung oder eines Dienstes, die auf einem bestimmten Computer installiert ist. Um ein Deployment genau zu kontrollieren und sicher zu sein, dass die richtigen Pakete getestet und installiert werden, muss der Deployment-Autor die genaue Version und den Quellort jedes zu installierenden Pakets angeben, einschließlich der Abhängigkeiten und der Abhängigkeiten der Abhängigkeiten. Mit dieser Spezifikation kann eine Bereitstellung wiederholt auf mehreren Rechnern angewendet oder auf einem Testrechner getestet werden, und der Autor der Bereitstellung kann sicher sein, dass jedes Mal die gleichen Pakete bereitgestellt werden. Das ist es, was ein requirements.txt tut.

Sie sehen also, dass beide zwar wie eine große Liste von Paketen und Versionen aussehen, aber sehr unterschiedliche Aufgaben haben. Und es ist wirklich leicht, das zu verwechseln und etwas falsch zu machen! Aber die richtige Art, darüber nachzudenken, ist, dass requirements.txt ist eine "Antwort" auf die "Frage", die sich aus den Anforderungen in den verschiedenen setup.py Paketdateien. Anstatt sie von Hand zu schreiben, wird sie oft erzeugt, indem pip angewiesen wird, sich alle setup.py Dateien in einer Reihe von gewünschten Paketen, findet eine Reihe von Paketen, von denen es glaubt, dass sie alle Anforderungen erfüllen, und "friert" dann, nachdem sie installiert sind, diese Liste von Paketen in einer Textdatei ein (dies ist der Ort, an dem die pip freeze Name stammt).

Die Quintessenz ist also:

  • setup.py sollten die lockersten Versionen von Abhängigkeiten deklariert werden, die noch praktikabel sind. Seine Aufgabe ist es, zu sagen, womit ein bestimmtes Paket arbeiten kann.
  • requirements.txt ist ein Bereitstellungsmanifest, das einen gesamten Installationsauftrag definiert und nicht als an ein bestimmtes Paket gebunden betrachtet werden sollte. Seine Aufgabe ist es, eine vollständige Liste aller Pakete zu deklarieren, die für eine Bereitstellung erforderlich sind.
  • Da diese beiden Dinge so unterschiedliche Inhalte und Daseinsberechtigungen haben, ist es nicht möglich, das eine einfach in das andere zu kopieren.

Referenzen:

334voto

Romain Hardouin Punkte 3749

Sie können es auch umdrehen und die Abhängigkeiten in setup.py und haben ein einziges Zeichen - einen Punkt . - in requirements.txt stattdessen.


Alternativ, auch wenn dies nicht empfohlen wird, ist es immer noch möglich, die requirements.txt Datei (wenn sie nicht per URL auf externe Anforderungen verweist) mit dem folgenden Hack (getestet mit pip 9.0.1 ):

install_reqs = parse_requirements('requirements.txt', session='hack')

Dadurch wird nicht gefiltert Umweltmarker Allerdings.


In alten Versionen von pip, genauer gesagt älter als 6.0 gibt es eine öffentliche API, mit der dies möglich ist. Eine Anforderungsdatei kann Kommentare enthalten ( # ) und kann einige andere Dateien enthalten ( --requirement o -r ). Wenn Sie also wirklich eine requirements.txt können Sie den Pip-Parser verwenden:

from pip.req import parse_requirements

# parse_requirements() returns generator of pip.req.InstallRequirement objects
install_reqs = parse_requirements(<requirements_path>)

# reqs is a list of requirement
# e.g. ['django==1.5.1', 'mezzanine==1.4.6']
reqs = [str(ir.req) for ir in install_reqs]

setup(
    ...
    install_requires=reqs
)

146voto

Fredrick Brennan Punkte 6599

Es kann kein Dateihandle annehmen. Die install_requires Argument kann nur eine Zeichenkette oder eine Liste von Zeichenketten sein .

Sie können Ihre Datei natürlich auch im Setup-Skript einlesen und als Liste von Zeichenketten an install_requires .

import os
from setuptools import setup

with open('requirements.txt') as f:
    required = f.read().splitlines()

setup(...
install_requires=required,
...)

70voto

Tobu Punkte 23823

Anforderungsdateien verwenden ein erweitertes Pip-Format, das nur sinnvoll ist, wenn Sie Ihre setup.py mit stärkeren Einschränkungen, z. B. mit der Angabe der genauen URLs, aus denen einige der Abhängigkeiten stammen müssen, oder der Ausgabe von pip freeze um den gesamten Paketsatz auf bekannte Arbeitsversionen einzufrieren. Wenn Sie die zusätzlichen Beschränkungen nicht benötigen, verwenden Sie nur eine setup.py . Wenn Sie das Gefühl haben, dass Sie wirklich eine requirements.txt Auf jeden Fall können Sie eine einzige Zeile daraus machen:

.

Sie ist gültig und bezieht sich genau auf den Inhalt der Datei setup.py die sich im selben Verzeichnis befindet.

40voto

famousgarkin Punkte 12992

Auch wenn dies keine exakte Antwort auf die Frage ist, empfehle ich den Blogbeitrag von Donald Stufft unter https://caremad.io/2013/07/setup-vs-requirement/ für einen guten Überblick über dieses Problem. Ich habe es mit großem Erfolg verwendet.

Kurz gesagt, requirements.txt ist kein setup.py Alternative, sondern eine Ergänzung zum Einsatz. Behalten Sie eine angemessene Abstraktion der Paketabhängigkeiten in setup.py . Einstellung requirements.txt oder mehrere von ihnen, um bestimmte Versionen von Paketabhängigkeiten für Entwicklung, Test oder Produktion zu holen.

Z.B. mit Paketen, die im Repo unter deps/ :

# fetch specific dependencies
--no-index
--find-links deps/

# install package
# NOTE: -e . for editable mode
.

pip führt das Paket setup.py und installiert die spezifischen Versionen der Abhängigkeiten, die in install_requires . Es gibt keine Duplizität und der Zweck der beiden Artefakte bleibt erhalten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X