在 Windows 中导出 Flask 应用程序的环境变量

Exporting environment variables for Flask Application in Windows

我正在关注 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

中创建此 class 配置
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')

然后我运行我的应用程序,但是出现错误消息"A secret key is required to use CSRF.",所以我认为我的flask应用程序无法获取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. 我需要 add/fix 什么才能使我的应用程序正常工作?

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

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

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

设置环境变量的问题 从控制面板是一个程序来检测 这些变量的变化,它需要关闭并重新打开。 但是,当你 运行 一个程序时,它会继承环境变量 从它的父进程。所以你也需要关闭它,一直持续到 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 window, 这些环境值将被取消设置。 因此,如果您打开一个新的命令行 window,则需要重新输入它们。 或者您可以从控制面板中设置值,这些值将由新的 cmd windows 自动继承(类似于 .bashrc 文件)。

使用 .env 文件

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

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

文件夹结构:

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

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

要导入这些值,您需要对其进行解析并将其注入到应用程序环境中。 对于 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=

现在,关于您的问题:

Is setting environment variables and exporting it the same ? If not, how do I export environment variables after setting environment variables so my application can work ?

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

How is storing environment variables in .env file different from setting environment variables in Control Panel? Because when I tried to search "Edit .env file in windows" on google, results such as "adding environment variables" come up.

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

What is the difference between .bash_profile and .env file ? I ran man bash and it said .bash_profile is The personal initialization file, executed for login shells, but I do not understand whether this means it is totally different from .env file.

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