在virtualenv中设置环境变量

Mah*_*sam 149 python heroku environment-variables virtualenv

我有一个Heroku项目,它使用环境变量来获取其配置,但我使用virtualenv首先在本地测试我的应用程序.

有没有办法在virtualenv中设置远程机器上定义的环境变量?

Dan*_*gen 285

如果您正在使用virtualenvwrapper(我强烈建议这样做),您可以使用具有相同名称的脚本定义不同的挂钩(preactivate,postactivate,predeactivate,postdeactivate)$VIRTUAL_ENV/bin/.你需要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
Run Code Online (Sandbox Code Playgroud)

如果要将此配置保留在项目目录中,只需从项目目录创建符号链接即可$VIRTUAL_ENV/bin/postactivate.

$ rm $VIRTUAL_ENV/bin/postactivate
$ ln -s .env/postactivate $VIRTUAL_ENV/bin/postactivate
Run Code Online (Sandbox Code Playgroud)

每次使用mkvirtualenv时,您甚至可以自动创建符号链接.

在停用时清理

请记住,这不会自行清理.停用virtualenv时,环境变量将保持不变.要对称清理,您可以添加$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
Run Code Online (Sandbox Code Playgroud)

请记住,如果将此用于可能已在您的环境中设置的环境变量,则取消设置将导致它们在离开virtualenv时完全取消设置.因此,如果完全可能,您可以在某处临时记录先前的值,然后在停用时将其读回.

建立:

$ 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
Run Code Online (Sandbox Code Playgroud)

测试:

$ echo $SOME_VAR
banana

$ workon myenv

$ echo $SOME_VAR
apple

$ deactivate

$ echo $SOME_VAR
banana
Run Code Online (Sandbox Code Playgroud)

  • 和源代码控制?这如何转化为其他人克隆和建立需要环境的项目.var.s? (2认同)

Ken*_*itz 101

更新

截至2017年5月17日,autoenv的README声明direnv可能是更好的选择,并暗示不再维护autoenv.

老答案

我写了autoenv来做到这一点:

https://github.com/kennethreitz/autoenv

  • 非常有趣的GIF:D (12认同)
  • 仅供参考,似乎`.env`文件bork Heroku构建,至少在我的经验中.所以不要将它包含在您的仓库中.长期用户/ autoenv btw的巨大粉丝.嗨肯尼斯,你这个男人! (3认同)

kgr*_*kgr 40

你可以尝试:

export ENVVAR=value
Run Code Online (Sandbox Code Playgroud)

在virtualenv_root/bin/activate中.基本上,激活脚本是您开始使用virtualenv时执行的操作,因此您可以将所有自定义放在那里.

  • 不确定这是否足够干净但最终确实有效! (2认同)
  • 是的,它既便宜又讨厌,但偶尔这就是你所需要的. (2认同)
  • 我不推荐这个,我这样做了,后来所有激活脚本(激活、激活.csh、激活.fish)都被自动覆盖,所以我丢失了我的更改。使用 postactivate 和 predeactivate。 (2认同)
  • 还可以在 virtualenv_root/bin/activate 定义的“deactivate”函数中添加“unset ENVVAR”以平衡设置和取消设置 (2认同)

Nag*_*i45 36

仅使用virtualenv(不使用virtualenvwrapper),通过activate您采购的脚本轻松设置环境变量以激活virtualenv.

跑:

nano YOUR_ENV/bin/activate
Run Code Online (Sandbox Code Playgroud)

将环境变量添加到文件末尾,如下所示:

export KEY=VALUE
Run Code Online (Sandbox Code Playgroud)

如果需要,你也可以设置一个类似的钩子来解开环境变量,如Danilo Bargen在上面的答案中所建议的那样.

  • 一个更理智的方法IMO.覆盖`cd`只是为了拥有环境变量?*不寒而栗* (9认同)
  • 停用后清理怎么样? (6认同)
  • 这可行,但对我来说,在 Windows 上它是“YOUR_ENV/Scripts/activate.bat”和“set KEY=VALUE”。 (3认同)
  • 感谢 @RiversCuomo 提供 Windows 特定信息!将其添加到答案中。 (2认同)

The*_*erN 28

虽然这里有很多很好的答案,但我没有看到一个解决方案,它既包括取消激活时未设置的环境变量,也不需要额外的库virtualenv,所以这里的解决方案只涉及编辑/ bin/activate,使用变量MY_SERVER_NAMEMY_DATABASE_URL例子:

激活脚本中应该有停用的定义,并且您希望在其末尾取消设置变量:

deactivate () {
    ...

    # Unset My Server's variables
    unset MY_SERVER_NAME
    unset MY_DATABASE_URL
}
Run Code Online (Sandbox Code Playgroud)

然后在激活脚本的末尾,设置变量:

# Set My Server's variables
export MY_SERVER_NAME="<domain for My Server>"
export MY_DATABASE_URL="<url for database>"
Run Code Online (Sandbox Code Playgroud)

这样你就不需要安装其他任何东西来使它工作,并且当你deactivate使用virtualenv 时,你最终不会留下变量.

  • 我喜欢这种方法,因为我不想要外部库或应用程序,但问题是,如果重建环境,您将失去所有设置. (3认同)
  • 这种方法的优点是设置速度快,缺乏魔力.将环境变量保持在源代码管理之外将始终引导您回到在重建环境时可能破坏您的机密/设置的问题. (2认同)
  • 我真的不明白为什么在您的存储库中包含virtualenv是个好主意,因为它们不是很可移植,但是我想您可以将导出文件放在一个单独的文件中,而不是将其激活脚本并在以下情况下获取文件的源它存在,并且不要将该文件添加到您的存储库中。 (2认同)

Cra*_*ens 17

在virtualenv中,您可以使用两种方法来测试它.第一个是通过Heroku工具带(https://toolbelt.heroku.com/)安装的工具.该工具是领班.它将导出本地存储在.env文件中的所有环境变量,然后在Procfile中运行app进程.

第二种方法,如果你正在寻找一个更轻的方法是在本地有一个.env文件然后运行:

export $(cat .env)
Run Code Online (Sandbox Code Playgroud)


Dan*_*kin 8

要在env目录中激活 virtualenv并导出存储在.env使用中的环境变量:

source env/bin/activate && set -a; source .env; set +a
Run Code Online (Sandbox Code Playgroud)

或者只是以下行pyenv

set -a; source .env; set +a
Run Code Online (Sandbox Code Playgroud)

  • 你能解释一下“set +a”吗? (2认同)

Grz*_*orz 8

关于标准venv包,这里有一个解决方案:

  • 在激活时设置更新环境变量。
  • 停用时恢复环境变量的先前值。

解决方案

  1. 创建 MY_ENV 环境。
python -m venv MY_ENV
Run Code Online (Sandbox Code Playgroud)
  1. 在任何文本编辑器(例如 vim)中打开activate脚本。
vim MY_ENV/bin/activate
Run Code Online (Sandbox Code Playgroud)
  1. 更新函数体deactivate

当您停用虚拟环境时,将执行这些行。他们恢复了之前的值ENV_VARIABLE

deactivate () {
    ... # Already existing code

    # Restore the previous value of the ENV_VARIABLE on deactivation
    # This code is executed when `deactivate` alias is called.
    if [ ! "${1:-}" = "nondestructive" ] ; then
        if [ -n "${_OLD_ENV_VARIABLE:-}" ] ; then
            ENV_VARIABLE="${_OLD_ENV_VARIABLE:-}"
            export ENV_VARIABLE
            unset _OLD_ENV_VARIABLE
        else
            unset ENV_VARIABLE
        fi
    fi

}
Run Code Online (Sandbox Code Playgroud)
  1. 在脚本末尾添加行,您可以在其中定义"new value of the ENV_VARIABLE".

当您激活虚拟环境时,将执行这些行。

# Update or set a ENV_VARIABLE on activation
if [ -n "${ENV_VARIABLE:-}" ] ; then
    _OLD_ENV_VARIABLE="${ENV_VARIABLE:-}"
fi
export ENV_VARIABLE="new value of the ENV_VARIABLE"

Run Code Online (Sandbox Code Playgroud)
  1. 保存并关闭文件。

结果

设置新环境变量的结果:

:~$ echo $ENV_VARIABLE

:~$

:~$ source MY_ENV/bin/activate
(MY_ENV):~$

(MY_ENV):~$ echo $ENV_VARIABLE
new value of the ENV_VARIABLE
:~$

(MY_ENV):~$ deactivate
:~$

:~$ echo $ENV_VARIABLE

:~$


Run Code Online (Sandbox Code Playgroud)

更新现有环境变量的结果:

:~$ export ENV_VARIABLE = "old value of the ENV_VARIABLE"
:~$

:~$ echo $ENV_VARIABLE
old value of the ENV_VARIABLE
:~$

:~$ source MY_ENV/bin/activate
(MY_ENV):~$

(MY_ENV):~$ echo $ENV_VARIABLE
new value of the ENV_VARIABLE
:~$

(MY_ENV):~$ deactivate
:~$

:~$ echo $ENV_VARIABLE
old value of the ENV_VARIABLE
:~$

Run Code Online (Sandbox Code Playgroud)

  • 这是唯一使用现代 venv 的答案,并且应该是正确的答案。其他答案已经过时了。venv 创建的虚拟环境中不存在 postactivate 和 predeactivate 挂钩。 (2认同)

Fiz*_*han 6

安装autoenv

$ pip install autoenv
Run Code Online (Sandbox Code Playgroud)

(要么)

$ brew install autoenv
Run Code Online (Sandbox Code Playgroud)

然后.env在virtualenv项目文件夹中创建文件

$ echo "source bin/activate" > .env
Run Code Online (Sandbox Code Playgroud)

现在一切正常.