Werkzeug库中的wrappers模块主要对requestresponse进行封装。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)

上面的小例子的实现步骤分析:

  1. 根据传入web应用的environ构造请求对象request
  2. web应用构造响应对象response
  3. 调用响应对象response。调用过程中产生三个值:app_iterstatusheaders,其中statusheaders作为参数传递给函数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类 ——为响应提供认证的类。

RequestResponse

终于讲到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用于构建请求对象和响应对象。

Werkzeug库——wrappers模块的更多相关文章

  1. [python标准库]Pickle模块

    Pickle-------python对象序列化 本文主要阐述以下几点: 1.pickle模块简介 2.pickle模块提供的方法 3.注意事项 4.实例解析 1.pickle模块简介 The pic ...

  2. PHP之fopen wrappers模块

    一.fopen wrappers模块的配置 ①.allow_url_fopen boolean //出于安全性考虑,此选项只能在 php.ini 中设置 //本选项激活了 URL 形式的 fopen ...

  3. Python 标准库 ConfigParser 模块 的使用

    Python 标准库 ConfigParser 模块 的使用 demo #!/usr/bin/env python # coding=utf-8 import ConfigParser import ...

  4. Python标准库——collections模块的Counter类

    1.collections模块 collections模块自Python 2.4版本开始被引入,包含了dict.set.list.tuple以外的一些特殊的容器类型,分别是: OrderedDict类 ...

  5. 使用不同的C++支持库的模块混合开发时,引发异常展开不正常,抛异常竟引出一个SIGSEGV

    如果你使用gcc对一部分模块进行了GNUMake的编译,这些编译出动态库使用在Gradle编译框架下的项目.那么就有可能出现题目中的情况,使用不同的C++支持库的模块混合开发时,引发异常展开不正常. ...

  6. 20201207-2 openpyxl 库与模块导入

    1-1 import openpyxl # 通过文件路径,打开工作簿 wb1 = openpyxl.load_workbook('./demo_excel.xlsx') # 用 Workbook() ...

  7. Python第三方库(模块)"scikit learn"以及其他库的安装

    scikit-learn是一个用于机器学习的 Python 模块. 其主页:http://scikit-learn.org/stable/. GitHub地址: https://github.com/ ...

  8. python标准库 sysconfig模块

    # -*- coding: utf-8 -*-# python:2.x__author__ = 'Administrator'import sysconfig#sysconfig:解释器编译时配置#作 ...

  9. [python标准库]XML模块

    1.什么是XML XML是可扩展标记语言(Extensible Markup Language)的缩写,其中的 标记(markup)是关键部分.您可以创建内容,然后使用限定标记标记它,从而使每个单词. ...

随机推荐

  1. leetcood学习笔记-38-报数

    ---恢复内容开始--- 题目描述: 第一次提交: class Solution: def countAndSay(self, n: int) -> str: f = " for i ...

  2. docker-compose安装及docker-compose.yml详解

    1.下载安装 [root@cx-- ~]# curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-comp ...

  3. C++在#include命令中,用〈 〉和“”有什么区别

    使用尖括号表示在包含文件目录中去查找(包含目录是由用户在设置环境时设置的),而不在源文件目录去查找: 使用双引号则表示首先在当前的源文件目录中查找,若未找到才到包含目录中去查找.  

  4. DP杂题2

    1.邦邦的大合唱站队 https://www.luogu.org/problem/show?pid=3694 XY说这是道简单的签到题,然后我大概是普及组都拿不到三等的那种了.. 插入题解.写得太好了 ...

  5. System.Web.Mvc.IController.cs

    ylbtech-System.Web.Mvc.IController.cs 1.程序集 System.Web.Mvc, Version=5.2.3.0, Culture=neutral, Public ...

  6. IO初步,字节输入流和字节输出流

    字节输出流 OutputStream(基类,抽象) 特点:写任意的文件 方法:写出数据的方法:write write(int b) 写出1个字节 -128~127之间,写的是一个ASCLL码的值 wr ...

  7. Django的日常-AJAX

    目录 Django的日常-AJAX AJAX简介 AJAX与JQ的一个实例 AJAX与contentType AJAX传json格式 AJAX传文件 Django的日常-AJAX AJAX简介 首先A ...

  8. wangEditor 菜单栏随页面滚动位置改变(吸顶)问题解决

    参考:https://www.kancloud.cn/wangfupeng/wangeditor2/113980 当页面向下滚动到隐藏了菜单栏时,编辑器默认会fixed菜单栏,即让菜单栏保持『吸顶』状 ...

  9. Python全栈开发:web框架们

    Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块. 1 2 3 ...

  10. 企业网盘居然支持高速局域网文件传输工具(速度可达20M)

    高速局域网文件传输工具Mobox,局域网内文件共享是公司内非常必须的功能,原本文件共享可以通过:1)windows目录共享目录来实现文件交互:2)通过U盘拷贝给对方:3)通过QQ发送给对方:4)通过邮 ...