你可能想用Python来开发自己的Web应用,或者已经使用过类似于flask这样的WSGI应用框架开发过Web应用但不知道什么是WSGI.
这篇文章,详细的讲述到底什么是WSGI,以及WSGI接口的简单教程
什么是WSGI?
当我们要用Python去开发一个Web应用时该怎么办?
我们要手动编写TCP监听,响应,发送SQL语句来与数据库互动,生成合适的HTML。当然,这些都是在没有轮子的情况下。
如果每一个开发人员在开发每一个Web应用时都这样,那么工作效率就会大大降低。因此也出现了轮子——帮忙处理TCP等繁琐的HTTP互动,让开发人员专注于业务逻辑代码
因此,WSGI出现了
WSGI用于定义底层TCP的轮子与Web应用/框架之间的沟通
他们的关系是这样的:
服务器 => Python => WSGI Server => WSGI App/Framework => HTTP => User Request
其中:
WSGI Server : 负责TCP等方面的业务
WSGI App/Framework : 负责通过WSGI与WSGI Server沟通,处理业务逻辑代码
而WSGI接口就是用来连接这两个模块的。WSGI Server通过接口把HTTP的请求信息传给WSGI App/Framework,而WSGI App/Framework通过接口把HTTP的响应信息传给WSGI Server .
一个小示例
WSGI的接口简直棒极了,因为十分的简单。Python自带了一个WSGI Server叫wsgiref,而WSGI App/Framework可以只是一个函数,我们让wsgiref来调用这个函数
WSGI App/Framework :
def wsgi_app(self, environ, start_response):
start_response("200 OK",[])
return ["hello world".encode("utf-8")]
environ和start_response都是由WSGI Server传给我们的,我们可以把他通俗的叫做上下文,因为它包括了每一次HTTP请求的信息。WSGI Server每接到一次请求,接调用这个函数一次
start_response接受俩参数,一个是HTTP状态码;一个是由列表组成的HTTP Headers ; 状态码必须是至少有四个字符的字符串,我在菜鸟教程上整理了一下:
{
100:"Continue",
101:"Switching Protocols",
200:"OK",
201:"Created",
202:"Accepted",
203:"Non-Authoritative Information",
204:"No Content",
205:"Reset Content",
206:"Partial Content",
300:"Multiple Choices",
301:"Moved Permanently",
302:"Found",
303:"See Other",
304:"Not Modified",
305:"Use Proxy",
306:"Unused",
307:"Temporary Redirect",
400:"Bad Request",
401:"Unauthorized",
402:"Payment Required",
403:"Forbidden",
404:"Not Found",
405:"Method Not Allowed",
406:"Not Acceptable",
407:"Proxy Authentication Required",
408:"Request Time-out",
409:"Conflict",
410:"Gone",
411:"Length Required",
412:"Precondition Failed",
413:"Request Entity Too Large",
414:"Request-URI Too Large",
415:"Unsupported Media Type",
416:"Requested range not satisfiable",
417:"Expectation Failed",
500:"Internal Server Error",
501:"Not Implemented",
502:"Bad Gateway",
503:"Service Unavailable",
504:"Gateway Time-out",
505:"HTTP Version not supported"
}
WSGI Server :
from wsgiref.simple_server import make_server
httpd = make_server("", port, wsgi_app)
print("Server Running at http://127.0.0.1:{}".format(port) + "/")
httpd.serve_forever()
我们导入wsgiref,创建httpd对象并传入我们的WSGI App/Framework函数,打印运行日志,并在端口上监听响应。因为每一个WSGI Server的参数都不一样,所以这里不多做介绍,请自行百度。
尝试访问下:
$ python server.py
Server Running at http://127.0.0.1:8080/
127.0.0.1 - - [20/Oct/2020 21:47:18] "GET / HTTP/1.1" 200 16
成功响应
调用environ参数
我们可以通过WSGI Server传入的environ参数来获取HTTP请求的信息,environ参数大致上是一个字典,获取信息大致这样:
# 获取HTTP请求的请求方式:GET or POST
environ["REQUEST_METHOD"]
# 获取HTTP请求的路径: /request_url
environ["PATH_INFO"]
有关于更多的信息,请参考 PEP 0333
start_response函数
我们可以通过WSGI Server传入的start_response函数来设置我们返回的HTTP信息,这里是不错的一些例子:
# 设置HTTP响应码: 200 OK
start_response("200 OK",[])
# 设置HTTP响应头: ("content_type","text/html")
start_response("200 Ok",[("content_type","text/html"),]
需要注意的是,start_response函数只能调用一次,上面的示例需要合并。有关于HTTP响应头的疑问,可以参考 HTTP响应头信息
写在最后
以上就是WSGI的基本介绍,如果想更深入的了解WSGI,还是请阅读官方文档吧。
09后第一次写文章,不喜勿喷