¿Cómo personalizar un requirements.txt para múltiples entornos?

112

Tengo dos ramas, Desarrollo y Producción. Cada uno tiene dependencias, algunas de las cuales son diferentes. El desarrollo apunta a dependencias que están en desarrollo. Lo mismo ocurre con la Producción. Necesito implementar en Heroku, que espera las dependencias de cada rama en un solo archivo llamado 'requirements.txt'.

¿Cuál es la mejor forma de organizarse?

En lo que he pensado:

  • Mantenga archivos de requisitos separados, uno en cada rama (¡debe sobrevivir a las fusiones frecuentes!)
  • Dígale a Heroku qué archivo de requisitos quiero usar (¿variable de entorno?)
  • Escribir scripts de implementación (crear rama temporal, modificar el archivo de requisitos, confirmar, implementar, eliminar rama temporal)
Charles R
fuente
1
script de implementación más fácil: mantenga 2 archivos. use un enlace simbólico entre ellos.
Udy

Respuestas:

208

Puede poner en cascada sus archivos de requisitos y usar la marca "-r" para decirle a pip que incluya el contenido de un archivo dentro de otro. Puede dividir sus requisitos en una jerarquía de carpetas modular como esta:

`-- django_project_root
|-- requirements
|   |-- common.txt
|   |-- dev.txt
|   `-- prod.txt
`-- requirements.txt

El contenido de los archivos se vería así:

common.txt:

# Contains requirements common to all environments
req1==1.0
req2==1.0
req3==1.0
...

dev.txt:

# Specifies only dev-specific requirements
# But imports the common ones too
-r common.txt
dev_req==1.0
...

prod.txt:

# Same for prod...
-r common.txt
prod_req==1.0
...

Fuera de Heroku, ahora puede configurar entornos como este:

pip install -r requirements/dev.txt

o

pip install -r requirements/prod.txt

Dado que Heroku busca específicamente "requirements.txt" en la raíz del proyecto, debería reflejar prod, así:

requisitos.txt:

# Mirrors prod
-r requirements/prod.txt
Christian Abbott
fuente
2
Ignoró el problema de cómo usar archivos de requisitos separados para diferentes entornos en heroku.
Ed J
29
Creo que mi respuesta abordó eso.
Christian Abbott
1
Estaba buscando una manera de tener diferentes requisitos en Heroku para la preparación (donde quiero paquetes de depuración adicionales) y el entorno de producción (donde no necesito estos paquetes de depuración). Desafortunadamente, como dijo @EdJ, esta respuesta no aborda esto.
Antoine Pinsard
1
Podría estar malinterpretando su pregunta o tal vez su pregunta sea diferente al póster original. Pero para aclarar, el archivo requirements.txt de la rama provisional puede contener "-r requirements / staging.txt" (o similar), mientras que el de la rama prod puede contener "-r requirements / prod.txt" (ver el final de mi respuesta). Sincronice la rama adecuada con su instancia de Heroku correspondiente.
Christian Abbott
2
@SohamNavadiya Eso no es lo que pregunté. Digamos que tengo un base.txtpaquete con 3 paquetes y dev.txtcon 1 paquete (y -r base.txt). TODOS los 4 paquetes están instalados en mi entorno virtual. Ahora quiero instalar el quinto paquete y listarlo en base, NO en dev, ¿cómo lo hago? Claro, puedo instalarlo y pip freeze > base.txteso NO resuelve el problema. Luego coloca la cuarta dependencia de desarrollo en la base que no quiero.
Manan Mehta
11

Una opción viable hoy en día que no existía cuando se publicaron las preguntas y respuestas originales es usar pipenv en lugar de pip para administrar las dependencias.

Con pipenv, ya no es necesario administrar manualmente dos archivos de requisitos separados, como con pip, y en su lugar pipenv administra los paquetes de desarrollo y producción a través de interacciones en la línea de comando.

Para instalar un paquete para su uso tanto en producción como en desarrollo:

pipenv install <package>

Para instalar un paquete solo para el entorno de desarrollo:

pipenv install <package> --dev

A través de esos comandos, pipenv almacena y administra la configuración del entorno en dos archivos (Pipfile y Pipfile.lock). El paquete de compilación Python actual de Heroku admite de forma nativa pipenv y se configurará a sí mismo desde Pipfile.lock si existe en lugar de requirements.txt.

Consulte el enlace pipenv para obtener la documentación completa de la herramienta.

Christian Abbott
fuente
4
pipenv es una pérdida de tiempo. El bloqueo tarda demasiado.
nurettin
9
pipenv está roto en casi todos los aspectos. Promete mucho, pero se envía muy poco
ospider
5
@ospider Utilizo pipenv a diario y no estoy experimentando problemas tan negativos como tú y nurettin informan. Trabajando con pipenv versión 2018.10.13. Por lo tanto, roto en todos los aspectos es una declaración muy vacía.
Kwuite
1
@Kwuite Comparto el sentimiento de tu última frase. Hay poco diálogo para entablar cuando un comentario es crítico pero vacío.
Christian Abbott
3
De acuerdo con nurettin y ospider. pipenv es horrible.
Andrew Palmer
3

Si su requisito es poder cambiar entre entornos en la misma máquina, puede ser necesario crear diferentes carpetas virtualenv para cada entorno al que necesite cambiar.

python3 -m venv venv_dev
source venv_dev/bin/activate
pip install -r pip/common.txt
pip install -r pip/dev.txt
exit
python3 -m venv venv_prod
source venv_prod/bin/activate
pip install -r pip/common.txt
exit
source venv_dev/bin/activate
# now we are in dev environment so your code editor and build systems will work.

# let's install a new dev package:
# pip install awesome
# pip freeze -r pip/temp.txt
# find that package, put it into pip/dev.txt
# rm pip/temp.txt

# pretty cumbersome, but it works. 
nurettin
fuente