当你开始学习Flask时,配置看上去是小菜一碟。你仅仅需要在config.py定义几个变量,然后万事大吉。 然而当你不得不管理一个生产上的应用的配置时,这一切将变得棘手万分。 你不得不设法保护API密钥,或者纠结于为了不同的环境(比如开发环境和生产环境)使用不同的配置。 在本章我们将探讨Flask的一些高级特性,它们能让配置管理更为轻松。

从小处起步

一个简单的应用不需要任何复杂的配置。你仅仅需要在你的根目录下放置一个config.py文件,并在app.pyyourapp/__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=Trueapp.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中设定的变量。

参见

依照环境变量来配置

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中的配置的更多相关文章

  1. windows下跑python flask,环境配置

    首先声明一下,我安装的是python 2.7. 第一步:下载easy_setup.py 下载地址:https://pypi.python.org/pypi/setuptools 这个下载地址真心难找, ...

  2. python flask中的代码约定

    在Python社区中有许多关于代码风格的约定.如果你写过一段时间Python了,那么也许对此已经有些了解. 我会简单介绍一下,同时给你一些URL链接,从中你可以找到关于这个话题的详细信息. 让我们提出 ...

  3. Python Flask 多环境配置

    Python里取配置文件的时候,之前是使用的ini文件和python里configparser 模块: 可参考:https://www.cnblogs.com/feeland/p/4514771.ht ...

  4. peewee在flask中的配置

    # 原文:https://blog.csdn.net/mouday/article/details/85332510 Flask的钩子函数与peewee.InterfaceError: (0, '') ...

  5. python Flask中html模版中如何引用css,js等资源

    已有静态页面,需要将其整合到瓶的项目中,需要搞清楚, 之前的HTML中的: <link rel =“stylesheet”href =“css / framework7.ios.css”> ...

  6. Flask:文件配置方式实践及其中的各种问题记录

    Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2, 提示: 1.请查看本文后面的“18-07-17  11:18重大纠正” ! 2.flask run命令运行时传入参数 ...

  7. Python Flask高级编程之RESTFul API前后端分离精讲 (网盘免费分享)

    Python Flask高级编程之RESTFul API前后端分离精讲 (免费分享)  点击链接或搜索QQ号直接加群获取其它资料: 链接:https://pan.baidu.com/s/12eKrJK ...

  8. [python][flask] Flask 图片上传与下载例子(支持漂亮的拖拽上传)

    目录 1.效果预览 2.新增逻辑概览 3.tuchuang.py 逻辑介绍 3.1 图片上传 3.2 图片合法检查 3.3 图片下载 4.__init__.py 逻辑介绍 5.upload.html ...

  9. windows下python+flask环境配置详细图文教程

    本帖是本人在安装配置python和flask环境时所用到的资源下载及相关的教程进行了整理罗列,来方便后面的人员,省去搜索的时间.如果你在安装配置是存在问题可留言给我. 首先罗列一下python+fla ...

随机推荐

  1. 从JDK源码角度看并发竞争的超时

    JDK中的并发框架提供的另外一个优秀机制是锁获取超时的支持,当大量线程对某一锁竞争时可能导致某些线程在很长一段时间都获取不了锁,在某些场景下可能希望如果线程在一段时间内不能成功获取锁就取消对该锁的等待 ...

  2. Socket编程实践(4) --多进程并发server

    1.Socket地址复用 int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); in ...

  3. 【一天一道LeetCode】#41. First Missing Positive

    一天一道LeetCode系列 (一)题目 Given an unsorted integer array, find the first missing positive integer. For e ...

  4. android binder机制详解

    摘要 Binder是android中一个很重要且很复杂的概念,它在系统的整体运作中发挥着极其重要的作用,不过本文并不打算从深层次分析Binder机制,有两点原因:1是目前网上已经有2篇很好的文章了,2 ...

  5. XBMC源代码分析 1:整体结构以及编译方法

    XBMC(全称是XBOX Media Center)是一个开源的媒体中心软件.XBMC最初为Xbox而开发,可以运行在Linux.OSX.Windows.Android4.0系统.我自己下载了一个然后 ...

  6. Django应用部署 - 上线指南

    http://blog.csdn.net/pipisorry/article/details/46957613 python manage.py runserver已经很接近于服务器的形式,但是并不能 ...

  7. [前端]Emmet 基本语法快查

    Emmet 是一种快速写html的语法,通过几个简单的缩写,就可以拓展成html标签,工作中写html多多少少会有一些,使用的语法都是基础语法,这里总结下最常用的几个,备查. 这个插件支持非常多的ID ...

  8. android 自定义下拉菜单

    本实例的自定义下拉菜单主要是继承PopupWindow类来实现的弹出窗体,各种布局效果可以根据自己定义设计.弹出的动画效果主要用到了translate.alpha.scale,具体实现步骤如下: 先上 ...

  9. Xcode两种调试小技巧

    1."全局"断点 正常情况下如果代码有错误,会直接触发SIGXXXX信号,然后中断在main函数里. 但是我们还是不知道到底是什么引发了异常信号.我们可以在断点导航器中添加一个全局 ...

  10. 使用IO映射的方式获取tiny4412板子上的ID号

    在以前的文章中,有一篇 基于ARM-contexA9-Linux驱动开发:如何获取板子上独有的ID号 在那篇文章中,具体可以参考.那时候我使用了简单的字符设备驱动框架,最终的ID号通过read方法可将 ...