Werkzeug 是一个WSGI工具包,也能够做为一个Web框架的底层库。html
在介绍Werkzeug以前,先介绍一下 WSGI(Python Web Server Gateway Interface),它为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。这是一个规范,描述了web server如何与web application交互、web application如何处理请求,该规范的具体描述在PEP3333,强烈推荐先阅读 PEP3333 再回头来阅读本文。python
WSGI 分为两个部分:web
能够经过下面两张图片来梳理一下它们之间的调用关系: redis
先从一份示例代码理解:apache
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
return ['Hello World!']
复制代码
一个最基本的 WSGI 应用就是如上所示,定义了一个 application 函数(callable object),callable object(可调用对象) 包括: 一个函数、方法、类或一个实现了__call__
的实例均可以用做应用程序对象。这个函数接受两个参数,分别是environ和start_response。服务器
经过回调函数(start_response)将响应状态和响应头返回给 server,同时返回响应正文(response body),响应正文是可迭代的、并包含了多个字符串。数据结构
werkzeug 提供了 python web WSGI 开发相关的功能:app
下面使用 Werkzeug 来实现一个简单的WSGI应用:框架
from werkzeug.wrappers import Request, Response
def application(environ, start_response):
request = Request(environ)
text = 'Hello %s!' % request.args.get('name', 'World')
response = Response(text, mimetype='text/plain')
return response(environ, start_response)
复制代码
如上代码所示,请求数据须要环境对象,Werkzeug容许你以一个轻松的方式访问数据。响应对象是一个 WSGI 应用,提供了更好的方法来建立响应。函数
具体建立一个 WSGI 应用请查看文档,后面会陆续提到Flask框架中使用到Werkzeug的数据结构。这里贴一些官方文档的例子,使用werkzeug建立一个web 应用:
import os
import redis
import urlparse
from werkzeug.wrappers import Request, Response
from werkzeug.routing import Map, Rule
from werkzeug.exceptions import HTTPException, NotFound
from werkzeug.wsgi import SharedDataMiddleware
from werkzeug.utils import redirect
from jinja2 import Environment, FileSystemLoader
class Shortly(object):
""" Shortly 是一个实际的 WSGI 应用,经过 __call__ 方法直接调 用 wsgi_app, 同时经过一个可选设置建立一个中间件,将static文件夹暴露给用户: """
def __init__(self, config):
self.redis = redis.Redis(config['redis_host'], config['redis_port'])
def dispatch_request(self, request):
return Response('Hello World!')
def wsgi_app(self, environ, start_response):
request = Request(environ)
response = self.dispatch_request(request)
return response(environ, start_response)
def __call__(self, environ, start_response):
return self. wsgi_app(environ, start_response)
def create_app(redis_host='localhost', redis_port=6379, with_static=True):
app = Shortly({
'redis_host': redis_host,
'redis_port': redis_port
})
if with_static:
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
'/static': os.path.join(os.path.dirname(__file__), 'static')
})
return app
if __name__ == '__main__':
from werkzeug.serving import run_simple
app = create_app()
run_simple('127.0.0.1', 5000, app, use_debugger=True, use_reloader=True)
复制代码
思路很简单,咱们的 Shortly 是一个实际的 WSGI 应用。 __call__
方法直接调用 wsgi_app 。这样作咱们能够装饰 wsgi_app 调用中间件,就像咱们在 create_app 函数中作的同样。 wsgi_app 实际上建立了一个 Request 对象,以后经过 dispatch_request 调用 Request 对象而后给 WSGI 应用返回一个 Response 对象。正如你看到的:不管是建立 Shortly 类,仍是建立 Werkzeug Request 对象来执行 WSGI 接口。最终结果只是从 dispatch_request 方法返回另外一个 WSGI 应用。这部分解释来源于官方文档的中文版。
本文主要解释了WSGI规范和Werkzeug(WSGI 工具集),以及如何实现一个符合WSGI规范的WSGI应用,最后使用Werkzeug 工具集中的相关模块,快速实现了一个基于WSGI的简单应用。