當前位置:
首頁 > 知識 > Werkzeug 庫以及 wrapper 模塊

Werkzeug 庫以及 wrapper 模塊

點擊

上方藍字

,快速關注我們)




來源:fanchunke


fanchunke.me/Flask/Werkzeug庫簡介/


如有好文章投稿,請點擊 → 這裡了解詳情




簡介



Werkzeug是一個Python寫成的WSGI工具集。它遵循WSGI規範,對伺服器和Web應用之間的「中間層」進行了開發,衍生出一系列非常有用的Web服務底層模塊。關於Werkzeug功能的最簡單的一個例子如下:





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)


if __name__ == "__main__":


from werkzeug.serving import run_simple


run_simple("localhost", 4000, application)



運行上面的例子,當在瀏覽器輸入http://localhost:4000/就會向本地的伺服器發出一個請求。在請求的過程中,werkzeug主要做了下面幾件事情:






  1. 根據伺服器和WSGI伺服器產生的environ環境信息,封裝一個Request實例,這個實例包含請求的所有信息;



  2. Web應用根據封裝的Request實例信息,產生一個Response實例(上述例子只是輸出一段字元串)。這個Response實例是一個可調用的WSGI應用;



  3. 上一步驟產生的可調用應用對象response調用response(environ, start_response)生成響應信息並發回客戶端。調用函數是由WSGI規範規定的。




以上過程很好地將伺服器和web應用分離開來:伺服器不用考慮請求信息怎麼被解析給web應用,以及後續怎麼和web應用通信;web應用也不用考慮怎麼將響應信息返回給伺服器。伺服器要做的只是提供web應用所需的請求信息,web應用提供的也只是響應信息,中間的處理過程werkzeug可以幫助完成。




wrappers模塊




Werkzeug庫中的wrappers模塊主要對request和response進行封裝。request包含了客戶端發往伺服器的所有請求信息,response包含了web應用返回給客戶端的所有信息。wrappers模塊對請求和響應的封裝簡化了客戶端、伺服器和web應用通信的流程。本文主要介紹wrappers模塊中重要的類。




BaseRequest




BaseRequest是一個非常基礎的請求類,它可以和其他的「混合」類結合在一起構建複雜的請求類。只要傳遞一個環境變數environ(由WSGI伺服器根據請求產生),便可以構造一個BaseRequest實例。其構造函數如下:





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)**





@

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)





@

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對象的調用。代碼如下:





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應用。





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

)




上面的小例子的實現步驟分析:






  1. 根據傳入web應用的environ構造請求對象request;



  2. web應用構造響應對象response;



  3. 調用響應對象response。調用過程中產生三個值:app_iter、status、headers,其中status和headers作為參數傳遞給函數start_response用於生成響應報文首行的相關信息,而app_iter作為響應的內容(它是一個可迭代對象)返回給WSGI網關;



  4. 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類,具體如下:





class

Request

(

BaseRequest

,

AcceptMixin

,

ETagRequestMixin

,


UserAgentMixin

,

AuthorizationMixin

,


CommonRequestDescriptorsMixin

)




Response類繼承自BaseResponse類,並且結合一些響應相關的Mixin類,具體如下:





class

Response

(

BaseResponse

,

ETagResponseMixin

,

ResponseStreamMixin

,


CommonResponseDescriptorsMixin

,


WWWAuthenticateMixin

)




至此,可以從wrappers模塊中引入Request類和Response用於構建請求對象和響應對象。




看完本文有收穫?請轉

發分享給更多人


關注「Python開發者」,提升Python技能


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python開發者 的精彩文章:

這裡有 10 個省時間的 PyCharm 技巧
限免100人|魔鏡數據訓練營招生開始,帶你從0到1打造數據產品
用分布式爬蟲搞點數據回來!
Python 爬蟲神器 PyQuery 的使用方法
教你搭建一個好看的 Jupyter 環境

TAG:Python開發者 |