fresh in werkzeug
hello world WSGI app
def application(environ, start_response): start_response( '200 OK', [('Content-Type', 'text/plain')] ) return ['hello world']
参数是environ字典和callable的start_response
WSGI应用
wsgi应用就是我们可以调用然后传递一个environ字典 和一个start_response的可调用对象的应用。
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)
WSGI环境
wsgi环境包含了用户发送请求的所有信息。 使用create_environ()
函数可以创建一个wsgi environ
from werkzeug.test import create_environ environ = create_environ('/foo', 'http://localhost:8080/') >>> environ {'CONTENT_LENGTH': '0', 'CONTENT_TYPE': '', 'HTTP_HOST': 'localhost:8080', 'PATH_INFO': '/foo', 'QUERY_STRING': '', 'REQUEST_METHOD': 'GET', 'SCRIPT_NAME': '', 'SERVER_NAME': 'localhost', 'SERVER_PORT': '8080', 'SERVER_PROTOCOL': 'HTTP/1.1', 'wsgi.errors': <open file '<stderr>', mode 'w' at 0x0000000001D52150>, 'wsgi.input': <cStringIO.StringO at 0x34838f0>, 'wsgi.multiprocess': False, 'wsgi.multithread': False, 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.version': (1, 0)}
输出可以得到environ的字典内容,需要关注的内容 是请求方式get,host为localhost:8080, 路径信息/foo,服务器端口8080等
用environ参数创建Request请求
from werkzeug.wrappers import Request request = Request(environ) >>> request.host 'localhost:8080' >>> request.url 'http://localhost:8080/foo'
为了方便测试,我们可以用函数from_values()
来 提供一些参数创建一个request对象。
>>> from cStringIO import StringIO >>> data = "name=this+is+encoded+form+data&another_key=another+one" >>> request = Request.from_values(query_string='foo=bar&blah=blafasel', ... content_length=len(data), input_stream=StringIO(data), ... content_type='application/x-www-form-urlencoded', ... method='POST') ... >>> request.method 'POST'
request.args
可以得到请求参数的字典, request.form
可以得到请求中数据的字典。
出来上传的文件也很简单,request.files
就可以 得到文件的字典
def store_file(request): file = request.files.get('my_file') if file: file.save('/where/to/store/file.txt') else: handle_the_error()
这里的文件是FileStorage对象,提供了一些常见的 文件操作
request.headers
是请求头部的内容
可以模拟一个浏览器来发出请求
>>> environ = create_environ() >>> environ.update( ... HTTP_USER_AGENT='Mozilla/5.0 (Macintosh; U; Mac OS X 10.5; en-US; ) Firefox/3.1', ... HTTP_ACCEPT='text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', ... HTTP_ACCEPT_LANGUAGE='de-at,en-us;q=0.8,en;q=0.5', ... HTTP_ACCEPT_ENCODING='gzip,deflate', ... HTTP_ACCEPT_CHARSET='ISO-8859-1,utf-8;q=0.7,*;q=0.7', ... HTTP_IF_MODIFIED_SINCE='Fri, 20 Feb 2009 10:10:25 GMT', ... HTTP_IF_NONE_MATCH='"e51c9-1e5d-46356dc86c640"', ... HTTP_CACHE_CONTROL='max-age=0' ... ) ... >>> request = Request(environ)
然后通过request.user_agent可以获取里面的信息
>>> request.user_agent.browser 'firefox' >>> request.user_agent.platform 'macos' >>> request.user_agent.version '3.1' >>> request.user_agent.language 'en-US'
查看浏览器支持的mimetypes
>>> request.accept_mimetypes text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 >>> request.accept_mimetypes.best 'text/html'
可以用同样的方法来查看支持的语言,编码等。
Responses
响应对象用于向用户发送数据。实际上响应对象 就是wsgi应用,所以实际上我们的操作不是返回 一个响应对象,而是在wsgi应用中像一个wsgi对象 这样调用响应对象然后返回得到的值。
例如我们的wsgi应用是这样的:
def application(environ, start_response): start_response( '200 OK', [('Content-Type', 'text/plain')] ) return ['hello world']
那我们的response对象可以如下:
from werkzeug.wrappers import Response def application(environ, start_response): response = Response('hello world') return response(environ, start_response)
与request对象不同,response对象设计为可以 修改的,我们可以直接对属性的值进行修改:
>>> from werkzeug.wrappers import Response >>> response = Response("Hello World!") >>> response.headers['content-type'] 'text/plain; charset=utf-8' >>> response.data 'Hello World!' >>> response.headers['content-length'] = len(response.data) >>> response.status '200 ok' >>> response.status = '404 not found' >>> response.status_code = 400
response中还可以设置cookie.
>>> res = Response('hello world') >>> res.set_cookie('name', 'value') >>> res.headers['Set-Cookie'] 'name=value; Path=/' >>> res.set_cookie('name1', 'value1') >>> res.headers.getlist('Set-Cookie') ['name=value; Path=/', 'name1=value1; Path=/']
设置多过一个cookie的时候可以使用getlist
来 获取cookie的列表