配置处理¶
New in version 0.3.
应用程序需要某种形式的配置。你可能会需要根据应用环境更改不同的设置,比如开关调试模式、 设置密钥、或是别的设定环境的东西。
Flask 被设计为需要配置来启动应用。你可以在代码中硬编码配置,这对于小的应用并不坏,但是有更好的方法。
跟你如何加载配置无关,有一个配置对象用来维持加载的配置值:Flask
对象的 config
属性。
这是Flask自身放置特定配置的地方同时也是扩展放置它们配置值的地方。但是,这里也可以放置你自己的配置。
基本配置¶
config
实际上是字典的一个子类且能够像字典一样被修改:
app = Flask(__name__)
app.config['DEBUG'] = True
某些配置也被传入到 Flask
对象因此你可以在那里读取它们:
app.debug = True
你能够用 dict.update()
方法一次性地更新多个键值:
app.config.update(
DEBUG=True,
SECRET_KEY='...'
)
内置的配置值¶
下列配置值是 Flask 内部使用的:
|
启用/禁止调试模式 |
|
启用/禁止测试模式 |
|
显式地启用或者禁止异常的传播。 如果没有设置 或显式地设置为 None , 当 TESTING 或 DEBUG 为真时, 隐式为真。 |
|
默认情况下,如果应用工作在调试模式, 请求上下文不会在异常时出栈来允许调试器内省。 这可以通过这个键来禁用。 你同样可以用这个设定来强制启用它, 即使没有调试执行,这对调试生产应用很有用 (但风险也很大) |
|
密钥 |
|
会话 cookie 的名称 |
|
会话 cookie 的域。如果没有设置的话,
cookie 将会对 |
|
会话 cookie 的路径。如果没有设置或者没有为 |
|
控制 cookie 是否应被设置 httponly 的标志, 默认为 True 。 |
|
控制 cookie 是否应被设置安全标志,默认为 False。 |
|
一个持久化的会话的生存时间,作为一个
|
|
启用/禁止 x-sendfile |
|
日志记录器的名称 |
|
服务器的名称以及端口,需要它为了支持子域名
(如: |
|
如果应用不占用完整的域名或子域名,
这个选项可以被设置为应用所在的路径。
这个路径也会用于会话 cookie 的路径值。
如果直接使用域名,则留作 |
|
如果设置为字节数, Flask 会拒绝内容长度大于 此值的请求进入,并返回一个 413 状态码。 |
|
默认缓存控制的最大期限,以秒计,
在 |
|
如果这个值被设置为 |
|
Werkzeug 处理请求中的特定数据的内部数据结构会
抛出同样也是“错误的请求”异常的特殊的 key errors 。
同样地,为了保持一致,许多操作可以
显式地抛出 BadRequest 异常。因为在调试中,
你希望准确地找出异常的原因,
这个设置用于在这些情形下调试。
如果这个值被设置为 |
|
URL 模式用于 URL 生成。如果没有设置 URL 模式,
默认将为 |
|
默认情况下 Flask 序列化对象成 ascii 编码的 JSON。
如果不对该配置项就行设置的话,Flask 将不会编码成
ASCII 保持字符串原样,并且返回 unicode 字符串。 |
|
默认情况下 Flask 将会依键值顺序的方式序列化 JSON。 这样做是为了确保字典哈希种子的独立性,返回值将会一致不会造成 额外的 HTTP 缓存。通过改变这个变量可以重载默认行为。 这是不推荐也许会带来缓存消耗的性能问题。 |
|
如果设置成 |
更多关于 SERVER_NAME
内容
SERVER_NAME
键是用于子域名支持。因为 Flask 在得知现有服务器名之前不能 猜测出子域名部分,所以如果你想使用子域名,这个选项必要的,并且也用于会话 cookie。
请牢记不只有 Flask 存在不知道子域名的问题,你的浏览器同样存在这样的问题。
大多数现代 web 浏览器不允许服务器名不含有点的跨子域名 cookie。因此如果你的服务器的
名称为 'localhost'
,你将不能为 'localhost'
和所有它的子域名设置一个 cookie。
请选择一个合适的服务器名,像 'myapplication.local'
, 并添加你想要的服务器名 + 子域名
到你的 host 配置或设置一个本地 bind 。
New in version 0.4: LOGGER_NAME
New in version 0.5: SERVER_NAME
New in version 0.6: MAX_CONTENT_LENGTH
New in version 0.7: PROPAGATE_EXCEPTIONS
, PRESERVE_CONTEXT_ON_EXCEPTION
New in version 0.8: TRAP_BAD_REQUEST_ERRORS
, TRAP_HTTP_EXCEPTIONS
,
APPLICATION_ROOT
, SESSION_COOKIE_DOMAIN
,
SESSION_COOKIE_PATH
, SESSION_COOKIE_HTTPONLY
,
SESSION_COOKIE_SECURE
New in version 0.9: PREFERRED_URL_SCHEME
New in version 0.10: JSON_AS_ASCII
, JSON_SORT_KEYS
, JSONIFY_PRETTYPRINT_REGULAR
从文件中配置¶
如果你能在独立的文件里存储配置,理想情况是存储在实际的应用包之外,它将变得更有用。 这能够使得打包和分发你的应用程序通过不同的处理工具( 使用 Distribute 部署 ), 之后才修改配置文件。
因此一个共同的模式是这样的:
app = Flask(__name__)
app.config.from_object('yourapplication.default_settings')
app.config.from_envvar('YOURAPPLICATION_SETTINGS')
首先从 yourapplication.default_settings 模块加载配置,接着用
YOURAPPLICATION_SETTINGS
环境变量指向的文件的内容覆盖其值。在 Linux 或者 OS X 上,
这个环境变量可以在启动服务器之前,在 shell 上 export 命令设置:
$ export YOURAPPLICATION_SETTINGS=/path/to/settings.cfg
$ python run-app.py
* Running on http://127.0.0.1:5000/
* Restarting with reloader...
在 Windows 系统上,使用内置的 set 代替:
>set YOURAPPLICATION_SETTINGS=\path\to\settings.cfg
配置文件本身实际上是 Python 文件。只有大写名称的值才会被存储到配置对象中。 因此请确保在配置键中使用了大写字母。
这里是一个配置文件的例子:
# Example configuration
DEBUG = False
SECRET_KEY = '?\xbf,\xb4\x8d\xa3"<\x9c\xb0@\x0f5\xab,w\xee\x8d$0\x13\x8b83'
确保尽早地载入配置,这样扩展才能在启动时访问配置。还有其他方式从不同的文件中加载配置对象。
完整的介绍请查阅 Config
对象的文档。
配置最佳实践¶
前面提到的方法的缺点是使测试有点困难。通常对于这个问题没有单一 100% 的解决方案,但是 你可以注意下面的事项来改善:
在函数中创建你的应用,并在上面注册蓝图。这样你可以用不同的配置来创建多个应用实例, 以此使得单元测试变得很简单。你可以用这样的方法来按需传入配置。
不要写出在导入时需要配置的代码。如果你限制只在请求中访问配置, 你可以在之后按需重新配置对象。
开发/生产¶
大多数应用程序需要不止一个配置。至少对生产服务器和开发服务器有独立的配置。最容易的处理方式就是 使用一个总是被加载的默认配置和部分版本控制,以及一个独立的配置像上面例子提及到的覆盖必要的配置值:
app = Flask(__name__)
app.config.from_object('yourapplication.default_settings')
app.config.from_envvar('YOURAPPLICATION_SETTINGS')
接着你只要新建一个独立的 config.py 文件并且导入 YOURAPPLICATION_SETTINGS=/path/to/config.py
。
不过也有替代方法。例如你可以使用导入或者子类化。
在 Django 世界中流行的是在文件顶部,显式地使用 from yourapplication.default_settings import *
导入配置文件,并手动覆盖更改。你也可以检查一个类似 YOURAPPLICATION_MODE
的环境变量来设置
production , development 等等,并导入基于此的不同的硬编码文件。
一个有趣的模式也是为配置使用类和继承:
class Config(object):
DEBUG = False
TESTING = False
DATABASE_URI = 'sqlite://:memory:'
class ProductionConfig(Config):
DATABASE_URI = 'mysql://user@localhost/foo'
class DevelopmentConfig(Config):
DEBUG = True
class TestingConfig(Config):
TESTING = True
为了使得这样一个配置有用你只要调用 from_object()
:
app.config.from_object('configmodule.ProductionConfig')
有许多不同处理配置文件方式,这取决于你想要如何管理配置文件。不过这里有一些好的建议:
在版本控制中保留一个默认配置。在覆盖配置值之前要么用默认的配置填充你的配置, 要么在你的配置文件中导入它。
使用环境变量来在配置间切换。这样可以从 Python 解释器之外完成,使开发和部署更容易, 因为你可以在不触及代码的情况下快速简便地切换配置。如果你经常在不同的项目中作业, 你甚至可以创建激活一个 virtualenv 并导出开发 配置的脚本。
使用一个类似 fabric 工具在生成环境向生成服务器分别推送代码和配置。对于如何做到这一点的细节, 请查阅 使用 Fabric 部署 。
示例文件夹¶
New in version 0.8.
Flask 0.8 引入了示例文件夹。Flask 在很长时间使得直接引用相对应用文件夹 的路径成为可能。这也是许多开发者加载存储在载入应用旁边的配置的方法。不幸 的是,这只会在应用不是包,即根路径指向包内容的情况下才能工作。
在 Flask 0.8 中,引入一个新的属性: Flask.instance_path
。它涉及到一个新的称为
“示例文件夹”的概念。实例文件夹被为不使用版本控制和特定的部署而设计。
这是放置运行时更改的文件和配置文件的最佳位置。
创建 Flask 应用的时候你可以显式地提供示例文件夹路径或者让 Flask 自动识别实例文件夹。对于显式的配置,使用 instance_path 参数:
app = Flask(__name__, instance_path='/path/to/instance/folder')
请注意给出的 一定 是绝对路径。
如果 instance_path 参数没有赋值,会适用下面默认的位置:
已卸载的模块:
/myapp.py /instance
已卸载的包:
/myapp /__init__.py /instance
安装过的模块或者包:
$PREFIX/lib/python2.X/site-packages/myapp $PREFIX/var/myapp-instance
$PREFIX
是你 Python 安装的前缀。这个前缀可以是/usr
或者你 virtualenv 的路径。 你可以打印sys.prefix
的值来查看前缀被设置成了什么。
既然配置对象提供从相对文件名来载入配置的方式,那么我们也使得它从相对实例 路径的文件名加载成为可能, 如果你想这样做。配置文件中的相对路径的行为可以 在“相对应用的根目录”(默认)和 “相对实例文件夹”中切换, 后者通过应用构造函 数的 instance_relative_config 开关实现:
app = Flask(__name__, instance_relative_config=True)
这里有一个配置 Flask 来从模块预载入配置并覆盖配置文件夹中配置文件(如果存在)的完整例子:
app = Flask(__name__, instance_relative_config=True)
app.config.from_object('yourapplication.default_settings')
app.config.from_pyfile('application.cfg', silent=True)
实例文件夹的路径可以在 Flask.instance_path
找到。 Flask 也提供了 一个打开实例文件夹中文件的捷径,
就是 Flask.open_instance_resource()
。
两者使用的示例:
filename = os.path.join(app.instance_path, 'application.cfg')
with open(filename) as f:
config = f.read()
# or via open_instance_resource:
with app.open_instance_resource('application.cfg') as f:
config = f.read()