Python flask中的配置
当你开始学习Flask时,配置看上去是小菜一碟。你仅仅需要在config.py定义几个变量,然后万事大吉。 然而当你不得不管理一个生产上的应用的配置时,这一切将变得棘手万分。 你不得不设法保护API密钥,或者纠结于为了不同的环境(比如开发环境和生产环境)使用不同的配置。 在本章我们将探讨Flask的一些高级特性,它们能让配置管理更为轻松。
从小处起步
一个简单的应用不需要任何复杂的配置。你仅仅需要在你的根目录下放置一个config.py文件,并在app.py或yourapp/__init__.py中加载它。
config.py的每一行中应该是某一个变量的赋值语句。一旦config.py在稍后被加载,这个配置变量可以通过app.config
字典来获取,比如app.config["DEBUG"]
。 以下是一个小项目的config.py文件的范例:
DEBUG = True # 启动Flask的Debug模式
BCRYPT_LEVEL = 13 # 配置Flask-Bcrypt拓展
MAIL_FROM_EMAIL = "robert@example.com" # 设置邮件来源
有一些配置变量是内建的,比如DEBUG
。还有些配置变量是关于Flask拓展的,比如BCPYRT_LEVEL
就是用于Flask-Bcrypt拓展(一个用于hash映射密码的拓展)。 你甚至可以定义在这个应用中用到的自己的配置变量。 在这个例子中,我使用app.config["MAIL_FROM_EMAIL"]
来表示邮件往来时(比如重置密码)默认的发送方。 这使得在将来要修改的时候不会带来太多麻烦。
为了加载这些配置变量,我通常使用app.config.from_object()
。如果是单一模块应用中,是在app.py;或者在yourapp/__init__.py,如果是基于包的应用。 无论在哪种情况下,代码看上去像这样:
from flask import Flask
app = Flask(__name__)
app.config.from_object('config')
# 现在通过app.config["VAR_NAME"],我们可以访问到对应的变量
一些重要的配置变量
变量 | 描述 | 默认值 |
---|---|---|
DEBUG | 在调试错误的时候给你一些有用的工具。比如当一个请求导致异常的发生时,会出现的一个web界面的调用堆栈和Python命令行。 | 在开发环境下应该设置成True,在生产环境下应设置为False。 |
SECRET_KEY | Flask使用这个密钥来对cookies和别的东西进行签名。你应该在instance文件夹中设定这个值,并不要把它放入版本控制中。你可以在下一节读到关于instance文件夹的更多信息。 | 这应该是一个复杂的任意值。 |
BCRYPT_LEVEL | 如果使用Flask-Bcrypt来hash映射用户密码(如果没有,现在就用它),你需要为hash密码的算法指定“rounds”的值。设置的rounds值越高,计算一次hash花费的时间就越长(同样的效果作用于破解方,这个才是重要的)。rounds的值应该随着你的设备的计算能力的提升而增加 | 如果使用Flask-Bcrypt来hash映射用户密码(如果没有,现在就用它),你需要为hash密码的算法指定“rounds”的值。设置的rounds值越高,计算一次hash花费的时间就越长(同样的效果作用于破解方,这个才是重要的)。rounds的值应该随着你的设备的计算能力的提升而增加 |
确保生产环境下已经设置了 DEBUG = False
。如果忘记关掉,用户会很乐意对你的服务器执行任意的Python代码。
instance文件夹
有时你需要定义一些不能为人所知的配置变量。为此,你会想要把它们从config.py中的其他变量分离出来,并保持在版本控制之外。 你可能要隐藏类似数据库密码和API密钥的秘密,或定义特定于当前机器的参数。 为了让这更加轻松,Flask提供了一个叫instance文件夹的特性。 instance文件夹是根目录的一个子文件夹,包括了一个特定于当前应用实例的配置文件。我们不要把它提交到版本控制中。
这是一个使用了instance文件夹的简单Flask应用的结构:
config.py
requirements.txt
run.py
instance/
config.py
yourapp/
__init__.py
models.py
views.py
templates/
static/
使用instance文件夹
要想加载定义在instance文件夹中的配置变量,你可以使用app.config.from_pyfile()
。 如果在调用Flask()
创建应用时设置了instance_relative_config=True
,app.config.from_pyfile()
将查看在instance文件夹的特殊文件。
app = Flask(__name__, instance_relative_config=True)
app.config.from_object('config')
app.config.from_pyfile('config.py')
现在,你可以在instance/config.py中定义变量,一如在config.py。 你也应该将instance文件夹加入到版本控制系统的忽略名单中。比如假设你用的是git,你需要在gitignore中新开一行,写下instance/
。
密钥
instance文件夹的隐秘属性使得它成为藏匿密钥的好地方。 你可以在放入应用的密钥或第三方的API密钥。假如你的应用是开源的,或者将会是开源的,这会很重要。我们希望其他人去使用他们自己申请的密钥。
# instance/config.py
SECRET_KEY = 'Sm9obiBTY2hyb20ga2lja3MgYXNz'
STRIPE_API_KEY = 'SmFjb2IgS2FwbGFuLU1vc3MgaXMgYSBoZXJv'
SQLALCHEMY_DATABASE_URI= \
"postgresql://user:TWljaGHFgiBCYXJ0b3N6a2lld2ljeiEh@localhost/databasename"
最小化依赖于环境的配置
如果你的生产环境和开发环境之间的差别非常小,你可以使用你的instance文件夹抹平配置上的差别。 在instance/config.py中定义的变量可以覆盖在config.py中设定的值。 你只需要在app.config.from_object()
之后才调用app.config.from_pyfile()
。 这样做的其中一个优点是你可以在不同的机器中修改你的应用的配置。你的开发版本库可能看上去像这样:
config.py
DEBUG = False
SQLALCHEMY_ECHO = False
instance/config.py
DEBUG = True
SQLALCHEMY_ECHO = True
然后在生产环境中,你将这些代码从instance/config.py中移除,它就会改用回config.py中设定的变量。
参见
- 在这里可以读到关于Flask-SQLAlchemy的配置密钥: http://pythonhosted.org/Flask-SQLAlchemy/config.html#configuration-keys
依照环境变量来配置
instance文件夹不应该在版本控制中。这意味这你将不能追踪你的instance配置。 在只有一两个变量的情况下这不是什么问题,但如果你有关于多个环境(生产,稳定,开发,等等)的一大堆配置,你不会愿意冒失去它们的风险。
Flask给我们提供了根据环境变量选择一个配置文件的能力。 这意味着我们可以在我们的版本库中有多个配置文件,并总是能根据具体环境,加载到对的那个。
当我们到了有多个配置文件共存的境况,是时候把文件都移动到config
包之下。 下面是在这样的一个版本库中大致的样子:
requirements.txt
run.py
config/
__init__.py # 空的,只是用来告诉Python它是一个包。
default.py
production.py
development.py
staging.py
instance/
config.py
yourapp/
__init__.py
models.py
views.py
static/
templates/
在我们有一些不同的配置文件的情况下,可以这样设置:
文件名 | 内容 |
---|---|
config/default.py | 默认值,适用于所有的环境或交由具体环境进行覆盖。举个例子,在config/default.py中设置DEBUG = False ,在config/development.py中设置DEBUG = True 。 |
config/development.py | 在开发环境中用到的值。这里你可以设定在localhost中用到的数据库URI链接。 |
config/production.py | 在生产环境中用到的值。这里你可以设定数据库服务器的URI链接,而不是开发环境下的本地数据库URI链接。 |
config/staging.py | 在你的开发过程中,你可能需要在一个模拟生产环境的服务器上测试你的应用。你也许会使用不一样的数据库,想要为稳定版本的应用替换掉一些配置。 |
要在不同的环境中指定所需的变量,你可以调用app.config.from_envvar()
:
# yourapp/__init__.py
app = Flask(__name__, instance_relative_config=True)
app.config.from_object('config.default')
app.config.from_pyfile('config.py') # 从instance文件夹中加载配置
app.config.from_envvar('APP_CONFIG_FILE')
app.config.from_envvar(‘APP_CONFIG_FILE’)
将加载由环境变量APP_CONFIG_FILE
指定的文件。这个环境变量的值应该是一个配置文件的绝对路径。
这个环境变量的设定方式取决于你运行你的应用的平台。如果你是在一台标准的Linux服务器上运行,你可以使用一个shell脚本来设置环境变量并运行run.py
。
start.sh
APP_CONFIG_FILE=/var/www/yourapp/config/production.py
python run.py
start.sh特定于某个环境,所以它也不能放入版本控制当中。如果你把应用托管到Heroku,你可以用Heroku提供的工具设置环境变量参数。对于其他PAAS平台也是同样的处理。
总结
- 一个简单的应用也许仅需一个配置文件:config.py
- instance文件夹可以帮助我们隐藏不愿为人所知的配置变量。
- instance文件夹可以用来改变特定环境下的程序配置。
- 应对复杂的,基于环境的配置,我们可以结合环境变量和
app.config.from_envvar()
来使用。
Python flask中的配置的更多相关文章
- windows下跑python flask,环境配置
首先声明一下,我安装的是python 2.7. 第一步:下载easy_setup.py 下载地址:https://pypi.python.org/pypi/setuptools 这个下载地址真心难找, ...
- python flask中的代码约定
在Python社区中有许多关于代码风格的约定.如果你写过一段时间Python了,那么也许对此已经有些了解. 我会简单介绍一下,同时给你一些URL链接,从中你可以找到关于这个话题的详细信息. 让我们提出 ...
- Python Flask 多环境配置
Python里取配置文件的时候,之前是使用的ini文件和python里configparser 模块: 可参考:https://www.cnblogs.com/feeland/p/4514771.ht ...
- peewee在flask中的配置
# 原文:https://blog.csdn.net/mouday/article/details/85332510 Flask的钩子函数与peewee.InterfaceError: (0, '') ...
- python Flask中html模版中如何引用css,js等资源
已有静态页面,需要将其整合到瓶的项目中,需要搞清楚, 之前的HTML中的: <link rel =“stylesheet”href =“css / framework7.ios.css”> ...
- Flask:文件配置方式实践及其中的各种问题记录
Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2, 提示: 1.请查看本文后面的“18-07-17 11:18重大纠正” ! 2.flask run命令运行时传入参数 ...
- Python Flask高级编程之RESTFul API前后端分离精讲 (网盘免费分享)
Python Flask高级编程之RESTFul API前后端分离精讲 (免费分享) 点击链接或搜索QQ号直接加群获取其它资料: 链接:https://pan.baidu.com/s/12eKrJK ...
- [python][flask] Flask 图片上传与下载例子(支持漂亮的拖拽上传)
目录 1.效果预览 2.新增逻辑概览 3.tuchuang.py 逻辑介绍 3.1 图片上传 3.2 图片合法检查 3.3 图片下载 4.__init__.py 逻辑介绍 5.upload.html ...
- windows下python+flask环境配置详细图文教程
本帖是本人在安装配置python和flask环境时所用到的资源下载及相关的教程进行了整理罗列,来方便后面的人员,省去搜索的时间.如果你在安装配置是存在问题可留言给我. 首先罗列一下python+fla ...
随机推荐
- 数值分析:Hermite多项式
http://blog.csdn.net/pipisorry/article/details/49366047 Hermite埃尔米特多项式 在数学中,埃尔米特多项式是一种经典的正交多项式族,得名于法 ...
- Linux IPC实践(5) --System V消息队列(2)
消息发送/接收API msgsnd函数 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 参数 msgid: 由ms ...
- libcoro:在c++中支持coroutine
起因 在第一个版本的libtnet开发完成之后,我一直在思考如何让异步方式的网络编程更加简单. 虽然libtnet通过c++ shared_ptr以及function等技术很大程度上面解决了异步代码编 ...
- 挖掘频繁项集之FP-Growth算法
http://blog.csdn.net/pipisorry/article/details/48918007 FP-Growth频繁项集挖掘算法(Frequent-Pattern Growth, 频 ...
- ZooKeeper 实现分布式队列
使用场景 在传统的单进程编程中,我们使用队列来存储数据结构,用来在多线程之间共享或者传递数据.在分布式环境下,同样需要一个类似单进程的组件, 用来实现跨进程.跨主机.跨网络的数据共享和数据传递.这就 ...
- “基于数据仓库的广东省高速公路一张网过渡期通行数据及异常分析系统"已被《计算机时代》录用
今天收到<计算机时代>编辑部寄来的稿件录用通知,本人撰写的论文"基于数据仓库的广东省高速公路一张网过渡期通行数据及异常分析系统",已被<计算机时代>录 ...
- 017-封装-OC笔记
学习目标 1.[了解]异常处理 2.[掌握]类方法 3.[掌握]NSString类 4.[掌握]匿名对象 5.[掌握]封装实例变量 6.[掌握]对象之间的关系 一.异常处理 什么是异常? 代码完全符合 ...
- some phrase for oral english
依我看,在我看来 I suppose that, ... As far as i'm concerned, ... As i see it, ... It seems to me that ... 1 ...
- Android官方技术文档翻译——IntelliJ 项目迁移
本文译自Android官方技术文档<Migrating from IntelliJ Projects>,原文地址:http://tools.android.com/tech-docs/ne ...
- 如何成为Android高手
要成为Android 高手并不是一件容易的事情.并不是很多人想象的 能够飞快的写出几行漂亮的代码去解决一些困难的问题 就是Android 高手了.真正的Android 高手需要考虑的问题远远不是写些漂 ...