Werkzeug庫中的wrappers
模組主要對request
和response
進行封裝。request
包含了客戶端發往伺服器的所有請求資訊,response
包含了web應用返回給客戶端的所有資訊。wrappers
模組對請求和響應的封裝簡化了客戶端、伺服器和web應用通訊的流程。本文主要介紹wrappers
模組中重要的類。
BaseRequest
BaseRequest
是一個非常基礎的請求類,它可以和其他的“混合”類結合在一起構建複雜的請求類。只要傳遞一個環境變數environ
(由WSGI
伺服器根據請求產生),便可以構造一個BaseRequest
例項。其建構函式如下:
1 2 3 4 5 |
def __init__(self, environ, populate_request=True, shallow=False): self.environ = environ if populate_request and not shallow: self.environ['werkzeug.request'] = self self.shallow = shallow |
初始化後,形成的例項request
便具有了一些屬性可以訪問,這些屬性只能以“只讀”的方式訪問。例如:
- url_charset
- want_form_data_parsed
- stream
- args
- data
- form
- values
- files
- cookies
- headers
- path
- full_path
- script_root
- url
- base_url
- url_root
- host_url
- host
- access_route
- remote_addr
BaseRequest
中還有兩個類方法比較常用:
from_values(cls, *args, kwargs)**
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
@classmethod def from_values(cls, *args, **kwargs): """Create a new request object based on the values provided. If environ is given missing values are filled from there. This method is useful for small scripts when you need to simulate a request from an URL. Do not use this method for unittesting, there is a full featured client object (:class:`Client`) that allows to create multipart requests, support for cookies etc. This accepts the same options as the :class:`~werkzeug.test.EnvironBuilder`. .. versionchanged:: 0.5 This method now accepts the same arguments as :class:`~werkzeug.test.EnvironBuilder`. Because of this the `environ` parameter is now called `environ_overrides`. :return: request object """ from werkzeug.test import EnvironBuilder charset = kwargs.pop('charset', cls.charset) kwargs['charset'] = charset builder = EnvironBuilder(*args, **kwargs) try: return builder.get_request(cls) finally: builder.close() |
這個類方法可以根據提供的引數構建一個請求。
application(cls, f)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@classmethod def application(cls, f): """Decorate a function as responder that accepts the request as first argument. This works like the :func:`responder` decorator but the function is passed the request object as first argument and the request object will be closed automatically:: @Request.application def my_wsgi_app(request): return Response('Hello World!') :param f: the WSGI callable to decorate :return: a new WSGI callable """ #: return a callable that wraps the -2nd argument with the request #: and calls the function with all the arguments up to that one and #: the request. The return value is then called with the latest #: two arguments. This makes it possible to use this decorator for #: both methods and standalone WSGI functions. def application(*args): request = cls(args[-2]) with request: return f(*args[:-2] + (request,))(*args[-2:]) return update_wrapper(application, f) |
這個類方法是一個裝飾器,可以用來裝飾WSGI
可呼叫物件或函式。
以上屬性和方法的具體用法可以參考Request——werkzeug文件。
BaseResponse
BaseResponse
類是一個響應類,用它可以封裝一個response
物件。response
物件最大的特點是它是一個WSGI
應用。
在之前介紹WSGI
規範的文章中曾介紹過Web伺服器閘道器
,它簡化了伺服器和web應用之間的通訊過程,它要求伺服器和web應用要遵循WSGI
規範進行開發。對於web應用而言,應用應該實現一個函式或者一個可呼叫物件,這樣WSGI
伺服器可以通過呼叫myWebApp(environ, start_response)
從web應用獲得響應內容。
response
響應物件就是這樣一個WSGI
應用物件。在其實現過程中有一個__call__
方法,可以實現對一個response
物件的呼叫。程式碼如下:
1 2 3 4 5 6 7 8 9 10 |
def __call__(self, environ, start_response): """Process this response as WSGI application. :param environ: the WSGI environment. :param start_response: the response callable provided by the WSGI server. :return: an application iterator """ app_iter, status, headers = self.get_wsgi_response(environ) start_response(status, headers) return app_iter |
這樣,我們就可以很清楚地理解WSGI
應用的實現過程。下面是一個非常簡單的WSGI
應用。
1 2 3 4 5 |
from werkzeug.wrappers import Request, Response def application(environ, start_response): request = Request(environ) response = Response("Hello %s!" % request.args.get('name', 'World!')) return response(environ, start_response) |
上面的小例子的實現步驟分析:
- 根據傳入web應用的
environ
構造請求物件request
; - web應用構造響應物件
response
; - 呼叫響應物件
response
。呼叫過程中產生三個值:app_iter
、status
、headers
,其中status
和headers
作為引數傳遞給函式start_response
用於生成響應報文首行的相關資訊,而app_iter
作為響應的內容(它是一個可迭代物件)返回給WSGI閘道器
; WSGI閘道器
將返回的資訊組成響應首行、響應首部、響應主體等,形成響應報文發回給客戶端。
BaseResponse
類中還有一些屬性和方法,以下屬性和方法的具體用法可以參考Response——werkzeug文件。
- 屬性
- status_code
- status
- data
- is_stream
- is_sequence
- ······
- 方法
- call_on_close(func)
- close()
- freeze()
- force_type() 類方法
- from_app() 類方法
- set_data()
- get_data()
_ensure_sequence()
- make_sequence()
- iter_encoded()
- calculate_content_length()
- set_cookie()
- delete_cookie()
- get_wsgi_headers(environ)
- get_app_iter(environ)
- get_wsgi_response(environ)
__call__(environ, start_response)
- ······
Mixin類
BaseRequest
類和BaseResponse
類是請求和響應最基礎的類。wrappers
模組中還提供了一些Mixin
類,用於擴充套件請求類和響應類。
有關請求類的Mixin
類
有關請求類的Mixin
類主要有:
AcceptMixin
類 ——請求報文中關於客戶端希望接收的資料型別的類。ETagRequestMixin
類 ——請求報文中關於Etag和Cache的類。UserAgentMixin
類 ——請求報文中關於user_agent的類。AuthorizationMixin
類 ——請求報文中關於認證的類。CommonRequestDescriptorsMixin
類 ——通過這個類可以獲取請求首部中的相關資訊。
有關響應類的Mixin
類
有關響應類的Mixin
類主要有:
ETagResponseMixin
類 ——為響應增加Etag和Cache控制的類。ResponseStreamMixin
類 ——為響應可迭代物件提供一個“只寫”的介面的類。CommonResponseDescriptorsMixin
類 ——通過這個類可以獲取響應首部中的相關資訊。WWWAuthenticateMixin
類 ——為響應提供認證的類。
Request和Response
終於講到Request
類和Response
類了。
Request
類繼承自BaseRequest
類,並且結合一些請求相關的Mixin
類,具體如下:
1 2 3 |
class Request(BaseRequest, AcceptMixin, ETagRequestMixin, UserAgentMixin, AuthorizationMixin, CommonRequestDescriptorsMixin) |
Response
類繼承自BaseResponse
類,並且結合一些響應相關的Mixin
類,具體如下:
1 2 3 |
class Response(BaseResponse, ETagResponseMixin, ResponseStreamMixin, CommonResponseDescriptorsMixin, WWWAuthenticateMixin) |
至此,可以從wrappers
模組中引入Request
類和Response
用於構建請求物件和響應物件。