Kiedy używać pliku wymagań pip, a kiedy install_requires w setup.py?

94

Używam pip z virtualenv do pakowania i instalowania niektórych bibliotek Pythona.

Wyobrażam sobie, że to, co robię, to dość powszechny scenariusz. Jestem opiekunem kilku bibliotek, dla których mogę jawnie określić zależności. Niektóre z moich bibliotek są zależne od bibliotek innych firm, które mają zależności przechodnie, nad którymi nie mam kontroli.

To, co próbuję osiągnąć, to pip installpobranie / zainstalowanie wszystkich zewnętrznych zależności w jednej z moich bibliotek. W dokumentacji pip zmagam się z tym, czy / w jaki sposób pliki wymagań mogą to zrobić samodzielnie lub czy są one tylko dodatkiem do używania install_requires.

Czy użyłbym install_requireswe wszystkich moich bibliotekach do określenia zależności i zakresów wersji, a następnie użyłbym pliku wymagań tylko do rozwiązania konfliktu i / lub zamrożenia go na potrzeby kompilacji produkcyjnej?

Udawajmy, że żyję w wyimaginowanym świecie (wiem, wiem), a moje wcześniejsze zależności są proste i gwarantują, że nigdy nie kolidują ani nie przerywają wstecznej kompatybilności. Czy byłbym zmuszony w ogóle użyć pliku wymagań pip, czy po prostu pozwolić pip / setuptools / distribute zainstalować wszystko na podstawie install_requires?

Jest tutaj wiele podobnych pytań, ale nie mogłem znaleźć żadnego tak podstawowego, jak użycie jednego lub drugiego lub harmonijnego użycia ich obu razem.

Joe Holloway
źródło
3
To bardzo fajny artykuł wyjaśniający związek tych dwojga, a także sposób ich integracji.
Björn Pollex

Odpowiedzi:

68

Moja filozofia jest taka, że install_requirespowinno wskazywać minimum tego, czego potrzebujesz. Może zawierać wymagania dotyczące wersji, jeśli wiesz że niektóre wersje nie będą działać; ale nie powinno mieć wymagań dotyczących wersji, w przypadku których nie jesteś pewien (np. nie jesteś pewien, czy przyszłe wydanie zależności zepsuje Twoją bibliotekę, czy nie).

Z drugiej strony pliki wymagań powinny wskazywać, co wiesz, że działa, i mogą zawierać zalecane opcjonalne zależności. Na przykład możesz użyć SQLAlchemy, ale zasugerować MySQL, więc umieść MySQLdb w pliku wymagań).

Podsumowując: install_requirespolega na trzymaniu ludzi z dala od rzeczy, o których wiesz, że nie działają, podczas gdy pliki wymagań mają prowadzić ludzi do rzeczy, o których wiesz, że działają. Jednym z powodów jest to, że install_requireswymagania są zawsze sprawdzane i nie można ich wyłączyć bez faktycznej zmiany metadanych pakietu. Nie możesz więc łatwo wypróbować nowej kombinacji. Pliki wymagań są sprawdzane tylko podczas instalacji.

Ian Bicking
źródło
5
czy to oznacza, że ​​powinieneś lustro setup.py install_requires=deps w requirements.txt?
proppy
9
Posiadanie obu wymagań w setup.py i pliku wymagań jest jednak niebezpieczne, ponieważ duplikacja prosi tylko o utratę synchronizacji.
Sebastian Blask
1
Jak więc właściwie z tym pracujesz? Zakładam, że użyjesz pliku wymagań raz, aby uzyskać stan, który zdecydowanie działa. Następnie zainstaluj z rzeczywistym pakietem za pomocą pip. Nigdy nie będziesz mógł użyć, -Uponieważ może to przesłonić zależności z pliku wymagań? Jak aktualizujesz?
Sebastian Blask
1
Czy ta odpowiedź dotyczy w równym stopniu aplikacji i pakietów? Wyobraź sobie my-web-app (aplikację) zależną od jakiegoś narzędzia (pakietu), z których oba zależą od pakietu żądań. Jeśli jakieś narzędzie ma plik Requirements.txt, który przypina konkretną wersję lub zakres wersji żądań, wydaje się, że stwarza to potencjalny problem dla mojej aplikacji internetowej, która mogła określić sprzeczny zakres wersji / wersji.
Reece
2
Powinien istnieć jedyny sposób na zainstalowanie pakietu. Dlatego posiadanie obu nie jest zalecane, chyba że chcesz zmylić innych współpracowników.
Gewthen
18

oto co umieściłem w moim setup.py:

# this grabs the requirements from requirements.txt
REQUIREMENTS = [i.strip() for i in open("requirements.txt").readlines()]

setup(
    .....
    install_requires=REQUIREMENTS
)
rbp
źródło
20
Uważaj, pliki wymagań mogą zawierać komentarze i załączniki. Powinieneś użyć parsera pip
Romain Hardouin
1
tak, ostatecznie zmieniłem to, aby usunąć komentarze. Parser pip wygląda lepiej niż moja odpowiedź.
rbp
7
Po co w ogóle używać pliku wymagań, skoro wszystko, co zawiera, jest już w pliku setup.py?
Sebastian Blask
2
@RomainHardouin, jak wspomniano w komentarzach do Twojej połączonej odpowiedzi, pip nie powinien być używany w ten sposób.
akaihola
1
tak, to działało dla mnie, dopóki nie --extra-index-urlbyło wymagane krytyczne w wymaganiach i to wybuchło w mojej twarzy. Dzięki @RomainHardouin
Tommy,
11

Podręcznik użytkownika pakietu Python zawiera stronę poświęconą temu tematowi, bardzo polecam ją przeczytać:

Podsumowanie:

install_requiresjest tam lista zależności pakietu, które absolutnie muszą być zainstalowane, aby pakiet działał. Nie służy do przypinania zależności do określonych wersji, ale na przykład akceptowane są zakresy install_requires=['django>=1.8']. install_requiresjest obserwowany przez pip install name-on-pypii inne narzędzia.

requirements.txtto tylko plik tekstowy, z którym możesz skorzystać pip install -r requirements.txt. To oznaczało mieć wersje wszystkich zależności i subdependencies przypięte coś takiego: django==1.8.1. Możesz go utworzyć za pomocą pip freeze > requirements.txt. (Niektóre usługi, takie jak Heroku, uruchamiają się automatycznie pip install -r requirements.txt.) pip install name-on-pypiNie patrzy requirements.txt, tylko na install_requires.

Flimm
źródło
5

Zawsze używam tylko setup.pyi, install_requiresponieważ jest tylko jedno miejsce, na które mogę spojrzeć. Jest tak samo potężny, jak posiadanie pliku wymagań i nie trzeba go dublować.

Sebastian Blask
źródło
Pytanie brzmi, kiedy użyć jednego lub drugiego, nie przeliterowałem tego, ale moja odpowiedź brzmi, że zawsze używam jednego, a nigdy drugiego. Jak to nie jest odpowiedzią na pytanie?
Sebastian Blask