WSGI到底是什么?
在用Python Web开发时经常会遇到WSGI,所以WSGI到底是什么呢?本文我们一起来揭开WSGI神秘的面纱!
先来看一下WSGI的介绍:
全称Python Web Server Gateway Interface,指定了web服务器和Python web应用或web框架之间的标准接口,以提高web应用在一系列web服务器间的移植性。 具体可查看 官方文档
从以上介绍我们可以看出:
- WSGI是一套接口标准协议/规范;
- 通信(作用)区间是Web服务器和Python Web应用程序之间;
- 目的是制定标准,以保证不同Web服务器可以和不同的Python程序之间相互通信
你可能会问,为什么需要WSGI?
首先,我们明确一下web应用处理请求的具体流程:
- 用户操作操作浏览器发送请求;
- 请求转发至对应的web服务器
- web服务器将请求转交给web应用程序,web应用程序处理请求
- web应用将请求结果返回给web服务器,由web服务器返回用户响应结果
- 浏览器收到响应,向用户展示
可以看到,请求时Web服务器需要和web应用程序进行通信,但是web服务器有很多种啊,Python web应用开发框架也对应多种啊,所以WSGI应运而生,定义了一套通信标准。试想一下,如果不统一标准的话,就会存在Web框架和Web服务器数据无法匹配的情况,那么开发就会受到限制,这显然不合理的。
既然定义了标准,那么WSGI的标准或规范是?
web服务器在将请求转交给web应用程序之前,需要先将http报文转换为WSGI规定的格式。
WSGI规定,Web程序必须有一个可调用对象,且该可调用对象接收两个参数,返回一个可迭代对象:
- environ:字典,包含请求的所有信息
- start_response:在可调用对象中调用的函数,用来发起响应,参数包括状态码,headers等
通过以上学习,一起实现一个简单WSGI服务吧
首先,我们编写一个符合WSGI标准的一个http处理函数:
def hello(environ, start_response):
status = "200 OK"
response_headers = [('Content-Type', 'text/html')]
start_response(status, response_headers)
path = environ['PATH_INFO'][1:] or 'hello'
return [b'<h1> %s </h1>' % path.encode()]
该方法负责获取environ字典中的path_info,也就是获取请求路径,然后在前端展示。
接下来,我们需要一个服务器启动WSGI服务器用来处理验证,使用Python内置的WSGI服务器模块wsgiref,编写server.py:
# coding:utf-8
"""
desc: WSGI服务器实现
"""
from wsgiref.simple_server import make_server
from learn_wsgi.client import hello
def main():
server = make_server('localhost', 8001, hello)
print('Serving HTTP on port 8001...')
server.serve_forever()
if __name__ == '__main__':
main()
执行python server.py,浏览器打开"http://localhost:8001/a",即可验证。
通过实现一个简单的WSGI服务,我们可以看到:通过environ可以获取http请求的所有信息,http响应的数据都可以通过start_response加上函数的返回值作为body。
当然,以上只是一个简单的案例,那么在python的Web框架内部是如何遵循WSGI规范的呢?以Flask举例,
Flask与WSGI
Flask中的程序实例app就是一个可调用对象,我们创建app实例时所调用的Flask类实现了__call__方法,__call__方法调用了wsgi_app()方法,该方法完成了请求和响应的处理,WSGI服务器通过调用该方法传入请求数据,获取返回数据:
def wsgi_app(self, environ, start_response):
ctx = self.request_context(environ)
error = None
try:
try:
ctx.push()
response = self.full_dispatch_request()
except Exception as e:
error = e
response = self.handle_exception(e)
except: # noqa: B001
error = sys.exc_info()[1]
raise
return response(environ, start_response)
finally:
if self.should_ignore_error(error):
error = None
ctx.auto_pop(error)
def __call__(self, environ, start_response):
return self.wsgi_app(environ, start_response)
Flask的werkzeug库是一个非常优秀的WSGI工具库,具体的实现我们之后再详细学习。
以上。
WSGI到底是什么?的更多相关文章
- 根据WSGI协议自己实现mini-web框架(1)
1. 为什么要研究WSGI 我之前在学习web开发时,往往都是根据MVT等架构直接写所谓的“视图”,使用其本身自带的http服务器,当时就一直很好奇,为什么有了HTTP协议之后,还要研究WSGI协议, ...
- [译]如何在Web开发中使用Python
[译]如何在Web开发中使用Python 原文:HOWTO Use Python in the Web 摘要 这篇文档展示了Python如何融入到web中.它介绍了几种Python结合web服务器的方 ...
- Flask容器化部署原理与实现
本文将介绍Flask的部署方案:Flask + Nginx + uWSGI,并使用docker进行容器化部署,部署的实例来源 Flask开发初探,操作系统为ubuntu. Flask系列文章: Fla ...
- 详解Flask上下文
上下文是在Flask开发中的一个核心概念,本文将通过阅读源码分享下其原理和实现. Flask系列文章: Flask开发初探 WSGI到底是什么 Flask源码分析一:服务启动 Flask路由内部实现原 ...
- 转载:Python Web开发最难懂的WSGI协议,到底包含哪些内容?
原文:PSC推出的第二篇文章-<Python Web开发最难懂的WSGI协议,到底包含哪些内容?>-2017.9.27 我想大部分Python开发者最先接触到的方向是WEB方向(因为总是有 ...
- Python Web开发最难懂的WSGI协议,到底包含哪些内容?
原文出处: PythonScientists 我想大部分Python开发者最先接触到的方向是WEB方向(因为总是有开发者希望马上给自己做个博客出来,例如我),既然是WEB,免不了接触到一些WEB框架, ...
- 什么是 WSGI -- Python 中的 “CGI” 接口简介
今天在 git.oschina 的首页上看到他们推出演示平台,其中,Python 的演示平台支持 WSGI 接口的应用.虽然,这个演示平台连它自己提供的示例都跑不起来,但是,它还是成功的勾起了我对 W ...
- 探索 OpenStack 之(11):cinder-api Service 启动过程分析 以及 WSGI / Paste deploy / Router 等介绍
OpenStack 中的每一个提供 REST API Service 的组件,比如 cinder-api,nova-api 等,其实是一个 WSGI App,其主要功能是接受客户端发来的 HTTP R ...
- 网关协议学习:CGI、FastCGI、WSGI、uWSGI
一直对这四者的概念和区别很模糊,现在就特意梳理一下它们的关系与区别. CGI CGI即通用网关接口(Common Gateway Interface),是外部应用程序(CGI程序)与Web服务器之间的 ...
随机推荐
- MySQL系统变量auto_increment_increment与auto_increment_offset学习总结
在MySQL中,系统变量auto_increment_increment与auto_increment_offset是与自增列相关的两个参数变量.在官方文档中,将其划分为Replication Mas ...
- VirtualBox6安装CentOS7设置静态IP
安装virtualbox后安装centos7, 这里就不在赘述了, 网上有很多教程 先关闭虚拟机, 按照如下设置配置网络 这里需要使用双网卡, 我们在开启第二个网卡, 如下所示 之后开启虚拟机, 进行 ...
- st表复习笔记
st表,一种高效的区间最值查询(RMQ)算法.本质其实是一个动态规划. 其实吧,对于看过线性dp的人来说应该不难理解,只是处理有些麻烦.但是本土狗因为-1的问题居然改了许久... 用两个2^i的区间把 ...
- Flink中异步AsyncIO的实现 (源码分析)
先上张图整体了解Flink中的异步io 阿里贡献给flink的,优点就不说了嘛,官网上都有,就是写库不会柱塞性能更好 然后来看一下, Flink 中异步io主要分为两种 一种是有序Ordered 一种 ...
- PHP根据ip获取地理位置(通过高德地图接口)
PHP根据ip获取地理位置(通过高德地图接口)<pre>//restapi.amap.com/v3/ip?key=2004f145cf3a39a72e9ca70ca4b2a1dc& ...
- nyoj 69-数的长度 (log10(),计算数的位数)
69-数的长度 内存限制:64MB 时间限制:3000ms 特判: No 通过数:10 提交数:13 难度:1 题目描述: N!阶乘是一个非常大的数,大家都知道计算公式是N!=N*(N-1)····· ...
- Java开发者入职必备条件
01.基础技术体系 我认为知识技能体系化是判断技术是否过关的第一步.知识体系化包含两层含义: 1. 能够知道技术知识图谱(高清版图谱扫文末二维码)的内容 比如分布式系统中常用的RPC技术,其背后就涉及 ...
- 领扣(LeetCode)两个列表的最小索引总和 个人题解
假设Andy和Doris想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示. 你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅. 如果答案不止一个,则输出所有答 ...
- python三种格式化输出
name = '张三'age = 22job = Engineersalary = 99999999 info1 = ''' ---------- info1 of %s ---------- nam ...
- postgresql , etcd , patroni 做failover
os: centos 7.4etcd:3.2 主从IP信息192.168.56.101 node1 master192.168.56.102 node2 slave192.168.56.103 nod ...