Como personalizar um requirements.txt para vários ambientes?

111

Tenho duas filiais, Desenvolvimento e Produção. Cada um possui dependências, algumas das quais são diferentes. O desenvolvimento aponta para dependências que estão em desenvolvimento. Da mesma forma para a produção. Eu preciso implantar no Heroku, que espera as dependências de cada branch em um único arquivo chamado 'requirements.txt'.

Qual a melhor forma de se organizar?

O que eu pensei:

  • Manter arquivos de requisitos separados, um em cada ramo (deve sobreviver a fusões frequentes!)
  • Diga ao Heroku qual arquivo de requisitos eu desejo usar (variável de ambiente?)
  • Escrever scripts de implantação (criar ramificação temporária, modificar arquivo de requisitos, confirmar, implementar, excluir ramificação temporária)
Charles R
fonte
1
script de implantação mais fácil: mantenha 2 arquivos. use link simbólico entre eles.
Udy

Respostas:

205

Você pode colocar seus arquivos de requisitos em cascata e usar o sinalizador "-r" para dizer ao pip para incluir o conteúdo de um arquivo dentro de outro. Você pode dividir seus requisitos em uma hierarquia de pastas modular como esta:

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

O conteúdo dos arquivos ficaria assim:

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
...

Fora do Heroku, agora você pode configurar ambientes como este:

pip install -r requirements/dev.txt

ou

pip install -r requirements/prod.txt

Como o Heroku procura especificamente por "requirements.txt" na raiz do projeto, ele deve apenas espelhar o produto, assim:

requisitos.txt:

# Mirrors prod
-r requirements/prod.txt
Christian Abbott
fonte
2
Você ignorou o problema de como usar arquivos de requisitos separados para ambientes diferentes no heroku.
Ed J de
29
Eu acredito que minha resposta abordou isso.
Christian Abbott
1
Eu estava procurando uma maneira de ter requisitos diferentes no Heroku para teste (onde quero pacotes de depuração adicionais) e ambiente de produção (onde não preciso desses pacotes de depuração). Infelizmente, como @EdJ disse, esta resposta não aborda isso.
Antoine Pinsard
1
Posso não ter entendido sua pergunta ou talvez sua pergunta seja diferente do autor do pôster original. Mas para esclarecimento, o requirements.txt do branch de teste pode conter "-r requirements / staging.txt" (ou similar), enquanto o do branch prod pode conter "-r requirements / prod.txt" (veja o final da minha resposta). Sincronize o branch apropriado com sua instância Heroku correspondente.
Christian Abbott
2
@SohamNavadiya Não foi isso que perguntei. Digamos que eu tenha um base.txtcom 3 pacotes nele e dev.txtcom 1 pacote nele (e -r base.txt). TODOS os 4 pacotes estão instalados em meu ambiente virtual. Quero agora instalar o 5º pacote e listá-lo na base, NÃO no dev, como faço isso? Claro, posso instalá-lo, pip freeze > base.txtmas isso NÃO resolve o problema. Em seguida, ele coloca a 4ª dependência de desenvolvimento na base que eu não quero.
Manan Mehta
10

Uma opção viável hoje, que não existia quando a pergunta e resposta original foram postadas, é usar pipenv em vez de pip para gerenciar dependências.

Com o pipenv, o gerenciamento manual de dois arquivos de requisitos separados como com o pip não é mais necessário e, em vez disso, o pipenv gerencia os pacotes de desenvolvimento e produção por meio de interações na linha de comando.

Para instalar um pacote para uso em produção e desenvolvimento:

pipenv install <package>

Para instalar um pacote apenas para o ambiente de desenvolvimento:

pipenv install <package> --dev

Por meio desses comandos, o pipenv armazena e gerencia a configuração do ambiente em dois arquivos (Pipfile e Pipfile.lock). O buildpack atual do Python do Heroku suporta nativamente pipenv e irá se configurar a partir de Pipfile.lock se ele existir em vez de requirements.txt.

Consulte o link pipenv para obter a documentação completa da ferramenta.

Christian Abbott
fonte
4
pipenv é uma perda de tempo. O bloqueio demora muito.
nurettin
9
pipenv está quebrado em quase todos os aspectos. Ele promete muito, mas vem muito pouco
ospider
4
@ospider Estou usando pipenv diariamente e não estou enfrentando os problemas negativos que você e nurettin estão relatando. Trabalhar com pipenv versão 2018.10.13. Quebrado em todos os aspectos é, portanto, uma declaração muito vazia.
Kwuite
1
@Kwuite Eu compartilho o sentimento de sua última frase. Há pouco diálogo para se envolver quando um comentário é crítico, mas vazio.
Christian Abbott de
3
Concordo com nurettin e ospider. pipenv é horrível.
Andrew Palmer
3

Se o seu requisito é ser capaz de alternar entre ambientes na mesma máquina, pode ser necessário criar diferentes pastas virtualenv para cada ambiente para o qual você precisa alternar.

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
fonte