configurando uma variável de ambiente no virtualenv

160

Eu tenho um projeto Heroku que usa variáveis ​​de ambiente para obter sua configuração, mas eu uso o virtualenv para testar meu aplicativo localmente primeiro.

Existe uma maneira de definir as variáveis ​​de ambiente definidas na máquina remota dentro do virtualenv?

Mahmoud Hanafy
fonte

Respostas:

106

Atualizar

A partir de 17 de maio de 2017, o README da autoenv indica que o direnv é provavelmente a melhor opção e implica que o autoenv não é mais mantido.

Resposta antiga

Eu escrevi autoenv para fazer exatamente isso:

https://github.com/kennethreitz/autoenv

Kenneth Reitz
fonte
12
Gif muito engraçado: D
chachan
3
Apenas para sua informação, parece que os .envarquivos que o Heroku constrói, pelo menos na minha experiência. Portanto, não o inclua no seu repositório. Usuário de longa data / grande fã de autoenv btw. Olá Kenneth, você é cara!
galarant
Esta resposta ainda é relevante após a edição? Qual é a sua opinião sobre a solução sugerida por Nagasaki45 & TheLetterN
freezed
288

Caso esteja usando o virtualenvwrapper (eu recomendo isso), você pode definir diferentes ganchos (pré-ativar, pós-ativar, pré-ativar, pós-desativar) usando os scripts com os mesmos nomes em $VIRTUAL_ENV/bin/. Você precisa do gancho pós-ativo.

$ workon myvenv

$ cat $VIRTUAL_ENV/bin/postactivate
#!/bin/bash
# This hook is run after this virtualenv is activated.
export DJANGO_DEBUG=True
export S3_KEY=mykey
export S3_SECRET=mysecret

$ echo $DJANGO_DEBUG
True

Se você deseja manter essa configuração no diretório do projeto, basta criar um link simbólico do diretório do projeto para $VIRTUAL_ENV/bin/postactivate.

$ rm $VIRTUAL_ENV/bin/postactivate
$ ln -s .env/postactivate $VIRTUAL_ENV/bin/postactivate

Você pode até automatizar a criação dos links simbólicos toda vez que usar mkvirtualenv .

Limpando e desativando

Lembre-se de que isso não será limpo depois de si. Quando você desativa o virtualenv, a variável de ambiente persiste. Para limpar simetricamente, você pode adicionar a $VIRTUAL_ENV/bin/predeactivate.

$ cat $VIRTUAL_ENV/bin/predeactivate
#!/bin/bash
# This hook is run before this virtualenv is deactivated.
unset DJANGO_DEBUG

$ deactivate

$ echo $DJANGO_DEBUG

Lembre-se de que, se estiver usando isso para variáveis ​​de ambiente que já podem estar configuradas em seu ambiente, a desativação resultará na desativação completa da saída da virtualenv. Portanto, se é provável que você possa registrar o valor anterior em algum lugar temporário, leia-o novamente em desativar.

Configuração:

$ cat $VIRTUAL_ENV/bin/postactivate
#!/bin/bash
# This hook is run after this virtualenv is activated.
if [[ -n $SOME_VAR ]]
then
    export SOME_VAR_BACKUP=$SOME_VAR
fi
export SOME_VAR=apple

$ cat $VIRTUAL_ENV/bin/predeactivate
#!/bin/bash
# This hook is run before this virtualenv is deactivated.
if [[ -n $SOME_VAR_BACKUP ]]
then
    export SOME_VAR=$SOME_VAR_BACKUP
    unset SOME_VAR_BACKUP
else
    unset SOME_VAR
fi

Teste:

$ echo $SOME_VAR
banana

$ workon myenv

$ echo $SOME_VAR
apple

$ deactivate

$ echo $SOME_VAR
banana
Danilo Bargen
fonte
Apenas uma precisão: fazer ln -s .env/postactivate $VIRTUAL_ENV/bin/postactivatenão funcionou para mim. lnquer um caminho completo, então eu tinha que fazerln -s `pwd`/.env/postactivate $VIRTUAL_ENV/bin/postactivate
Zoneur
@Zoneur Em que SO você está? No Linux, os caminhos relativos funcionam ln.
precisa saber é o seguinte
@DaniloBargen Eu uso o LinuxMint 3.2.0. Essa resposta dizia que lngosta de caminhos completos, então eu tentei e funcionou. Quando tentei cato link simbólico com o caminho relativo, ele disse No such file or directory.
Zoneur
@dpwrussel, que quase não passou pela revisão, é um bom complemento, mas é tão significativo que poderia ter sido feito como seu próprio post (o que lhe daria algum representante). Muitas boas respostas são bons :)
Kent Fredric
2
E controle de origem? Como isso se traduz em outras pessoas clonando e criando um projeto que precisa do ambiente. var.s?
CpILL 14/09/16
44

Você poderia tentar:

export ENVVAR=value

em virtualenv_root / bin / activar. Basicamente, o script de ativação é o que é executado quando você começa a usar o virtualenv, para que possa colocar toda a sua personalização lá.

kgr
fonte
2
Não tenho certeza se isso é limpo o suficiente, mas definitivamente funciona!
chachan
2
Sim, é barato e desagradável, mas ocasionalmente é disso que você precisa.
quer
1
Eu não recomendo isso, fiz isso e, algum tempo depois, todos os scripts de ativação (ativar, ativar.csh, ativar.fish) foram substituídos automaticamente, então perdi minha alteração. Use pós-ativo e pré-ativo.
Wil93 4/10
não use espaços ao redor do =
Rik Schoonbeek
Também pode adicionar 'ENVVAR não definido' na deactivatefunção definida virtualenv_root / bin / activar para equilibrar a definição e a definição
Lou Zell
42

Usando apenas virtualenv (sem virtualenvwrapper ), é fácil definir variáveis ​​de ambiente através do activatescript que você utiliza para ativar o virtualenv.

Corre:

nano YOUR_ENV/bin/activate

Adicione as variáveis ​​de ambiente ao final do arquivo, assim:

export KEY=VALUE

Você também pode definir um gancho semelhante para desabilitar a variável de ambiente, conforme sugerido por Danilo Bargen em sua excelente resposta acima, se necessário.

Nagasaki45
fonte
9
uma abordagem muito mais sã IMO. substituindo cdapenas para ter variáveis ​​de ambiente? arrepio
Michel Müller
que tal a limpeza após desativada?
buncis 03/02
36

Embora haja muitas respostas legais aqui, não vi uma solução publicada que inclua a desativação de variáveis ​​de ambiente na desativação e não exija bibliotecas adicionais além virtualenv, então aqui está minha solução que envolve apenas editar / bin / ativar, usando o variáveis MY_SERVER_NAMEe MY_DATABASE_URLcomo exemplos:

Deve haver uma definição para desativar no script de ativação, e você deseja desmarcar suas variáveis ​​no final dele:

deactivate () {
    ...

    # Unset My Server's variables
    unset MY_SERVER_NAME
    unset MY_DATABASE_URL
}

Em seguida, no final do script de ativação, defina as variáveis:

# Set My Server's variables
export MY_SERVER_NAME="<domain for My Server>"
export MY_DATABASE_URL="<url for database>"

Dessa forma, você não precisa instalar mais nada para fazê-lo funcionar e não acaba com as variáveis ​​que sobraram quando deactivateo virtualenv.

TheLetterN
fonte
3
Eu gosto dessa abordagem porque não quero libs ou aplicativos externos, mas o problema é que, se você reconstruir o ambiente, perderá todas as suas configurações.
VStoykov 8/16 '15
2
A vantagem dessa abordagem é a velocidade da configuração e a falta de mágica. Manter as variáveis ​​de ambiente fora do controle de origem sempre o levará de volta ao problema de potencialmente destruir seus segredos / configurações ao reconstruir ambientes.
Anthony Manning-Franklin
O diretório virtualenv acaba sendo verificado no repositório para que isso funcione? E se as variáveis ​​guardarem segredos que você não deseja no repositório? Como você lidaria com isto?
fraxture
2
Realmente não vejo por que seria uma boa idéia incluir uma virtualenv em seu repositório, pois elas não são muito portáteis, mas imagino que você possa colocar suas exportações em um arquivo separado em vez do script de ativação e originar o arquivo se está presente e não adicione esse arquivo ao seu repositório.
TheLetterN
18

Localmente em um virtualenv, existem dois métodos que você pode usar para testar isso. A primeira é uma ferramenta instalada através do cinto de ferramentas Heroku (https://toolbelt.heroku.com/). A ferramenta é capataz. Ele exportará todas as variáveis ​​de ambiente armazenadas em um arquivo .env localmente e, em seguida, executará os processos do aplicativo no seu Procfile.

A segunda maneira, se você estiver procurando uma abordagem mais leve, é ter um arquivo .env localmente e executar:

export $(cat .env)
CraigKerstiens
fonte
6

Instale o autoenv por

$ pip install autoenv

(ou)

$ brew install autoenv

E, em seguida, crie um .envarquivo na pasta do projeto virtualenv

$ echo "source bin/activate" > .env

Agora tudo funciona bem.

Fizer Khan
fonte
3

Se você já usa o Heroku, considere executar o servidor via Foreman . Ele suporta um .envarquivo que é simplesmente uma lista de linhas KEY=VALque serão exportadas para o seu aplicativo antes da execução.

Michael Mior
fonte
1

Para ativar o virtualenv no envdiretório e exportar variáveis ​​de ambiente armazenadas em .envuso:

source env/bin/activate && set -a; source .env; set +a
Daniil Mashkin
fonte
salvar em pseudônimos comecho 'alias e=". env/bin/activate && set -a; source .env; set +a"' >> ~/.bash_aliases
Daniil Mashkin 13/01