Python 的 WSGI 简单了解

从 flask 的 hello world 说起

直接讨论 WSGI,很多人可能没有概念,我们还是先从一个简单的 hello world 程序开始吧。

from flask import Flaskapp  = Flask(__name__)@app.route("/", methods=['GET'])
def index():return "Hello world!"if __name__ == '__main__':app.run(port=8000)

在这里插入图片描述

相信只要使用过 flask 框架或者其它 Python 框架的人,应该都会见过这个警告。这个警告的意思是:这是一个开发服务器。不要在生产环境使用它。使用一个生产的 WSGI 服务器来代替。

那么什么是 WSGI 呢?

WSGI is the Web Server Gateway Interface. It is a specification that describes how a web server communicates with web applications, and how web applications can be chained together to process one request.
WSGI 是 Web 服务器网关接口。它是一个规范,描述了web服务器如何与web应用程序通信,以及如何将web应用程序链接在一起以处理一个请求。

这里来看一个简略的时序图:
它描述了用户通过浏览器上网的过程,浏览器发送请求到 Server,Server 再把请求交给 Application 来处理,最后返回响应数据给用户的过程。(通常来说,请求在到达 Server 之前,还会先经过一个反向代理服务器,例如 nginx 或者 apache 等)
在这里插入图片描述
上面这个时序图其实可以看做是大部分网络应用程序的模式了。从请求到达应用和响应返回给用户,这个过程其实是固定的。所以,一个web应用的区别就在于它对请求的处理方式上,例如:用户使用百度、搜狗亦或是谷歌浏览器,对于用户的感知其实是相同的(尽管它们内部的实现并不相同,这里也不考虑用户的体验问题,哈哈)。

什么是 WSGI?

我们都知道通用的部分可以抽取出来,做成一个组件供其它应用使用。所以 WebServer 就是这样一个组件,它负责接收用户的请求,然后交给用户的Web应用,等到它处理完成之后,再把响应数据返回给调用者。所以,WebServer 要和 WebApplication 进行交互,那就需要定义一个协议或者更专业一点叫做接口,因此这就是 WSGI。而实现 WSGI 接口的,我们则成为 WebServer 或者 WSGI Server。

注:如果你有 java web 的背景,相信你应该使用过 tomcat,也听过 servlet API。其实,它们之间的关系和WSGI服务器与 WSGI接口的关系是类似的。

它的接口其实很简单,只要 Web 框架实现了它,就可以使用各种实现了 WSGI 接口的服务器了。
在这里插入图片描述
我们常用的 Web 框架有:falsk、django 等;WSGI 服务器有:gunicorn、uWSGI等。

对于我们入门学习来说,它其实也是很简单的,我们也不需要了解那么多。对于Web 框架的作者来说,他们需要提供一个带两个参数的可调用对象即可:

callable(environ, start_response)

下面是 Python 的 PEP3333 中提供的两个简单例子,一个是函数实现,一个是类实现,它们都是一个 Web Application。

HELLO_WORLD = b"Hello world!\n"def simple_app(environ, start_response):"""Simplest possible application object"""status = '200 OK'response_headers = [('Content-type', 'text/plain')]start_response(status, response_headers)return [HELLO_WORLD]class AppClass:"""Produce the same output, but using a class(Note: 'AppClass' is the "application" here, so calling itreturns an instance of 'AppClass', which is then the iterablereturn value of the "application callable" as required bythe spec.If we wanted to use *instances* of 'AppClass' as applicationobjects instead, we would have to implement a '__call__'method, which would be invoked to execute the application,and we would need to create an instance for use by theserver or gateway."""def __init__(self, environ, start_response):self.environ = environself.start = start_responsedef __iter__(self):status = '200 OK'response_headers = [('Content-type', 'text/plain')]self.start(status, response_headers)yield HELLO_WORLD

Python 官方提供了一个简单的 WSGI 实现,我们就以上面这两个例子为例来演示一下:

from wsgiref.simple_server import make_serverif __name__ == '__main__':with make_server("127.0.0.1", 8000, simple_app) as httpd:print("Server started on port 8000...")httpd.serve_forever()

在这里插入图片描述
在这里插入图片描述

使用基于类的实现,效果也是一样的,通常更推荐使用类的方式,因为可以利用面向对象的思想来编程。

from wsgiref.simple_server import make_serverif __name__ == '__main__':with make_server("127.0.0.1", 8000, AppClass) as httpd:print("Server started on port 8000...")httpd.serve_forever()

甚至,我们还可以再进行一步,使用这个 Python 自带的 WSGI 服务来运行最开始的 flask 的 hello world:

from wsgiref.simple_server import make_serverfrom flask import Flaskapp  = Flask(__name__)@app.route("/", methods=['GET'])
def index():return "Hello world!"if __name__ == '__main__':with make_server("127.0.0.1", 8000, app) as httpd:print("Server started on port 8000...")httpd.serve_forever()

这样再次运行它,连警告也没有了。不过,自带的这个只是一个简单的实现,官方也并不推荐在生产环境使用它。但是 flask 其实并不知道,我们使用了什么 WSGI 服务器,因为它也不关心这个。

在这里插入图片描述

在这里插入图片描述

flask 背后的秘密

甚至不需要深入 flask 的源码,只需要浅浅的一探,我们就能明白为什么上面那样做的可以的了。这是 Flask 类的源码的一小部分,其它的无需解释了,我相信这是不言自明的。

class Flask(App):"""The flask object implements a WSGI application and acts as the centralobject.  """def wsgi_app(self, environ: WSGIEnvironment, start_response: StartResponse) -> cabc.Iterable[bytes]:...def __call__(self, environ: WSGIEnvironment, start_response: StartResponse) -> cabc.Iterable[bytes]:"""The WSGI server calls the Flask application object as theWSGI application. This calls :meth:`wsgi_app`, which can bewrapped to apply middleware."""return self.wsgi_app(environ, start_response)

总结

关于 WSGI,它的文档就直接说明了,对于 Web 开发者来说,其实并不用去了解它。因为我们的工作重点其实是请求的处理,对于我上面序列图中的大部分操作都不需要关系了,它隐藏了很多的细节,使得我们可以更加专注于自己的工作内容。不过,我觉得简单的了解一下也是蛮好的,也不需要深入的了解,浅尝辄止即可。对于我们工作的整个领域都有一个概览,然后还是专注于自己工作的重点内容上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/141948.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【Axure原型】B端系统登录注册页设计成这样,就不用跟小孩一桌了

前言 在B端后台中,登录注册页这个东西,因为感觉很简单,所以经常不被产品经理们重视。但是登录注册页作为一个后台系统的门面,直接影响用户第一印象,又是非常重要的存在。 登录注册页的价值 B端系统登录注册页是用户…

极验3代前两个参数w逆向分析

声明: 该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关。 本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请联系作者立即删除! 前言 这次会简单的讲解…

Java封装(面向对象)

这个是大三来的时候刚开始又捡起来了java这个语言,以前是开设过这个课程的,但是上课都没哈好听讲,现在又开始学习java类的。 首先附上黑马程序员的一张听课截图吧 我就拿我在黑马程序员的例子上给自己的一个讲解吧 首先是javabean类 pack…

我在高职教STM32——准备HAL库工程模板(2)

新学期已开始,又要给学生上 STM32 嵌入式课程了。这课上了多年了,一直用的都是标准库来开发,已经驾轻就熟了。人就是这样,有了自己熟悉的舒适圈,就很难做出改变,老师上课也是如此,排斥新课和不熟悉的内容。显然,STM32 的开发,HAL 库已是主流,自己其实也在使用,只不过…

【IEEE出版,高录用 | EI快检索】第二届人工智能与自动化控制国际学术会议(AIAC 2024,10月25-27)

第二届人工智能与自动化控制国际学术会议(AIAC 2024) The 2nd International Conference on Artificial Intelligence and Automation Control 2024年10月25-27日 中国-广州 重要信息 会议官网:www.icaiac.org The 2nd International Conf…

网络安全学习(三)Hydra破解密码

接下来看一下Hydra工具,这是一个暴力破解密码的工具。 使用命令(注意区分大小写)。 hydra -L user.txt账号字典 -P pass.txt密码字典 IP地址 smb协议名称 hydra -l administrator指定账号 -P pass.txt密码字典 IP地址 smb协议名称 hydra -…

进程状态、进程创建和进程分类

文章目录 进程进程常见的状态进程调度进程状态变化关系 进程标识示例--进程标识的使用以及简介 进程创建fork函数vfork函数示例--使用fork函数创建子进程,并了解进程之间的关系 创建进程时发生的变化虚拟内存空间的变化示例--验证fork函数创建进程时的操作 对文件IO…

改进RRT*的路径规划算法

一、RRT算法 RRT 算法是一种基于随机采样的快速搜索算法。该算法的主要思想是通过随机采样来创建一个快速探索的树,从而生长出一条从起点到终点的路径。如图为随机树的生长过程。 初始化。首先,初始化起始点和目标点位置,并将起点作为根节点…

5-----RYZ维修工具 操作界面预览与功能操作解析 刷机 解锁 修复参数等等

以上是工具选项功能的界面预览 。通过预览可以看到很多功能选项。此类工具涵盖了很多操作区域。需要根据自己机型的实际需求来操作。根据开发者的描述。此工具有一下功能。包含mtk刷机 分区修复。9008刷机 备份基带efs等等。 高通操作区域 高通修复串码 高通修改写入基带qc…

python中的各类比较与计算

运算符 1.算数运算符2.关系运算符3.逻辑运算符4.关于短路求值5.赋值运算符1)的使用链式赋值多元赋值 2)复合赋值运算符 6.位运算符7.成员运算符8.身份运算符 1.算数运算符 # 加 print(1 2) # 减 print(2 - 1) # 乘 print(1 * 2) # 余数 4%31余数为1 print(4 % 3…

只要不逾期就行了吗?如何守护好你的“第二张身份证“!

在这个时代,信用记录已远远超越了金融交易的范畴,它如同一根无形的纽带,将我们生活的各个领域紧密相连。近闻有人甚至在步入婚姻殿堂前,也要细致核查对方的信用状况,毕竟,这关乎到共同生活的基石与未来幸福…

通过hosts.allow和hosts.deny限制用户登录

1、Hosts.allow和host.deny说明 两个文件是控制远程访问设置的,通过设置这个文件可以允许或者拒绝某个ip或者ip段的客户访问linux的某项服务。如果请求访问的主机名或IP不包含在/etc/hosts.allow中,那么tcpd进程就检查/etc/hosts.deny。看请求访问的主机…

volatile 实现原理了解吗?

volatile 实现原理了解吗? volatile 有两个作用,保证可见性和有序性。 volatile 怎么保证可见性的呢? 简单来说:读取和写入变量从原本的本地内存变成主内存中 相比 synchronized 的加锁方式来解决共享变量的内存可见性问题&#…

网络原理 IP协议与以太网协议

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 关注博主带你了解更多数据结构知识 目录 1.网络层 IP协议 1.IP协议格式 2.地址管理 2.1 IP地址 2.2 解决IP地址不够用的问题 2.3NAT网络地址转换 2.4网段划分 3.路由选择…

Unity多国语言支持

Unity多国语言支持 项目在我的课程 ”淘金城堡“ 中应用 项目的地址:http://t.csdnimg.cn/m0hFd 一、基本概念 在Unity中加入多国语言的支持可以让我们发布的游戏或应用上线在拥有不同语言的国家或地区。 下面介绍一款Unity官方提供的插件“Localization package…

FinLex An effective use of word embeddings for financial lexicon generation

FinLex: An effective use of word embeddings for financial lexicon generation 论文阅读 文章目录 FinLex: An effective use of word embeddings for financial lexicon generation 论文阅读 AbstractMethodology具体词表例子LM 词列表与 FinLex 词列表 词列表在分类任务中…

EMT-DAVT--基于子空间分布对齐和决策变量转移的多目标多任务优化

EMT-DAVT–基于子空间分布对齐和决策变量转移的多目标多任务优化 title: Multiobjective Multitasking Optimization With Subspace Distribution Alignment and Decision Variable Transfer author: Weifeng Gao, Jiangli Cheng, Maoguo Gong, Hong L…

FreeRTOS实战指南 — 3.1 C语言链表

目录 1 单向链表 1.1 单链表的概念 1.2 链表增加头结点的作用 1.3 单链表的实现 2 循环链表 3 双向链表 为什么学习链表?FreeRTOS使用链表来管理任务调度,来维护不同优先级的就绪任务;许多内部数据结构,如任务控制块&#x…

机器学习 vs 深度学习:深入浅出解析两者的区别

在当今科技飞速发展的时代,**机器学习(Machine Learning)和深度学习(Deep Learning)**成为了人工智能(AI)领域的热门话题。无论你是技术专家、学生,还是对AI感兴趣的普通读者&#x…

Pointnet++改进57:全网首发SCSA(2024最新注意力机制)|即插即用,提升特征提取模块性能

简介:1.该教程提供大量的首发改进的方式,降低上手难度,多种结构改进,助力寻找创新点!2.本篇文章对Pointnet++特征提取模块进行改进,加入SCSA注意力机制,提升性能。3.专栏持续更新,紧随最新的研究内容。 目录 1.理论介绍 2.修改步骤 2.1 步骤一 2.2 步骤二 2.3 步骤…