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的sleep函数的特殊特现象
MySQL中的系统函数sleep,实际应用的场景不多,一般用来做实验测试,昨天在测试的时候,意外发现sleep函数的一个特殊现象.如果在查询语句中使用sleep函数,那么休眠的时间跟返回的记录有关 ...
- 跑酷天堂C++小黑框版
上:跳跃 左右:行走 #include <bits/stdc++.h> #include <windows.h> #include <conio.h> using ...
- 【原创】(十)Linux内存管理 - zoned page frame allocator - 5
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...
- NOIP模拟 25
分层考试第一场. 垫底. T1 lighthouse 观察到m很小,想到容斥. 正常人都想枚举子集,只有我打了搜索. 为了压行,我压缩了几句分类讨论. 压错了,原地爆炸 考场思路: 不容斥这也不可做啊 ...
- 使用vue-cookies操作cookie
1.前言 在vue中如果想要操作cookie,除了使用之前我们自己封装好的操作cookie的方法之外,我们还可以使用vue-cookies插件,这是一个简单的Vue.js插件,专门用于在vue中处理浏 ...
- 转载]OK6410之tftp下载内核,nfs挂载文件系统全过程详解[转]
原文地址:OK6410之tftp下载内核,nfs挂载文件系统全过程详解[转]作者:千山我独行 由于工作的平台也是嵌入式,差不多的平台,所以一直就没有把自己买过来的ok6410板子好好玩玩.以前一直都是 ...
- freeradius简单配置
1.安装freeradius sudo apt-get update sudo apt-get install freeradius 2.配置client.conf vim /etc/freeradi ...
- 来了!GitHub for mobile 发布!iOS beta 版已来,Android 版即将发布
北京时间 2019 年 11 月 14 日,在 GitHub Universe 2019大会上,GitHub 正式发布了 GitHub for mobile,支持 iOS 与 Android 两大移动 ...
- javascript 解决默认取整的坑(目前已知的最佳解决方案)
javascript 解决默认取整的坑(目前已知的最佳解决方案) 复现该问题 js在数字操作时总会取更高精度的结果,例如1234/10结果就是123.4,但是在c或者java中整数除以10的结果还是整 ...
- springboot配置springMVC
/** * @ClassName MvcConfigure * @Description SpringMVC配置 * @Author JAGNG * @Date 2019/10/28 10:23 ** ...