【问题标题】:Exporting environment variables for Flask Application in Windows在 Windows 中为 Flask 应用程序导出环境变量
【发布时间】:2019-11-25 13:33:34
【问题描述】:

我正在关注一个 Youtube 教程全功能 Web 应用程序,但我遇到了应用程序工厂问题。根据我的理解,我需要将 SECRET_KEY 和 SQLALCHEMY_DATABASE_URI 等敏感信息放入环境变量中。在视频中,创作者在 Mac 上工作,他打开了他的 .bash_profile 文件并添加了这些行(我将真实值留空):

export SECRET_KEY='....'
export SQLALCHEMY_DATABASE_URI='......'

我正在使用 Windows,但在我的计算机中找不到 .bash_profile 文件,因此我转到控制面板并设置新的环境变量 SECRET_KEY 和 SQLALCHEMY_DATABASE_URI。然后我通过在 config.py 中创建此类 Config 来继续视频中的操作

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY')
    SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI')
    MAIL_SERVER = 'smtp.gmail.com'
    MAIL_PORT = 587
    MAIL_USE_TLS = True
    MAIL_USERNAME = os.environ.get('EMAIL_USER')
    MAIL_PASSWORD = os.environ.get('EMAIL_PASSWORD')

然后我运行我的应用程序,但出现了错误消息“使用 CSRF 需要密钥”,所以我认为我的烧瓶应用程序无法获取我设置的 SECRET_KEY 或其他环境变量。在我的 init.py 中有这些配置之前,应用程序运行良好,但现在当我将这些配置移动到 config.py 中的对象内部时,它停止工作。

根据我的理解,export 是一个创建环境变量的命令,所以我认为将这些变量导出到 .bash_profile 文件中等于设置环境变量。

为了解决我的问题,我尝试按照教程 (https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xv-a-better-application-structure) 创建 .env 文件。在命令提示符下,我跑了

 pip install python-dotenv

在 Config.py 中,我添加了

from dotenv import load_dotenv

basedir = os.path.abspath(os.path.dirname(__file__))
load_dotenv(os.path.join(basedir, '.env'))

我认为这会创建一个 .env 文件,我可以在其中存储我的环境变量,但它什么也没做,而且我没有在我的目录中看到任何 .env 文件。有人可以帮帮我吗 ?我有几个问题:

  1. 我需要添加/修复什么才能使我的应用程序正常工作?

  2. 设置环境变量和导出环境变量一样吗?如果没有,我如何在设置环境变量后导出环境变量以便我的应用程序可以工作?

  3. 在 .env 文件中存储环境变量与在控制面板中设置环境变量有何不同?因为当我尝试在 google 上搜索“Edit .env file in windows”时,会出现“添加环境变量”之类的结果。

  4. .bash_profile 和 .env 文件有什么区别?我跑了man bash,它说.bash_profile 是The personal initialization file, executed for login shells,但我不明白这是否意味着它与.env 文件完全不同。

【问题讨论】:

  • 不,您自己创建.env 文件并在单独的行中填写KEY=value
  • 嗨!谢谢你的评论。我想知道这是否与设置环境变量相同?我在谷歌的任何地方都找不到创建 .env 文件的教程。谢谢
  • 并不完全一样,但实际上如此。我会在一分钟内为你写一个更详细的答案。

标签: python flask environment-variables factory


【解决方案1】:

设置环境变量的问题 从控制面板是程序检测 这些变量的变化,需要关闭和重新打开。 但是,当您运行程序时,它会继承环境变量 从它的父进程。所以你也需要关闭它,一直到explorer.exe。所以有点棘手。

所以你需要采用不同的方法。

1.从命令行设置环境变量:

您可以为命令行会话设置环境变量 在 cmd 上使用 set 命令(或在 PowerShell 上使用 $env 全局) (export 在 Windows 上不存在)。

# cmd
set "SECRET_KEY=s3cr3t"

# powershell
$env:SECRET_KEY = 's3cr3t';

然后检查是否真的设置好了:

# cmd
echo %SECRET_KEY%

# powershell
$env:SECRET_KEY

应该打印s3cr3t。或者你可以直接使用set 不带任何参数的命令,它会打印所有的环境变量。

以这种方式设置所有环境变量后,您将运行您的应用程序:

# app.py
from flask import Flask
import config

app = Flask(__name__)
@app.route('/')
def home():
    return 'secret is ' + config.SECRET_KEY

app.run()
# config.py
from os import getenv

SECRET_KEY = getenv('SECRET_KEY', None)
assert SECRET_KEY  # make sure app doesn't run without this value

# use the key
print(SECRET_KEY)

运行它:

python config.py

输出:

s3cr3t

现在您可以从其他文件中导入config.py

需要注意的一点是,一旦你关闭了那个 cmd 窗口, 这些环境值将未设置。 因此,如果您打开一个新的命令行窗口,您需要重新输入它们。 或者您可以在控制面板中设置值,然后新的 cmd 窗口会自动继承这些值(类似于.bashrc 文件)。

使用.env文件

另一种方法是在项目的根文件夹中创建一个.env 文件, 这是一个像这样格式化的文本文件

SECRET_KEY=s3cr3t
SQLALCHEMY_DATABASE_URI=sqlite:///app.db

文件夹结构:

.
├── .env
├── config.py
├── app.py

您不应将这些.env 文件与其他源文件一起提交和共享。 因为那在源代码中不硬编码配置有什么意义,对吧?

要导入这些值,您需要对其进行解析并将其注入应用环境。 对于 Python,您可以使用 python-dotenv 库。

现在我们可以把config.py改成:

# config.py
from os import getenv

from dotenv import load_dotenv

load_dotenv()

SECRET_KEY = getenv('SECRET_KEY', None)
assert SECRET_KEY

# use the key
print(SECRET_KEY)

这将允许我们从.env 文件中加载配置 以及来自环境变量。

一种常见的模式是创建一个带有未填充键的.env.sample 文件,以提醒管理员正在设置应用程序以填充这些值。

# .env.sample
SECRET_KEY=
SQLALCHEMY_DATABASE_URI=

现在,至于你的问题:

正在设置环境变量并导出它 相同 ?如果没有,我如何导出环境变量 设置环境变量后,我的应用程序就可以工作了吗?

“导出”环境变量与从控制面板设置它们相同。 两者都是从源代码中删除秘密的方法。我已经在上面解释了使您的应用程序正常运行的两种方法。

在 .env 文件中存储环境变量与在控制面板中设置环境变量有何不同?因为当我尝试在google上搜索“Edit .env file in windows”时,会出现“添加环境变量”之类的结果。

.env文件中存储环境变量有点容易出错,因为伴随着一个小的服务器配置错误, 你可能会将这些秘密公开给所有人看。 通过使用set/export 设置它们,您可以关闭该漏洞(如果黑客设法接管您的应用程序,他仍然可以获得这些漏洞,因为如果您注意到我们可以使用带有getenv 功能的应用程序访问它)。

.bash_profile 和 .env 文件有什么区别?我跑了 man bash ,它说 .bash_profile 是个人初始化文件,为登录 shell 执行,但我不明白这是否意味着它与 .env 文件完全不同。

Bash 是 UNIX 系统中流行的 shell 应用程序。 .bashrc 是每次打开终端时都会执行的文件。 因此,当您向其中添加 export ENV_VAR=value 命令时,您打开的每个终端实际上​​都已经设置了这些环境变量。

【讨论】:

  • 非常感谢!!我遵循第一种方式,我的应用程序再次工作。当您说从控制面板设置环境变量时,我的程序需要关闭并重新打开“,请问这是否仅限于我在Config对象中有这些配置时的场景?因为之前当我有这些配置时init.py,我可以写os.environ.get()来获取我设置的环境变量。另外,请问这种情况下的父进程是什么?谢谢!!
  • 如果你从开始菜单运行命令行,那么explorer.exe是你的父进程,如果它来自你的编辑器(如VS Code),那么它是vscode.exe,如果它来自PyCharm,然后是pycharm.exe。你明白了。如果父程序不监听更改事件,您需要关闭/重新打开将运行您的应用程序python app.py 的程序(即命令行窗口),以让它从环境中读取更新的值。 serverfault.com/questions/8855/…
猜你喜欢
  • 2015-04-27
  • 2017-03-31
  • 2020-02-13
  • 2015-04-26
  • 2017-05-17
  • 1970-01-01
  • 2019-03-25
  • 1970-01-01
  • 2012-06-03
相关资源
最近更新 更多