认识WSGI
来源:互联网 发布:数据库黑客大曝光 编辑:程序博客网 时间:2024/06/03 20:22
WSGI是Web Server Gateway Interface的缩写。它是Python专有的一种接口规范(其它语言也有类似的规范,只是名字不一样而已,Python则是第一个提出该规范的语言)。该规范规定了WEB服务器与WEB应用框架之间的通信方式。
首先,WEB应用需要提供一个可调用的接口(如:函数);该接口接收2个参数:
其次,WEB服务器需要定义一个回调函数,该回调函数接收2个参数:
到目前为止,WSGI规范的说明就结束了,接着就是如何使用该规范。在日常的项目中,我们不会自己去写WSGI服务,也不会自己写WSGI的接口。因为这些都是比较公用的模块或框架,自然就有人已经写好了这些功能,我们只要直接使用即可。
首先,WEB应用需要提供一个可调用的接口(如:函数);该接口接收2个参数:
- 第一个参数是当前请求所有请求信息的字典对象
- 第二个参数是一个回调函数
其次,WEB服务器需要定义一个回调函数,该回调函数接收2个参数:
- 第一个参数是响应码
- 第二个参数是响应头的列表
- WEB服务器在接收到用户请求
- 组装本次请求的所有信息并存放在字典对象
- 调用WEB应用提供的接口,并传递响应的参数
- 从WEB应用接口获取返回的响应体内容
- 从传递的回调函数中获取响应码和响应头
总的来讲基本就是WEB服务器会把请求相关信息,通过调用接口的方式传递给WEB应用程序;接口WEB应用程序通过调用回调函数和返回值的方式,分别返回响应头和响应体内容给WEB服务器。其流程示意如下:
下面清单中是最简单的WSGI服务
#!/usr/bin/env python#coding:utf-8import socketfrom app import appg_status_code = g_rep_headers = Nonedef parse_headers(buf):headers = {}lines = buf.split('\r\n')for line in lines[1:]:line = line.strip()if not line:breaksp = line.split(':', 2)headers[sp[0]] = sp[1]return headersdef callback(status_code, rep_headers):global g_status_code, g_rep_headersg_status_code = status_codeg_rep_headers = rep_headersdef handle_request(client):global g_status_code, g_rep_headers buf = client.recv(1024)headers = parse_headers(buf)rsp = app(headers, callback)headers = [":".join(header) for header in g_rep_headers] client.send("%s\r\n%s\r\n\r\n" % (g_status_code, '\r\n'.join(headers))) client.send(rsp) def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('localhost',8080)) sock.listen(5) while True: connection, address = sock.accept() handle_request(connection) connection.close() if __name__ == '__main__': main()该清单中实现了一个socket服务,它监控了本地的8080端口,当有用户请求到达时则会在handle_request函数中,通过WSGI的方式调用外部的app接口,该接口会直接返回响应内容,并且会执行传递给它的call_back函数,最后handle_request函数中会把分散的信息组织起来,发送给访问用户。
其对应的app服务接口定义如下(保存为app.py文件):
#!/usr/bin/env python#coding:utf-8def app(environ, start_response):##do some this with different pathdata = b"Hello, World!\n"start_response("200 OK", [("Content-Type", "text/plain"),("Content-Length", str(len(data)))])return iter([data])该清单中只定义了一个app函数,也就是上一个清单中被引入的app接口。在app函数中可以根据不同的头信息来决定如何处理请求,最终返回对应的响应信息。
到目前为止,WSGI规范的说明就结束了,接着就是如何使用该规范。在日常的项目中,我们不会自己去写WSGI服务,也不会自己写WSGI的接口。因为这些都是比较公用的模块或框架,自然就有人已经写好了这些功能,我们只要直接使用即可。
首先,Python官方就自带了一个WSGI的服务,我们可以直接使用。方式如下:
#!/usr/bin/env python#coding:utf-8from wsgiref.simple_server import make_server from app import app httpd = make_server('localhost', 8080, app) httpd.serve_forever()该代码的功能与清单1基本相同,而我们只需要实现一个清单2中WSGI接口即可。
此外,还有很多的第三方WSGI库,比较流行的一个是gunicorn。官方给出的使用例子如下:
pip install gunicorn ##安装gunicorn库gunicorn -w 4 app:app ##启动WSGI服务,并指定app接口所在位置,这里是app.py文件下的app函数,需要确保在app.py所在目录执行是不是有点惊为天人,我们尽然一行代码都不需要多写就可以把现有的WSGI接口集成到WSGI服务中。并且-w 4是指启动4个worker进程来提供服务,也就是说我们的WSGI接口通过gunicorn启动之后,除了更方便之外,还同时支持了多进程的并发能力。
既然WSGI有第三方这么好的实现,那么WSGI接口呢?答案是当然有的。并且目前Python的大部分WEB框架都是支持WSGI接口的,比如:Django、Flask、Tornado等。所以当我们需要使用WSGI服务的时候,其实就是配置好这些模块并相应的启动即可。下面是以Flask为例启动的WSGI服务的样例:
#!/usr/bin/env python#coding:utf-8from flask import Flaskapp = Flask(__name__)@app.route('/')def hello_world(): return 'Hello World!'if __name__ == '__main__': app.run()把上述清单保存到flask_demo.py中,然后在该文件所在目录执行如下命令:
gunicorn -w 2 flask_demo:app该命令启动了2个gunicorn的worker来执行flask的app应用。
阅读全文
0 0
- 认识WSGI
- 有关WSGi的认识和讨论
- WSGI
- WSGI
- WSGI
- WSGI
- WSGI
- WSGI
- wsgi
- WSGI
- WSGI
- WSGI
- WSGI
- wsgi
- WSGI
- WSGI
- WSGI
- WSGI简介
- PAT甲级 1049. Counting Ones (30)
- 原生js实现倒计时
- Coursea吴恩达《卷积神经网络》课程笔记(2)深度卷积网络
- [saiku] 将saiku自带的H2嵌入式数据库迁移到本地mysql数据库
- C# 事件记录
- 认识WSGI
- ubuntu12 移植MP3
- 动态规划初步
- Java_HttpClient
- java代码运行Python程序
- 记录一次简单mysql主从配置
- unity3d新版动画系统模型动画播放,暂停,倒退播放
- 在全志r40平台tinav2.1系统下调通ov5640(分色排版)
- Error:This Gradle plugin requires Studio 3.0 minimum解决办法