Saltar al contenido

Requirements.txt vs setup.py

Luego de de nuestra larga compilación de información dimos con la respuesta esta impedimento que pueden tener algunos lectores. Te brindamos la solución y esperamos resultarte de mucha ayuda.

Solución:

requirements.txt:

Esto le ayuda a configurar su entorno de desarrollo.

Programas como pip se puede utilizar para instalar todos los paquetes enumerados en el archivo de una sola vez. Después de eso, puede comenzar a desarrollar su script de Python. Especialmente útil si planea que otros contribuyan al desarrollo o utilicen entornos virtuales. Así es como lo usas:

pip install -r requirements.txt

setup.py:

Esto le ayuda a crear paquetes que puede redistribuir.

los setup.py El script está destinado a instalar su paquete en el sistema del usuario final, no a preparar el entorno de desarrollo como pip install -r requirements.txt lo hace. Consulte esta respuesta para obtener más detalles sobre setup.py.


Las dependencias de su proyecto se enumeran en ambos archivos.

La respuesta corta es que requirements.txt es solo para enumerar los requisitos del paquete. setup.py por otro lado, es más como un script de instalación. Si no planea instalar el código Python, normalmente solo necesitará requirements.txt.

El archivo setup.py describe, además de las dependencias del paquete, el conjunto de archivos y módulos que deben empaquetarse (o compilarse, en el caso de módulos nativos (es decir, escritos en C)), y metadatos para agregar a las listas de paquetes de Python (p. ej. nombre, versión del paquete, descripción del paquete, autor, …).

Debido a que ambos archivos enumeran dependencias, esto puede conducir a un poco de duplicación. Lea a continuación para obtener más detalles.

requirements.txt


Este archivo enumera los requisitos del paquete de Python. Es un archivo de texto sin formato (opcionalmente con comentarios) que enumera el paquete dependencias de su proyecto de Python (uno por línea). Eso no describe la forma en que se instala tu paquete de Python. Por lo general, consumiría el archivo de requisitos con pip install -r requirements.txt.

El nombre de archivo del archivo de texto es arbitrario, pero a menudo se requirements.txt por convención. Al explorar repositorios de código fuente de otros paquetes de Python, es posible que se encuentre con otros nombres, como dev-dependencies.txt o dependencies-dev.txt. Aquellos tienen el mismo propósito que dependencies.txt pero en general, enumera las dependencias adicionales de interés para los desarrolladores del paquete en particular, es decir, para probar el código fuente (por ejemplo, pytest, pylint, etc.) antes del lanzamiento. Los usuarios del paquete generalmente no necesitarían todo el conjunto de dependencias del desarrollador para ejecutar el paquete.

Si es múltiplerequirements-X.txt las variantes están presentes, entonces normalmente una listará las dependencias en tiempo de ejecución y la otra en tiempo de compilación o dependencias de prueba. Algunos proyectos también conectan en cascada su archivo de requisitos, es decir, cuando un archivo de requisitos incluye otro archivo (ejemplo). Hacerlo puede reducir la repetición.

setup.py


Este es un script de Python que usa el setuptools módulo para definir un paquete de Python (nombre, archivos incluidos, metadatos del paquete e instalación). Será como requirements.txt, también enumera las dependencias de tiempo de ejecución del paquete. Setuptools es la forma de facto de construir e instalar paquetes de Python, pero tiene sus deficiencias, que con el tiempo han hecho surgir el desarrollo de nuevos “administradores de metapaquetes”, como pip. Ejemplos de deficiencias de setuptools son su incapacidad para instalar varias versiones del mismo paquete y la falta de un comando de desinstalación.

Cuando un usuario de Python lo hace pip install ./pkgdir_my_module (o pip install my-module), pip se ejecutará setup.py en el directorio (o módulo) dado. Del mismo modo, cualquier módulo que tenga un setup.py puede ser pip-instalado, por ejemplo, ejecutando pip install . de la misma carpeta.

¿Realmente necesito ambos?


La respuesta corta es no, pero es bueno tener ambos. Logran diferentes propósitos, pero ambos pueden usarse para enumerar sus dependencias.

Hay un truco que puede considerar para evitar duplicar su lista de dependencias entre requirements.txt y setup.py. Si ha escrito una setup.py para su paquete ya, y sus dependencias son en su mayoría externas, podría considerar tener un simple requirements.txt con solo lo siguiente:

 # requirements.txt
 #
 # installs dependencies from ./setup.py, and the package itself,
 # in editable mode
 -e .

 # (the -e above is optional). you could also just install the package
 # normally with just the line below (after uncommenting)
 # .

los -e es un especial pip install opción que instala el paquete dado en editable modo. Cuando pip -r requirements.txt se ejecuta en este archivo, pip instalará sus dependencias a través de la lista en ./setup.py. La opción editable colocará un enlace simbólico en su directorio de instalación (en lugar de un huevo o una copia archivada). Permite a los desarrolladores editar código en su lugar desde el repositorio sin reinstalarlo.

También puede aprovechar lo que se llama “extras de setuptools” cuando tiene ambos archivos en su repositorio de paquetes. Puede definir paquetes opcionales en setup.py en una categoría personalizada e instalar esos paquetes solo desde esa categoría con pip:

# setup.py
from setuptools import setup
setup(
   name="FOO"
   ...
   extras_require = 
       'dev': ['pylint'],
       'build': ['requests']
   
   ...
)

y luego, en el archivo de requisitos:

# install packages in the [build] category, from setup.py
# (path/to/mypkg is the directory where setup.py is)
-e path/to/mypkg[build]

Esto mantendría todas sus listas de dependencias dentro de setup.py.

Nota: Normalmente, ejecutaría pip y setup.py desde una caja de arena, como las creadas con el programa. virtualenv. Esto evitará instalar paquetes de Python fuera del contexto del entorno de desarrollo de su proyecto.

En aras de la integridad, así es como lo veo en 3 4 ángulos diferentes.

  1. Sus propósitos de diseño son diferentes

Esta es la descripción precisa citada de la documentación oficial (el énfasis es mío):

Mientras que install_requires (en setup.py) define las dependencias para un solo proyecto, Los archivos de requisitos se utilizan a menudo para definir los requisitos para un entorno Python completo.

Mientras que los requisitos de install_requires son mínimos, los archivos de requisitos a menudo contienen una lista exhaustiva de versiones ancladas con el fin de lograr instalaciones repetibles de un entorno completo.

Pero es posible que aún no sea fácil de entender, por lo que en la siguiente sección, se incluyen 2 ejemplos fácticos para demostrar cómo se supone que los 2 enfoques deben usarse de manera diferente.

  1. Por lo tanto, sus usos reales son (se supone que son) diferentes
  • Si tu proyecto foo se lanzará como una biblioteca independiente (es decir, otros probablemente lo harían import foo), entonces usted (y sus usuarios posteriores) querrán tener una declaración flexible de dependencia, de modo que su biblioteca no sea (y no debe) ser “exigente” acerca de la versión exacta de SUS dependencias. Entonces, típicamente, su setup.py contendría líneas como esta:

         install_requires=[
             'A>=1,<2',
             'B>=2'
         ]
    
  • Si solo desea “documentar” o “anclar” su entorno actual EXACTO para su aplicación bar, es decir, a usted o sus usuarios les gustaría utilizar su aplicación bar tal cual, es decir, corriendo python bar.py, es posible que desee congelar su entorno para que siempre se comporte de la misma manera. En tal caso, su archivo de requisitos se vería así:

         A==1.2.3
         B==2.3.4
         # It could even contain some dependencies NOT strickly required by your library
         pylint==3.4.5
    
  1. En realidad, ¿cuál uso?

    • Si está desarrollando una aplicación bar que será utilizado por python bar.py, incluso si eso es “solo un script por diversión”, se te recomienda que uses requirements.txt porque, quién sabe, la próxima semana (que es Navidad) recibirías una computadora nueva como regalo, por lo que necesitarías configure su entorno exacto allí nuevamente.

    • Si está desarrollando una biblioteca foo que será utilizado por import foo, tienes que preparar un setup.py. Período. Pero aún puede optar por proporcionar un requirements.txt al mismo tiempo, que puede:

      (a) estar en el A==1.2.3 estilo (como se explica en el # 2 arriba);

      (b) o simplemente contener un sencillo mágico .

         .
      

      lo que equivaldría aproximadamente a “instalar los requisitos basados ​​en setup.py” sin duplicación. Personalmente, considero que este último enfoque desdibuja la línea, aumenta la confusión y NO agrega realmente valor, pero no obstante, es un truco derivado de un enfoque mencionado por el mantenedor de paquetes de Python, Donald, en su publicación de blog.

  2. Diferentes límites inferiores.

    Suponiendo que exista una engine biblioteca con este historial:

    engine 1.1.0 Use steam
    ...
    engine 1.2.0 Internal combustion is invented
    engine 1.2.1 Fix engine leaking oil
    engine 1.2.2 Fix engine overheat
    engine 1.2.3 Fix occasional engine stalling
    
    engine 2.0.0 Introducing nuclear reactor
    

    Sigue los 3 criterios anteriores y decidió correctamente que su nueva biblioteca hybrid-engine usaría un setup.py para declarar su dependencia engine>=1.2.0,<2, y luego tu aplicación separada reliable-car usaría requirements.txt para declarar su dependencia engine>=1.2.3,<2 (o puede que desee simplemente anclar engine==1.2.3). Como puede ver, su elección para su número de límite inferior sigue siendo sutilmente diferente, y ninguno de ellos usa el último engine==2.0.0. Y he aquí por qué.

    • hybrid-engine depende de engine>=1.2.0 porque, lo necesario add_fuel() API se introdujo por primera vez en engine 1.2.0, y esa capacidad es la necesidad de hybrid-engine, independientemente de si puede haber algunos errores (menores) dentro de dicha versión y se han corregido en las versiones posteriores 1.2.1, 1.2.2 y 1.2.3.

    • reliable-car depende de engine>=1.2.3 porque esa es la versión más antigua SIN problemas conocidos, hasta ahora. Seguro que hay nuevas capacidades en versiones posteriores, es decir, "reactor nuclear" introducido en engine 2.0.0, pero no son necesariamente deseables para proyectos reliable-car. (Tu otro nuevo proyecto time-machine probablemente usaría engine>=2.0.0, pero ese es un tema diferente.)

Si para ti ha resultado de utilidad este artículo, te agradeceríamos que lo compartas con el resto programadores y nos ayudes a difundir nuestra información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *