¿Cuándo usar el archivo de requisitos pip frente a install_requires en setup.py?

94

Estoy usando pip con virtualenv para empaquetar e instalar algunas bibliotecas de Python.

Me imagino que lo que estoy haciendo es un escenario bastante común. Soy el encargado de mantenimiento de varias bibliotecas para las que puedo especificar las dependencias explícitamente. Algunas de mis bibliotecas dependen de bibliotecas de terceros que tienen dependencias transitivas sobre las que no tengo control.

Lo que estoy tratando de lograr es que pip installen una de mis bibliotecas descargue / instale todas sus dependencias ascendentes. Con lo que estoy luchando en la documentación de pip es si / cómo los archivos de requisitos pueden hacer esto por sí mismos o si en realidad son solo un complemento del uso install_requires.

¿Usaría install_requiresen todas mis bibliotecas para especificar dependencias y rangos de versiones y luego solo usaría un archivo de requisitos para resolver un conflicto y / o congelarlos para una compilación de producción?

Supongamos que vivo en un mundo imaginario (lo sé, lo sé) y mis dependencias ascendentes son sencillas y están garantizadas que nunca entrarán en conflicto o romperán la compatibilidad con versiones anteriores. ¿Me vería obligado a usar un archivo de requisitos de pip o simplemente dejaría que pip / setuptools / distribution instale todo en función de él install_requires?

Hay muchas preguntas similares aquí, pero no pude encontrar ninguna que fuera tan básica como cuándo usar una u otra o usarlas juntas en armonía.

Joe Holloway
fuente
3
Este es un artículo muy agradable que explica la relación de los dos y también cómo se integran.
Björn Pollex

Respuestas:

68

Mi filosofía es que install_requiresdebe indicar un mínimo de lo que necesita. Puede incluir requisitos de versión si sabe que algunas versiones no funcionarán; pero no debería tener requisitos de versión de los que no esté seguro (por ejemplo, no esté seguro de si una versión futura de una dependencia romperá su biblioteca o no).

Por otro lado, los archivos de requisitos deben indicar lo que sabe que funciona y pueden incluir dependencias opcionales que recomiende. Por ejemplo, puede usar SQLAlchemy pero sugerir MySQL, y así poner MySQLdb en el archivo de requisitos).

Entonces, en resumen: install_requireses mantener a las personas alejadas de cosas que sabes que no funcionan, mientras que los archivos de requisitos llevan a las personas hacia cosas que sabes que funcionan. Una razón de esto es que los install_requiresrequisitos siempre se verifican y no se pueden deshabilitar sin cambiar realmente los metadatos del paquete. Así que no es fácil probar una nueva combinación. Los archivos de requisitos solo se comprueban en el momento de la instalación.

Ian Bicking
fuente
5
¿Significa esto que debes reflejar las setup.py install_requires=profundidades requirements.txt?
proppy
9
Sin embargo, tener ambos, requisitos en setup.py y un archivo de requisitos es peligroso, porque la duplicación solo pide que se desincronice.
Sebastian Blask
1
Además, ¿cómo trabaja realmente con él entonces? Supongo que usa el archivo de requisitos una vez para llegar a un estado que definitivamente está funcionando. Luego instale con el paquete real con pip. ¿Nunca podrá usarlo -Uporque eso podría anular las dependencias del archivo de requisitos? ¿Cómo se actualiza?
Sebastian Blask
1
¿Esta respuesta se aplica por igual a aplicaciones y paquetes? Imagine my-web-app (una aplicación) dependiendo de alguna-herramienta (un paquete), las cuales dependen del paquete de solicitudes. Si alguna herramienta tiene un archivo requirements.txt que fija una versión particular o un rango de versiones de solicitudes, eso parecería crear un problema potencial para my-web-app, que podría haber especificado una versión / rango de versiones en conflicto.
Reece
2
Debería haber una única forma de instalar un paquete. Por lo tanto, no se recomienda tener ambos a menos que desee confundir a otros colaboradores.
Gewthen
17

esto es lo que puse en mi setup.py:

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

setup(
    .....
    install_requires=REQUIREMENTS
)
rbp
fuente
20
Tenga cuidado, los archivos de requisitos pueden contener comentarios e inclusiones. Debe usar el analizador pip
Romain Hardouin
1
sí, eventualmente cambié esto para eliminar los comentarios. pip parser se ve mejor que mi respuesta.
rbp
7
¿Por qué utilizar un archivo de requisitos si todo lo que contiene ya está en setup.py?
Sebastian Blask
2
@RomainHardouin, como se menciona en los comentarios de su respuesta vinculada, pip no está destinado a usarse de esa manera.
akaihola
1
Sí, esto funcionó para mí hasta --extra-index-urlque se requirió una crítica en los requisitos y esto estalló en mi cara. Gracias @RomainHardouin
Tommy
11

La Guía del usuario de Python Packaging tiene una página sobre este tema, le recomiendo que la lea:

Resumen:

install_requires¿Hay una lista de las dependencias del paquete que absolutamente deben instalarse para que funcione? No está destinado a anclar las dependencias a versiones específicas, pero se aceptan rangos, por ejemplo install_requires=['django>=1.8']. install_requireses observado por pip install name-on-pypiy otras herramientas.

requirements.txtes solo un archivo de texto, con el que puede optar por ejecutar pip install -r requirements.txt. Se supone que tienen las versiones de todas las dependencias y subdependencies cubrió, como esto: django==1.8.1. Puede crear uno usando pip freeze > requirements.txt. (Algunos servicios, como Heroku, se ejecutan automáticamente pip install -r requirements.txtpara usted.) pip install name-on-pypiNo mira requirements.txt, solo mira install_requires.

Flimm
fuente
5

Solo uso un setup.pyy install_requiresporque solo hay un lugar para mirar. Es tan poderoso como tener un archivo de requisitos y no hay duplicaciones que mantener.

Sebastián Blask
fuente
La pregunta es cuándo usar uno u otro, no lo deletreé, pero mi respuesta es que siempre uso uno y nunca el otro. ¿Cómo es que eso no responde a la pregunta?
Sebastian Blask