WSGI接口

WSGI接口什么是 WSGIWSGI WebServerGat 全称服务器网关接口 是 python 语言中定义的 Web 服务器和 Web 应用程序之间或者框架之间的通用接口标准 WSGI 就像一座桥梁 桥梁的一端成为服务器或者网关端 另一端称为应用端或者框架端 WSGI 的作用就是在协议之间转换 WSGI 将 Web 组件分成了三类 Web 服务器 WSGIServer Web 中间件 WSG

什么是WSGI

WSGI(Web Server GateWay Interface)全称服务器网关接口,是python语言中定义的Web服务器和Web应用程序之间或者框架之间的通用接口标准。WSGI就像一座桥梁,桥梁的一端称为服务器或者网关端,另一端称为应用端或者框架端,WSGI的作用就是在协议之间转换。WSGI将Web组件分成了三类:Web服务器(WSGI Server),Web中间件(WSGI Middleware)与Web应用程序(WSGI Application)。Web Server接收HTTP请求,封装一系列环境变量,按照WSGI接口标准调用注册的WSGI Application,最后将相应返回给客户端。

Web应用的本质

  1. 浏览器发送HTTP请求
  2. 服务器接收到请求,生成HTML文档
  3. 服务器把HTML文档作为HTTP响应的Body发送给浏览器
  4. 浏览器收到HTTP响应,从HTTP Body取出HTML文档进行显示

下面分别来看这三个组件

WSGI Server/gateway

wsgi server可以理解为一个符合wsgi规范的web server,接收request请求,封装一系列环境变量,按照wsgi规范调用注册的wsgi app,最后将response返回给客户端。文字很难解释清楚wsgi server到底是什么东西,以及做些什么事情,最直观的方式还是看wsgi server的实现代码。以python自带的wsgiref为例,wsgiref是按照wsgi规范实现的一个简单wsgi server。它的代码也不复杂,

  1. 服务器创建socket,监听端口,等待客户端连接。
  2. 当有请求来时,服务器解析客户端信息放到环境变量environ中,并调用绑定的handler来处理请求。
  3. handler解析这个http请求,将请求信息例如method,path等放到environ中。
  4. wsgi handler再将一些服务器端信息也放到environ中,最后服务器信息,客户端信息,本次请求信息全部都保存到了环境变量environ中。
  5. wsgi handler 调用注册的wsgi app,并将environ和回调函数传给wsgi app
  6. wsgi app 将reponse header/status/body 回传给wsgi handler
  7. 最终handler还是通过socket将response信息塞回给客户端。

WSGI Application

def simple_app(environ, start_response): status = '200 OK' response_headers = [('Content-type', 'text/plain')] start_response(status, response_headers) return [u"This is hello wsgi app".encode('utf8')] 

我们再用wsgiref 作为wsgi server ,然后调用这个wsgi app,就能直观看到一次request,response的效果,简单修改代码如下:

from wsgiref.simple_server import make_server def simple_app(environ, start_response): status = '200 OK' response_headers = [('Content-type', 'text/plain')] start_response(status, response_headers) return [u"This is hello wsgi app".encode('utf8')] httpd = make_server('', 8000, simple_app) print "Serving on port 8000..." httpd.serve_forever() 

访问http://127.0.0.1:8000 就能看到效果了。

此外,上面讲到了wsgi app只要是一个callable对象就可以了,因此不一定要是函数,一个实现了call方法的实例也可以,示例代码如下:

from wsgiref.simple_server import make_server class AppClass: def __call__(self,environ, start_response): status = '200 OK' response_headers = [('Content-type', 'text/plain')] start_response(status, response_headers) return ["hello world!"] app = AppClass() httpd = make_server('', 8000, app) print "Serving on port 8000..." httpd.serve_forever() 

WSGI MiddleWare

from wsgiref.simple_server import make_server
    URL_PATTERNS= (
    ('hi/','say_hi'),
    ('hello/','say_hello'),
    )

class Dispatcher(object):

def _match(self,path):
    path = path.split('/')[1]
    for url,app in URL_PATTERNS:
        if path in url:
            return app

def __call__(self,environ, start_response):
    path = environ.get('PATH_INFO','/')
    app = self._match(path)
    if app :
        app = globals()[app]
        return app(environ, start_response)
    else:
        start_response("404 NOT FOUND",[('Content-type', 'text/plain')])
        return ["Page dose not exists!"]

def say_hi(environ, start_response):
    start_response("200 OK",[('Content-type', 'text/html')])
    return ["kenshin say hi to you!"]

def say_hello(environ, start_response):
    start_response("200 OK",[('Content-type', 'text/html')])
    return ["kenshin say hello to you!"]

app = Dispatcher()

httpd = make_server('', 8000, app)
print "Serving on port 8000..."
httpd.serve_forever()

上面的例子可以看出来,middleware 包装之后,一个简单wsgi app就有了URL dispatch功能。然后我还可以在这个app外面再加上其它的middleware来包装它,例如加一个权限认证的middleware:

class Auth(object): def __init__(self,app): self.app = app def __call__(self,environ, start_response): #TODO return self.app(environ, start_response) app = Dispatcher() auth_app = Auth(app) httpd = make_server('', 8000, auth_app) print "Serving on port 8000..." httpd.serve_forever() 

经过这些middleware的包装,已经有点框架的感觉了。其实基于wsgi的框架,例如paste,pylons就是这样通过一层层middleware组合起来的。只是一个成熟的框架,这样的middleware会有很多,例如:

def configure(app): return ErrorHandlerMiddleware( SessionMiddleware( IdentificationMiddleware( AuthenticationMiddleware( UrlParserMiddleware(app)))))) 

只要这些Middleware符合wsgi规范,甚至还可以在各个框架之间组合重用。例如pylon的认证Middleware可以直接被TurboGears拿去使用。

声明:以上部分内容参考知名博主,小弟仅供学习使用,只做快乐的学习者。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/228713.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午6:22
下一篇 2026年3月16日 下午6:22


相关推荐

  • vue获得焦点事件处理函数中控制其失去焦点,但是失去焦点后该获得焦点事件一直被触发

    vue获得焦点事件处理函数中控制其失去焦点,但是失去焦点后该获得焦点事件一直被触发当input获取焦点的时候需要判断另一个操作是否已完成,否则需要引导用户先去执行另一个操作,是则允许输入。另一个操作跟当前操作是在同一个页面上,无法通过“下一步”进行控制。解决思路是:当input获取焦点的时候,判断是否满足条件,如果否,则弹出提示引导用户先做另一步操作,然后使当前input失去焦点。但问题是:代码如下:在输入框绑定focus事件:测试:没有选择…

    2022年6月18日
    74
  • intellijidea2021最新激活码(JetBrains全家桶)[通俗易懂]

    (intellijidea2021最新激活码)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~BI7JCUH1TG-eyJsaWNlb…

    2022年3月22日
    66
  • Jieba分词简介[通俗易懂]

    Jieba分词简介[通俗易懂]Jieba分词官网:https://github.com/fxsjy/jieba 三种分词模式 Jieba提供了三种分词模式:精确模式,试图将句子最精确地切开,适合文本分析; 全模式,把句子中所有的可以成词的词语都扫描出来,速度非常快,但是不能解决歧义; 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。importjiebasent…

    2022年5月24日
    38
  • jpg转nv12_jpeg改jpg

    jpg转nv12_jpeg改jpg代码主要用到了libyuv库和libjpeg库。编译:g++demo.cpp-lyuv-ljpeg-odemoubuntu下测试(需安装ffmpeg,width以及height按实际情况填写):ffplay-itest.yuv-pixel_formatnv12-swidthxheightdemo:#include<stdio.h>#include<stdlib.h>#include<libyuv.h>#..

    2025年12月4日
    5
  • html页面调用高德地图,html前端使用高德地图入门教程「建议收藏」

    html页面调用高德地图,html前端使用高德地图入门教程「建议收藏」文章目录开始准备工作注册Key前期页面上的准备插件使用插件使用步骤引入插件定位自定义地图显示位置和缩放级别添加实时路况图层获取定位信息(需要使用插件)浏览器定位IP定位获取当前城市信息覆盖物添加覆盖物获取覆盖物覆盖物的操作图层设置图层获取图层移除图层3D地图未完待续…开始准备工作注册Key如果开发者账号包括Key已经有了,请忽略此步骤首先,注册开发者账号,成为高德开放平台开发者登陆之后,在进入…

    2022年5月21日
    77
  • 使用 OpenAI 协议代理 Cloudflare Workers AI 服务

    使用 OpenAI 协议代理 Cloudflare Workers AI 服务

    2026年3月12日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号