Flask 应用最佳实践

一个好的应用目录结构可以方便代码的管理和维护,一个好的应用管理维护方式也可以强化程序的可扩展性

应用目录结构

假定我们的应用主目录是”flask-demo”,首先我们建议每个应用都放在一个独立的包下,假设包名是”myapp”。所以,整个应用的目录结构如下:

flask-demo/
  ├ run.py           # 应用启动程序
  ├ config.py        # 环境配置
  ├ requirements.txt # 列出应用程序依赖的所有Python包
  ├ tests/           # 测试代码包
  │   ├ __init__.py
  │   └ test_*.py    # 测试用例
  └ myapp/
      ├ admin/       # 蓝图目录
      ├ static/
      │   ├ css/     # css文件目录
      │   ├ img/     # 图片文件目录
      │   └ js/      # js文件目录
      ├ templates/   # 模板文件目录
      ├ __init__.py
      ├ forms.py     # 存放所有表单,如果多,将其变为一个包
      ├ models.py    # 存放所有数据模型,如果多,将其变为一个包
      └ views.py     # 存放所有视图函数,如果多,将其变为一个包

应用的创建代码放在”myapp/__init__.py”中:

from flask import Flask
from myapp.admin import admin
import config

app = Flask(__name__)
app.config.from_object(‘config‘)
app.register_blueprint(admin)

from myapp import views

我们把创建应用的代码与应用的启动剥离开,并且在应用对象创建之后,再导入视图模块,因为此时视图函数上的”@app.route()”才有效。视图模块包括了所有的视图函数及路由,如果有多个视图模块,则一并导入。在主目录下的”run.py”内,我们才放入应用的启动代码:

from myapp import app

app.run(host=‘0.0.0.0‘)

此后,应用的启动都是通过执行”run.py”来完成。蓝图里的目录结构跟应用基本上一样,也是”static”目录放所有静态文件,”templates”目录放所有模板文件,”views.py”存放所有视图,”forms.py”存放所有表单,”models.py”存放所有数据模型,我就不画了。蓝图对象的初始化也放在”__init__.py”里,并在初始化后导入蓝图中的视图模块,这样风格可以跟应用保持一致:

from flask import Blueprint

admin = Blueprint(‘admin‘, __name__, url_prefix=‘/admin‘)

from myapp.admin import views

还有一种风格,就是将蓝图的模板和静态文件也放在myapp的”templates”和”static”目录下,只是在这些目录下创建与蓝图同名的子目录,比如:

flask-demo/
  ...
  └ myapp/
      ├ admin/       # 蓝图目录
      ├ static/
      │   ├ admin/   # 蓝图admin专有的js, css, 图片文件
      │   ├ css/     # css文件目录
      │   ├ img/     # 图片文件目录
      │   └ js/      # js文件目录
      ├ templates/   # 模板文件目录
      │   └ admin/   # 蓝图admin的模板文件
      ├ __init__.py
      ...

这样做的好处就是便于资源统一管理。此时蓝图中获取模板文件或静态文件,都需要加个前缀,比如”render_template(‘admin/hello.html’)”。个人觉得,如果你的蓝图只是为了划分模块,蓝图之间重用部分较多,可以用这个方法。如果蓝图之间比较独立,比如用户站点和管理员后台,就建议采用第一种方法。

应用工厂 App Factory

Flask官方建议采用工厂的模式来创建应用。什么是应用工厂呢?让我们对上例中”myapp”下的”__init__.py”文件作如下修改:

from flask import Flask
from flask_mail import Mail
from flask_sqlalchemy import SQLAlchemy
from werkzeug.utils import import_string

mail = Mail()
db = SQLAlchemy()

blueprints = [
    ‘myapp.main:main‘,
    ‘myapp.admin:admin‘,
]

def create_app(config):
    app = Flask(__name__)
    app.config.from_object(config)

    # Load extensions
    mail.init_app(app)
    db.init_app(app)

    # Load blueprints
    for bp_name in blueprints:
        bp = import_string(bp_name)
        app.register_blueprint(bp)

    return app

我们不在代码中直接创建应用,而是通过调用”create_app()”方法来返回一个应用对象,这个”create_app()”就是应用工厂方法。在工厂方法里,我们分别加载了配置,扩展和蓝图。这里要注意,因为没有一个全局的app对象,所以上一节例子中的应用视图就无法工作,因为无法执行”@app.route()”。怎么办?还好Flask有个蓝图功能,我们将主程序里的视图,数据模型,表单等也放到一个蓝图下,这里起名为”main”。创建蓝图时不指定”url_prefix”,这样它的URL前缀就是根路径。

from flask import Blueprint

main = Blueprint(‘main‘, __name__)

from myapp.main import views

然后在视图函数里用蓝图对象路由即可,这个对象在蓝图创建后就可见了:

from myapp.main import main

@main.route(‘/‘)
def index():
    return ‘<h1>Hello World from app factory!</h1>‘

有了应用工厂后,我们怎么启动应用呢。这个就简单了,我们修改下主目录下的”run.py”文件:

from myapp import create_app
import config

app = create_app(‘config‘)

app.run(host=‘0.0.0.0‘, debug=True)

这样应用就可以被启动了

应用工厂好处如下:

  1. 在跑自动测试时,每个测试用例都通过应用工厂来获取各自的应用,这样测试用例之前不会互相污染
  2. 方便获取同一应用的多个实例,比如debug版和release版,并根据需要启用,甚至于同时启用来服务不同的目的

多应用组合

上节最后说到了多个应用(在同一Python进程中)同时启用。这个怎么做到?我们先来深入下Flask中的”app.run()”方法。这个方法本质上是调用了Werkzeug中的”werkzeug.serving.run_simple()”方法来启动一个WSGI服务器,前面例子中”app.run(host=’0.0.0.0′, debug=True)”等同于调用:

from werkzeug.serving import run_simple

# debug=True means use_reloader=True and use_debugger=True
run_simple(‘0.0.0.0‘, 5000, app, use_reloader=True, use_debugger=True)

我们曾经说过Flask就是基于Werkzeug和Jinja2建立起来的,Werkzeug帮助Flask封装了很多WSGI层面的操作。所以,要同时启用多个应用,就要利用Werkzeug的方法,大家看下面的例子:

from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.serving import run_simple
from myapp import create_app
import config

release_app = create_app(‘config.release‘)
debug_app = create_app(‘config.debug‘)

app = DispatcherMiddleware(release_app, {‘/test‘: debug_app})

run_simple(‘0.0.0.0‘, 5000, app, use_reloader=True, use_debugger=True)

我们将这段代码保存在主目录下的”run_batch.py”中,执行它后你会发现。release应用挂在了服务器的根路径上,而debug应用挂在了服务器的”/test”路径上了。这样,我们就实现了两个应用同时启用。”werkzeug.wsgi.DispatcherMiddleware”是一个调度中间件,它的实例化参数就是一组应用及其挂载路径的键值对,没提供挂载路径就意味着挂到根目录上。

此外,”run_simple()”方法只能用于开发环境,生产环境还是建议大家部署在一个强大的Web服务器上

时间: 2024-10-17 12:41:17

Flask 应用最佳实践的相关文章

基础入门_Python-模块和包.运维开发中watchdog事件监视的最佳实践?

简单介绍: 说明:  此模块是一个跨平台的PY库和SHELL工具,可以监视文件系统事件(增加/删除/修改) 快速安装: pip install --upgrade watchdog 日志记录: event_handler = LoggingEventHandler() -> event_handler 说明: 创建一个日志处理句柄,其实LoggingEventHandler是继承自FileSystemEventHandler类,只是重写了增删查改的回调函数,直接调用logging模块写到对应lo

Python 最佳实践指南

粗粗粗略地过了一遍,大体捞了一些东西出来,大段大段英文太费眼了,回头细读在更新进来 浓缩版,20分钟可大体过完,然后根据自己需要去看详细的吧 整体内容还是很不错的,建议细读英文 PS:文档含有巨量的TODO(没写空白着待补充的),不过但从目录上来看还是很强大滴,相信完善后,会成为一份很牛逼的指南(难度比官方指南高一点点) 第零部分 Getting Started 链接 不解释,不翻译,自个看….真的没啥(每本入门书籍第一章…) 第一部分 Writing Great Code Structurin

《Ansible自动化运维:技术与最佳实践》图书已上架,欢迎大家阅读

本书由资深运维程师联手打造,通过大量实例,详细讲解Ansible这个自动化运维工具的基础原理和使用技巧:从基础的架构解析.安装配置,到典型应用案例分析,作者分享了自己在工作中的实战经验,为各类运维操作.运维开发人员提供了翔实的指南.本书主要内容包括:Ansible架构及安装,Ansible 组件.组件扩展.API,playbook详解,最佳实践案例分析,用ansible-vault保护敏感数据,Ansible与云计算的结合,部署Zabbix组件.Haproxy + LAMP架构,以及Ansibl

flask 电子邮件进阶实践-用模板发送163邮件

电子邮件进阶实践 下面来学习构建邮件的HTML正文,并使用模板组织内容. 一封电子邮件的正文可以是纯文本(text/plain),也可以是HTML格式的文本(text/html).处于全面的考虑,一封邮件应该既包含纯文本正文又包含HTML格式的正文.HTML格式的正文将被优先读取:加入收信人的邮件系统比较古老,无法读取HTML格式的邮件,则会读取纯文本格式的正文. 下面来学习如何编写HTML邮件正文,以及如何在Flask-Mail中同时提供这两种格式的邮件正文. 如果HTML正文非常简单,比如仅

基础入门_Python-内建函数.运维开发中eval内建函数的最佳实践?

简单介绍: 说明: 在指定命名空间中计算参数字符串的有效表达式,并返回一个对象, Help on built-in function eval in module __builtin__: eval(...)     eval(source[, globals[, locals]]) -> value          Evaluate the source in the context of globals and locals.     The source may be a string 

45个实用的JavaScript技巧、窍门和最佳实践

如你所知,JavaScript是世界上第一的编程语言,它是Web的语言,是移动混合应用(mobile hybrid apps)的语言(比如PhoneGap或者Appcelerator),是服务器端的语言(比如NodeJS或者Wakanda),并且拥有很多其他的实现.同时它也是很多新手的启蒙语言,因为它不但可以在浏览器上显示一个简单的alert信息,而且还可以用来控制一个机器人(使用nodebot,或者nodruino).掌握JavaScript并且能够写出组织规范并性能高效的代码的开发人员,已经

毫秒必争,前端网页性能最佳实践

你愿意为打开一个网页等待多长时间?我一秒也不愿意等.但是事实上大多数网站在响应速度方面都让人失望.现在越来越多的人开始建立自己的网站,博客,你的网页响应速度如何呢?在这篇文章中我们来介绍一下提高网页性能的最佳实践,以及相应的问题解决方案,让站长或者即将要成为站长的朋友了解如何去测试和提高网站响应速度,对自己的网站更有信心. 最佳实践 最佳实践我们引用的来自yahoo前端性能团队总结的35条黄金定律.原文猛击这里.下面我们分门别类将每条的关键点总结一下. 网页内容 减少http请求次数 减少DNS

atitit.手动配置列表文件的选择and 数据的层次结构 attilax总结最佳实践--yaml

atitit.手动配置列表文件的选择and 数据的层次结构 attilax总结最佳实践--yaml 1. yaml是个好的选择.. 1 2. 数据的层次结构--结构:hash,list,和block literal. 1 3. yaml跟json的实现区别 1 4. xml的优点及json的问题 2 4.1. ide友好 2 4.2. JSON也适合与任何数据,复杂struts难以阅读 2 4.3. json难以手工维护 3 5. 基于YAML的开源项目解析YAML文件最常用的Java库是JvY

京东前端:PhantomJS 和NodeJS在网站前端监控平台的最佳实践

1. 为什么需要一个前端监控系统 通常在一个大型的 Web 项目中有很多监控系统,比如后端的服务 API 监控,接口存活.调用.延迟等监控,这些一般都用来监控后台接口数据层面的信息.而且对于大型网站系统来说,从后端服务到前台展示会有很多层:内网 VIP.CDN 等. 但是这些监控并不能准确地反应用户看到的前端页面状态,比如:页面第三方系统数据调用失败,模块加载异常,数据不正确,空白开天窗等. 相关厂商内容 Native动态化最新技术解析 不可错过的智能时代的大前端 性能优化最佳实践经验谈 百度技