establecer una variable de entorno en virtualenv

160

Tengo un proyecto Heroku que usa variables de entorno para obtener su configuración, pero primero uso virtualenv para probar mi aplicación localmente.

¿Hay alguna manera de establecer las variables de entorno definidas en la máquina remota dentro de virtualenv?

Mahmoud Hanafy
fuente

Respuestas:

106

Actualizar

A partir del 17 de mayo de 2017, el archivo README de autoenv afirma que direnv es probablemente la mejor opción e implica que autoenv ya no se mantiene.

Vieja respuesta

Escribí autoenv para hacer exactamente esto:

https://github.com/kennethreitz/autoenv

Kenneth Reitz
fuente
12
Gif
3
Solo para tu información, parece que los .envarchivos bork construyen Heroku, al menos en mi experiencia. Así que no lo incluyas en tu repositorio. Usuario de mucho tiempo / gran fan de autoenv por cierto. Hola Kenneth, hombre.
galarant
¿Sigue siendo relevante esta respuesta después de editar? ¿Cuál es su opinión acerca de la solución sugerida por Nagasaki45 y TheLetterN
freezed
288

En caso de que esté usando virtualenvwrapper (le recomiendo hacerlo), puede definir diferentes ganchos (preactivar, postactivar, predeactivar, posdeactivar) usando los scripts con los mismos nombres $VIRTUAL_ENV/bin/. Necesita el gancho postactivate.

$ 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

Si desea mantener esta configuración en el directorio de su proyecto, simplemente cree un enlace simbólico desde su directorio de proyecto $VIRTUAL_ENV/bin/postactivate.

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

Incluso podría automatizar la creación de los enlaces simbólicos cada vez que use mkvirtualenv .

Limpieza al desactivar

Recuerde que esto no se limpiará después de sí mismo. Cuando desactive virtualenv, la variable de entorno persistirá. Para limpiar simétricamente puede agregar 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

Recuerde que si usa esto para las variables de entorno que ya podrían estar configuradas en su entorno, entonces el desarmado resultará en que estén completamente desarmadas al abandonar virtualenv. Entonces, si eso es probable, podría registrar el valor anterior en algún lugar temporal y luego volver a leerlo en desactivar.

Preparar:

$ 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

Prueba:

$ echo $SOME_VAR
banana

$ workon myenv

$ echo $SOME_VAR
apple

$ deactivate

$ echo $SOME_VAR
banana
Danilo Bargen
fuente
Solo una precisión: hacer ln -s .env/postactivate $VIRTUAL_ENV/bin/postactivateno funcionó para mí. lnquiere un camino completo, así que tuve que hacerloln -s `pwd`/.env/postactivate $VIRTUAL_ENV/bin/postactivate
Zoneur
@Zoneur ¿En qué sistema operativo estás? En Linux, las rutas relativas funcionan ln.
Danilo Bargen
@DaniloBargen Yo uso LinuxMint 3.2.0. Esta respuesta dice que lnle gustan los caminos completos, así que lo intenté y funcionó. Cuando intenté catel enlace simbólico con la ruta relativa, decía No such file or directory.
Zoneur
@dpwrussel, eso casi no pasó por la revisión, es una buena adición, pero es tan significativo que podría haberse hecho como su propia publicación (lo que le habría dado algún representante). Muchas buenas respuestas son buenas :)
Kent Fredric
2
¿Y el control de la fuente? ¿Cómo se traduce esto en la clonación de otras personas y la creación de un proyecto que necesita el medio ambiente? var.s?
CpILL
44

Tu podrías intentar:

export ENVVAR=value

en virtualenv_root / bin / generate. Básicamente, el script de activación es lo que se ejecuta cuando comienza a usar virtualenv para que pueda poner toda su personalización allí.

kgr
fuente
2
¡No estoy seguro si eso es lo suficientemente limpio pero definitivamente funciona!
chachan
2
Sí, es barato y desagradable, pero en ocasiones eso es lo que necesitas.
Michael Scheper
1
No lo recomiendo, lo hice y, en algún momento, todos los scripts de activación (activar, activar.csh, activar.pez) se sobrescribieron automáticamente, por lo que perdí mi cambio. Use postactivate y predeactivate.
wil93
no use espacios alrededor del =
Rik Schoonbeek
También podría agregar 'desarmar ENVVAR' en la deactivatefunción definida virtualenv_root / bin / activar para equilibrar la configuración y la desarmado
Lou Zell
42

Usando solo virtualenv (sin virtualenvwrapper ), configurar las variables de entorno es fácil a través del activatescript que busca para activar virtualenv.

Correr:

nano YOUR_ENV/bin/activate

Agregue las variables de entorno al final del archivo de esta manera:

export KEY=VALUE

También puede establecer un enlace similar para desarmar la variable de entorno como lo sugiere Danilo Bargen en su gran respuesta anterior si es necesario.

Nagasaki45
fuente
9
Un enfoque mucho más sensato de la OMI. anulando cdsolo para tener variables de entorno? estremecimiento
Michel Müller
¿Qué tal la limpieza después de la desactivación?
Buncis
36

Si bien hay muchas buenas respuestas aquí, no vi una solución publicada que incluya variables de entorno desestabilizadoras en la desactivación y no requiera bibliotecas adicionales más allá virtualenv, así que aquí está mi solución que solo implica editar / bin / activar, usando el variables MY_SERVER_NAMEy MY_DATABASE_URLcomo ejemplos:

Debe haber una definición para desactivar en el script de activación, y desea desarmar sus variables al final:

deactivate () {
    ...

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

Luego, al final del script de activación, configure las variables:

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

De esta manera, no tiene que instalar nada más para que funcione, y no termina con las variables que quedan cuando deactivatevirtualenv.

TheLetterN
fuente
3
Me gusta este enfoque porque no quiero aplicaciones o bibliotecas externas, pero el problema con esto es que si reconstruyes el entorno perderás toda tu configuración.
VStoykov
2
La ventaja de este enfoque es la velocidad de configuración y la falta de magia. Mantener las variables de entorno fuera del control de la fuente siempre lo llevará de regreso al problema de destruir potencialmente sus secretos / configuraciones al reconstruir entornos.
Anthony Manning-Franklin
¿El directorio virtualenv termina siendo registrado en el repositorio para que esto funcione? ¿Qué pasa si las variables contienen secretos que no quieres en el repositorio? ¿Cómo manejarías esto?
fraxture el
2
Realmente no entiendo por qué sería una buena idea incluir un virtualenv en su repositorio, ya que no son muy portátiles, pero imagino que podría colocar sus exportaciones en un archivo separado en lugar del script de activación y obtener el archivo si está presente y no agregue ese archivo a su repositorio.
TheLetterN
18

Localmente dentro de un virtualenv hay dos métodos que podría usar para probar esto. La primera es una herramienta que se instala a través del cinturón de herramientas de Heroku (https://toolbelt.heroku.com/). La herramienta es capataz. Exportará todas las variables de entorno que están almacenadas en un archivo .env localmente y luego ejecutará los procesos de la aplicación dentro de su Procfile.

La segunda forma si está buscando un enfoque más ligero es tener un archivo .env localmente y luego ejecutar:

export $(cat .env)
CraigKerstiens
fuente
6

Instalar autoenv ya sea por

$ pip install autoenv

(o)

$ brew install autoenv

Y luego cree el .envarchivo en su carpeta de proyecto virtualenv

$ echo "source bin/activate" > .env

Ahora todo funciona bien.

Fizer Khan
fuente
3

Si ya está usando Heroku, considere ejecutar su servidor a través de Foreman . Es compatible con un .envarchivo que es simplemente una lista de líneas con las KEY=VALque se exportará a su aplicación antes de que se ejecute.

Michael Mior
fuente
1

Para activar virtualenv en env directorio y exportar variables de entorno almacenadas en .envuso:

source env/bin/activate && set -a; source .env; set +a
Daniil Mashkin
fuente
guardar en alias conecho 'alias e=". env/bin/activate && set -a; source .env; set +a"' >> ~/.bash_aliases
Daniil Mashkin