瓶踪暇影——使用Flask开发web应用琐记(1)
不知不觉间,已经一年没写博客了。看来写博客这活太重量级,还是微博上灌水省心啊。
之前在一个项目里用 Flask 开发其中的 Web 部分,有些小心得,插空整理出来放到博客上权当备忘。
里面的代码都来自实际项目。
多个 app 部署在同一服务器下
有时我们需要把多个独立的 Flask 应用部署在同一服务器下,根据 URL 前缀转到不同的应用,这时候可以用 werkzeug 的 DispatcherMiddleware 来实现 app 串接。
from werkzeug.wsgi import DispatcherMiddleware
dummy_app = Flask(__name__)
@dummy_app.route('/')
def index():
return redirect('/uc')
import uc.ucweb
import zs.zsweb
all_apps = ((None, dummy_app), ('/uc', uc.ucweb.app), ('/zs', zs.zsweb.app))
main_app = [app for (mp, app) in all_apps if not mp][0]
sub_apps = dict(((mp, app) for (mp, app) in all_apps if mp))
app = DispatcherMiddleware(main_app, sub_apps)
这个例子中创建了一个占位的 Flask 对象专用于转跳,这是项目中的某个特殊需求所致。一般来说把 all_apps 中想挂载到根路径的 app 对应的 URL 前缀设为 None 即可。后面的代码会根据 URL 前缀来把各应用自动分配给 DispatcherMiddleware 的构造函数。
instance_path 和配置文件读取
Flask 提供了从 Python 对象或者 .py 文件中读取配置的功能。但是因为 Flask 没有像 Pylons 那样使用 paster 来生成项目的初始结构,所以实际项目中这部分代码还是要自己写的。
import defaultcfg
kwargs = {}
kwargs['instance_relative_config'] = True
try:
instance_folder = os.environ['INSTANCE_FOLDER']
kwargs['instance_path'] = instance_folder
except KeyError:
pass
app_name = __name__.split('.')[0]
deploy_mode = 'production'
try:
if os.environ['DEPLOY_MODE'].upper() == 'DEBUG':
deploy_mode = 'debug'
except KeyError:
pass
app = Flask(app_name, **kwargs)
app.config.from_object(defaultcfg)
app.config.from_pyfile('common_%s.py' % (deploy_mode), silent=True)
app.config.from_pyfile('%s_%s.py' % (app_name, deploy_mode), silent=True)
字典 kwargs 将要传给``Flask`` 类构造函数的参数,其中 instance_relative_config 表示是否从实例路径(instance path)中读取配置文件,这样可以把配置与程序本身的路径分离,并且不需要硬编码其路径。当然,程序的运行时数据(比如程序自己的本地数据库、 cache 过来的一些参数表等)也应该放到实例路径中去,具体做法在此不多说。
接下来,看 instance_path 的实际路径是否已在环境变量中设置(其实从 argv 中读取命令行参数也是个不错的主意),没有则取 Flask 的默认值。
app_name 按 Flask 文档中的建议取 __name__ 的第一段。
在构造了 app 对象后,首先从 defaultcfg 对象中读取配置的默认值,然后读取公共配置文件 common_<部署模式>.py ,最后读取应用相关的配置文件 <程序名>_<部署模式>.py 。由于之前设置为从 instance_path 中读取配置文件,因此可以把不同 app 的 instance_path 指定到同一个目录,这样多个 app 的公共配置部分(比如日志设置、公共的数据库设置等)就可以只写一份,而各 app 自己的独有配置则放到各自的配置文件中去。生产系统的配置和调试系统的配置则通过表示部署模式的 deploy_mode 来区分开。
- adoal's blog
- 121 次点击

评论
发表新评论