在用Python Web开发时经常会遇到WSGI,所以WSGI到底是什么呢?本文我们一起来揭开WSGI神秘的面纱!

先来看一下WSGI的介绍

全称Python Web Server Gateway Interface,指定了web服务器和Python web应用或web框架之间的标准接口,以提高web应用在一系列web服务器间的移植性。 具体可查看 官方文档

从以上介绍我们可以看出:

  1. WSGI是一套接口标准协议/规范;
  2. 通信(作用)区间是Web服务器和Python Web应用程序之间;
  3. 目的是制定标准,以保证不同Web服务器可以和不同的Python程序之间相互通信

你可能会问,为什么需要WSGI?

首先,我们明确一下web应用处理请求的具体流程:

  1. 用户操作操作浏览器发送请求;
  2. 请求转发至对应的web服务器
  3. web服务器将请求转交给web应用程序,web应用程序处理请求
  4. web应用将请求结果返回给web服务器,由web服务器返回用户响应结果
  5. 浏览器收到响应,向用户展示

可以看到,请求时Web服务器需要和web应用程序进行通信,但是web服务器有很多种啊,Python web应用开发框架也对应多种啊,所以WSGI应运而生,定义了一套通信标准。试想一下,如果不统一标准的话,就会存在Web框架和Web服务器数据无法匹配的情况,那么开发就会受到限制,这显然不合理的。

既然定义了标准,那么WSGI的标准或规范是?

web服务器在将请求转交给web应用程序之前,需要先将http报文转换为WSGI规定的格式。

WSGI规定,Web程序必须有一个可调用对象,且该可调用对象接收两个参数,返回一个可迭代对象:

  1. environ:字典,包含请求的所有信息
  2. 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到底是什么?的更多相关文章

  1. 根据WSGI协议自己实现mini-web框架(1)

    1. 为什么要研究WSGI 我之前在学习web开发时,往往都是根据MVT等架构直接写所谓的“视图”,使用其本身自带的http服务器,当时就一直很好奇,为什么有了HTTP协议之后,还要研究WSGI协议, ...

  2. [译]如何在Web开发中使用Python

    [译]如何在Web开发中使用Python 原文:HOWTO Use Python in the Web 摘要 这篇文档展示了Python如何融入到web中.它介绍了几种Python结合web服务器的方 ...

  3. Flask容器化部署原理与实现

    本文将介绍Flask的部署方案:Flask + Nginx + uWSGI,并使用docker进行容器化部署,部署的实例来源 Flask开发初探,操作系统为ubuntu. Flask系列文章: Fla ...

  4. 详解Flask上下文

    上下文是在Flask开发中的一个核心概念,本文将通过阅读源码分享下其原理和实现. Flask系列文章: Flask开发初探 WSGI到底是什么 Flask源码分析一:服务启动 Flask路由内部实现原 ...

  5. 转载:Python Web开发最难懂的WSGI协议,到底包含哪些内容?

    原文:PSC推出的第二篇文章-<Python Web开发最难懂的WSGI协议,到底包含哪些内容?>-2017.9.27 我想大部分Python开发者最先接触到的方向是WEB方向(因为总是有 ...

  6. Python Web开发最难懂的WSGI协议,到底包含哪些内容?

    原文出处: PythonScientists 我想大部分Python开发者最先接触到的方向是WEB方向(因为总是有开发者希望马上给自己做个博客出来,例如我),既然是WEB,免不了接触到一些WEB框架, ...

  7. 什么是 WSGI -- Python 中的 “CGI” 接口简介

    今天在 git.oschina 的首页上看到他们推出演示平台,其中,Python 的演示平台支持 WSGI 接口的应用.虽然,这个演示平台连它自己提供的示例都跑不起来,但是,它还是成功的勾起了我对 W ...

  8. 探索 OpenStack 之(11):cinder-api Service 启动过程分析 以及 WSGI / Paste deploy / Router 等介绍

    OpenStack 中的每一个提供 REST API Service 的组件,比如 cinder-api,nova-api 等,其实是一个 WSGI App,其主要功能是接受客户端发来的 HTTP R ...

  9. 网关协议学习:CGI、FastCGI、WSGI、uWSGI

    一直对这四者的概念和区别很模糊,现在就特意梳理一下它们的关系与区别. CGI CGI即通用网关接口(Common Gateway Interface),是外部应用程序(CGI程序)与Web服务器之间的 ...

随机推荐

  1. [2018-01-12] python 当天学习笔记

    Python模块 Python欧快(Moudule),是一个Python文件,以.py结尾,包含了Python对象定义和Python语句. 模块让你能够有逻辑地组织你的Python代码段. 把相关的代 ...

  2. [考试反思]1011csp-s模拟测试69:无常

    承蒙大脸skyh的毒奶,加之以被kx和Parisb以及板儿逼剥夺了一中午的睡眠(其实还有半个晚上)RP守恒终于失效了,连续两场没考好 RP也是不够了,竟然考原题,而且还不换题,连样例都一模一样只不过加 ...

  3. 基于 JavaFX 开发的聊天客户端 OIM-即时通讯

    OIM 详细介绍 一.简介 OIM是一套即时通讯的聊天系统,在这里献给大家,一方面希望能够帮助对即时通讯有兴趣研究的朋友,希望我们能够共同进步,另一个就是希望能够帮助到需要即时通讯系统的朋友或者企业, ...

  4. Golang 类型定义总结手册| 面试最基础

    变量 var 关键字是 var ,定义后须被调用 支持多个同时定义 支持使用 := 缺省定义 变量定义(声明) //使用var 关键字 进行变量定义 : var + 变量名 + 变量类型 //Var ...

  5. Windows下mysql的下载和安装

    下载: 1.下载地址:https://www.mysql.com/downloads/ 2.选择社区版:MySQL Community (GPL) Downloads » 3.MySQL Commun ...

  6. python 做一个简单的登录接口

    # -*- conding :utf-8 -*-# File Name: homewoe# Create Date: 2019/11/20 / 9:15# Change Activity: 2019/ ...

  7. PageHelper分页+排序

    使用pageHelper插件来分页,只需在执行sql前用即可 String orderBy = 排序字段 + " desc";//按照(数据库)排序字段 倒序 排序 PageHel ...

  8. 宋宝华:Linux设备驱动框架里的设计模式之——模板方法(Template Method)

    本文系转载,著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者: 宋宝华 来源: 微信公众号linux阅码场(id: linuxdev) 前言 <设计模式>这本经典 ...

  9. WordPress 去掉底部的自豪的采用WordPress

    WordPress 去掉底部的自豪的采用WordPress  

  10. hdu 1028 Sample Ignatius and the Princess III (母函数)

    Ignatius and the Princess III Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K ...