技术标签: python Python3 运行原理 web框架 web开发 Flask
在学习Python Web开发过程中,掌握了Flask的开发方法。经过一段时间的视频学习,回过头来对Flask的运行原理做一简要解析,以增强自己对Flask的了解。
所有的 Python Web框架都要遵循 WSGI
协议,在这里还是要简单回顾一下 WSGI 的核心概念。
WSGI
中有一个非常重要的概念:每个Python Web应用都是一个可调用(callable)的对象。在 flask 中,这个对象就是 app = Flask(__name__)
创建出来的 app,就是下图中的绿色Application
部分。要运行web应用,必须有 web server,比如我们熟悉的apache
、nginx
,或者python
中的gunicorn
,我们下面要讲到的werkzeug提供的WSGIServer
,它们是下图的黄色Server部分。
Server和Application之间怎么通信,就是WSGI的功能。它规定了 app(environ, start_response) 的接口,server会调用 application,并传给它两个参数:environ
包含了请求的所有信息,start_response
是 application 处理完之后需要调用的函数,参数是状态码、响应头部还有错误信息。
WSGI application
非常重要的特点是:它是可以嵌套的。换句话说,可以写个application,它做的事情就是调用另外一个 application,然后再返回(类似一个 proxy)。一般来说,嵌套的最后一层是业务应用,中间就是 middleware。这样的好处是,可以解耦业务逻辑和其他功能,比如限流、认证、序列化等都实现成不同的中间层,不同的中间层和业务逻辑是不相关的,可以独立维护;而且用户也可以动态地组合不同的中间层来满足不同的需求。
Flask基于Werkzeug WSGI
工具箱和Jinja2 模板引擎。 Flask使用BSD
授权。 Flask也被称为“microframework”,因为它使用简单的核心,用extension增加其他功能。Flask没有默认使用的数据库、窗体验证工具。然而,Flask保留了扩增的弹性,可以用Flask-extension加入这些功能:ORM、窗体验证工具、文件上传、各种开放式身份验证技术。我们可以这么理解,Flask是一个核心,而其他功能则是一些插件,需要什么功能,只要找到对应的插件,将其插入核心就能够实现该功能了。
Flask是怎么将代码转换为我们可见的Web网页的。首先,我们得先从Web程序的一般流程来看,对于我们的Web应用来说,当客户端想要获取动态资源 时,(比如ASP和PHP这类语言写的网站),这个时候就会发起一个HTTP请求(比如用浏览器访问一个URL),此时Web应用程序就会在服务器后台进行相应的业务处理(比如对数据库进行操作或是进行一些计算操作等),取出用户需要的数据,生成相应的HTTP响应(当然,如果访问的是 静态资源 ,服务器则会直接返回用户所需的资源,不会进行业务处理)。整个处理工程如下所示:
在实际的应用中,不同的请求可能会调用相同的处理逻辑。这里有着相同业务处理逻辑的HTTP请求可以用一类URL来标识。比如在我们的博客站点中,对于所有想要获取Articles内容的请求而言,可以用 articles/这类URL来表示,这里的article_id用以区分不同的article。接着在后台定义一个get_article(article_id)的函数,用来获取article相应的数据,此外还需要建立URL和函数之间的一一对应关系。这就是Web开发中所谓的路由分发 ,如下图所示:
在Flask中,使用werkzeug来做路由分发,werkzeug
是Flask
使用的底层WSGI
库(WSGI,全称 Web Server Gateway interface
,或者 Python Web Server Gateway Interface
,是为 Python 语言定义的Web服务器和Web应用程序之间的一种简单而通用的接口)。
WSGI将Web服务分成两个部分:服务器和应用程序。WGSI服务器只负责与网络相关的两件事:接收浏览器的HTTP请求、向浏览器发送HTTP应答;而对HTTP请求的具体处理逻辑,则通过调用WSGI应用程序进行。WSGI工作流程如下图所示:
在Flask中,路由分发的代码写起来十分简单,如下:
# 管理员注销页面
@main.route('/logout')
def logout():
dm = DataManager()
currentUsers = dm.getUsers('0')
print(currentUsers[0])
return render_template('currentUsers.html', users=currentUsers)
通过业务逻辑函数获得我们所需的数据后,服务器将会根据这些数据来生成HTTP响应(对于Web应用来说,一般就是一个HTML文件,这个是可以直接被我们的客户端,即浏览器直接读取并解释的)。在Web开发中,常规的做法是将获取的数据传入Web应用提供的一个HTML模板文件中,经过模板系统的渲染后最终得到我们所需要的HTML响应文件。
一般情况下,虽然请求不同,但是响应中的数据的展示方式是相同的 ,通俗点说就是除了我们请求获得的数据不一样外,其他都是一样的,那么我们就可以设计一个模板(除了数据内容可以改动,其他都是固定的HTML文件)。我们以博客站点为例,对不同article而言,其具体article content虽然不同,但页面展示的内容除了请求的数据外都是一样的,都有标题拦,内容栏等。也就是说,对于article来说,我们只需提供一个HTML模板,然后传入不同article数据,即可得到不同的HTTP响应。这就是所谓的模板渲染 ,如下图所示:
在Flask中使用Jinja2模板渲染引擎来做模板渲染(Jinja2是基于python的模板引擎,功能比较类似于于PHP的smarty,J2ee的Freemarker和velocity。它能完全支持unicode,并具有集成的沙箱执行环境,应用广泛。jinja2使用BSD授权)。Jinja2的工作流程如下图所示:
在Flask中,模板渲染的代码写起来也是十分的便捷,代码如下:
@app.route('/articles/<int:article_id>/')
defget_article(article_id):
returnrender_template('path/to/template.html', data_needed)
在Flask
中,我们处理一个请求的流程就是,首先根据用户提交的URL来决定由哪个业务逻辑函数来处理,然后在函数中进行操作,取得所需的数据。再将取得的数据传给相应的模板文件中,由Jinja2负责渲染得到HTTP响应内容,即HTTP响应的HTML文件,然后由Flask返回响应内容。
下面主要以实例项目对Flask运行原理做一简要解析。在实例项目中,使用到了程序工厂函数和蓝本。项目目录结构如下:
在manager.py文件中,定义了项目启动的入口函数:
# 确保服务器只会在该脚本被 Python 解释器直接执行的时候才会运行,而不是作为模块导入的时候。
if __name__ == '__main__':
# 启用cmd命令行
# manager.run()
app.run(host='0.0.0.0', port=9000, debug=True)
同时,在该文件中创建了工厂方法实例:
app = create_app()
在工程方法中,对数据库进行了相关配置,创建了前端导航栏,同时对所创建的蓝本进行了注册。在创建的蓝本中主要涉及授权、路由及错误处理模块。
# 构造工厂方法
def create_app():
# 在这里__name__ == __main__
app = Flask(__name__)
app.url_map.converters['regex'] = RegexConverter
# 防止跨站攻击 注:为了增强安全性,密钥不应直接写入代码,而应该保存在环境变量中
# app.config['SECRET_KEY'] = 'hard to guess string SUNNY2017'
# app.secret_key = 'Sunny123456'
# flask提供的读取外部文件
app.config.from_pyfile('config')
# basedir = os.path.abspath(os.path.dirname(__file__))
# print(basedir)
# 配置数据库连接
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://lmapp:lmapp@localhost/smp'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
nav.register_element('top', Navbar(u'APP安盾',
View(u'当前在线', 'main.index'),
View(u'全部用户', 'main.all_users'),
View(u'注销', 'main.logout'),
View(u'修改密码', 'main.chgpwd'),
))
nav.init_app(app)
db.init_app(app)
bootstrap.init_app(app)
# init_views(app)
from .auth import auth as auth_blueprint
from .main import main as main_blueprint
# 注册蓝本 url_prefix='/auth'
app.register_blueprint(auth_blueprint,)
app.register_blueprint(main_blueprint, static_folder='static')
return app
文章浏览阅读1k次,点赞28次,收藏25次。很高兴跟大家分享我们最新的文生图模型 —— SDXL-Lightning,它实现了前所未有的速度和质量,并且已经向社区开放。_sdxllightning下载
文章浏览阅读1.5k次,点赞2次,收藏2次。前两天遇到一道lsb隐写的题目,需要用到cloacked-pixel这个脚本。工具地址下载后解压即可,这里需要注意,该脚本是基于python2的!但我电脑anaconda里面只有python3并没有很好的python基础,但借助anaconda可以轻松解决很多问题!教程如下:anaconda中添加python2但是在运行脚本时还会提示缺库(注意运行时要activate pythonXX手动切换到你所配置的python2环境下)继续使用anaconda为python2装缺少的._03-cloacked-pixel
文章浏览阅读2k次,点赞2次,收藏2次。原文http://home.cnblogs.com/group/topic/54788.html用代码添加:View Code <DataGrid.ContextMenu> <ContextMenu Name="dgmenu1" StaysOpen="true"> &..._wpf datagrid右键菜单
文章浏览阅读1.9k次,点赞2次,收藏6次。EB Tresos Studio离线激活方法_ebtresos离线激活
文章浏览阅读95次。当然用户组是可以拓展的,部门和职位常用在内部的管理系统,如果是面向c端的系统,比如淘宝网的商家,商家自身也有一套组织架构,如采购部,销售部,客服部,后勤部,有些人拥有客服权限,有些人拥有上架权限等,这就体现了用户组的扩展性。关于数据权限的处理,常见的有两种方式,一种是在角色内完成数据权限的定义,另一种是将角色和权限分开,两种方式各有偏重。即页面的功能按钮,包括查看,新增,修改,删除,审核等,用户点击删除按钮时,后台会校验用户角色下用户的所有权限是否包含该删除权限,如果是,就可以下一步,反之提示无权限。_如何将后台管理系统b端化
文章浏览阅读601次。前段时间倒腾了一下音乐节拍数检测,参考下面的网上的一个测试歌曲列表做了下对比,效果还不错,基本上都是准的。Itunes LinkNameTimeArtistBPMAlbumGenreAmazon LinkLoneliest Soul03:35Grace Potter and the Nocturnals168The Lion The Bea..._提取音乐节奏
文章浏览阅读776次。一直卡着的话直接去Microsoft Store下载这个试试看。_微软实时字幕下载不了
文章浏览阅读1.1w次。如何让谷歌Chrome地址栏恢复显示“www”和“https://”标识符地址栏隐藏“www”和“https://”标识符 谷歌 Chrome 现在默认在所有网站地址栏中少了一些内容,“www”子域和“https://”被隐藏起来了,因为谷歌认为这些不是大多数人要关注的信息。 Chrome 的产品经理 Emily Schechter 说,他们将开始从桌面版和 Android 版的第..._chrome 地址显示原始
文章浏览阅读3.5k次。文章目录Encoding Color Information for Visual Tracking:Algorithms and Benchmark 2015官网 下载数据集(4.4G)本文认为颜色信息可以提供丰富的判别线索对于视觉推理,大多数现代视觉跟踪器限制在灰度域。(也就是主要解决输入序列是灰度版本)因此我们在算法和基准两方面做了系统的研究,证明了颜色信息可以帮助提升视觉跟踪效果。..._encoding color information for visual tracking: algorithms and benchmark
文章浏览阅读860次,点赞20次,收藏21次。我们提出了一种用于自动驾驶汽车跟踪水平道路车道标记位置的可视化方法。我们的方法是基于预测滤波的。预测步骤估计在每个新的图像帧中期望的车道标记位置。它也是基于汽车的运动学模型和嵌入式测程传感器产生的信息。使用适当准备的测试车辆获得的实验结果表明,在某些条件下,如振荡和变道,预测步骤可以显著地减少跟踪误差。因此,我们相信我们的方法应用于基于图像的控制自动驾驶汽车可以提高系统性能。
文章浏览阅读1.2k次。通常提供两种基本处理方式:外包采购和工序外包。生产外包经营方式简介生产外包作为一种全新的生产经营方式,改善了传统方式的不足,主要类型有:一.OEM:(OrignalEquipmentManufactuce->原始设备制造商)典型的OEM方式为:拥有原始设备的OEM加工方(受委托方)按照委托方的要求,用自己的设备为其加工生产产品,而后贴上委托方商标交货,整个活动中,加工方只获得加工费用,自..._工序委外加工属于什么变更类型
文章浏览阅读432次。写在前面:暑期实习从申请到拿到阿里意向书大概持续了1个月的时间,和周围其他同学比较,我的面试流程算走的比较快的了。还没有拿到意向书的朋友们也不要太着急,调整好心态好好准备(虽然内心多多少少会有些焦虑),阿里走流程算是比较快的了。希望能对求职的你有所帮助。【阿里云1面(算法实习生)】1、自我介绍、项目介绍2、死锁出现的原因以及如何避免雾夜飞鹰:死锁产生的原因及四个必要条件zhuanlan.zhih..._yolo模型的时间复杂度