前言
本文主要介绍的是Python WSGI相关内容,主要来自以下网址:
What is WSGI? WSGI Tutorial An Introduction to the Python Web Server Gateway Interface (WSGI)可以看成一次简单粗暴的翻译。
什么是WSGI
WSGI的全称是Web Server Gateway Interface,这是一个规范,描述了web server如何与web application交互、web application如何处理请求。该规范的具体描述在PEP 3333。注意,WSGI既要实现web server,也要实现web application。
实现了WSGI的模块/库有wsgiref(python内置)、werkzeug.serving、twisted.web等,具体可见Servers which support WSGI。
当前运行在WSGI之上的web框架有Bottle、Flask、Django等,具体可见Frameworks that run on WSGI。
WSGI server所做的工作仅仅是将从客户端收到的请求传递给WSGI application,然后将WSGI application的返回值作为响应传给客户端。WSGI applications 可以是栈式的,这个栈的中间部分叫做中间件,两端是必须要实现的application和server。
WSGI教程
这部分内容主要来自WSGI Tutorial。
WSGI application接口
WSGI application接口应该实现为一个可调用对象,例如函数、方法、类、含__call__方法的实例。这个可调用对象可以接收2个参数:
一个字典,该字典可以包含了客户端请求的信息以及其他信息,可以认为是请求上下文,一般叫做environment(编码中多简写为environ、env); 一个用于发送HTTP响应状态(HTTP status )、响应头(HTTP headers)的回调函数。同时,可调用对象的返回值是响应正文(response body),响应正文是可迭代的、并包含了多个字符串。
WSGI application结构如下:
def application (environ, start_response): response_body = 'Request method: %s' % environ['REQUEST_METHOD'] # HTTP响应状态 status = '200 OK' # HTTP响应头,注意格式 response_headers = [ ('Content-Type', 'text/plain'), ('Content-Length', str(len(response_body))) ] # 将响应状态和响应头交给WSGI server start_response(status, response_headers) # 返回响应正文 return [response_body]
Environment
下面的程序可以将environment字典的内容返回给客户端(environment.py):
# ! /usr/bin/env python# -*- coding: utf-8 -*- # 导入python内置的WSGI serverfrom wsgiref.simple_server import make_serverdef application (environ, start_response): response_body = [ '%s: %s' % (key, value) for key, value in sorted(environ.items()) ] response_body = '/n'.join(response_body) # 由于下面将Content-Type设置为text/plain,所以`/n`在浏览器中会起到换行的作用 status = '200 OK' response_headers = [ ('Content-Type', 'text/plain'), ('Content-Length', str(len(response_body))) ] start_response(status, response_headers) return [response_body]# 实例化WSGI serverhttpd = make_server ( '127.0.0.1', 8051, # port application # WSGI application,此处就是一个函数)# handle_request函数只能处理一次请求,之后就在控制台`print 'end'`了httpd.handle_request()print 'end'
新闻热点
疑难解答