跳转到主要内容

可调整的请求接口。

项目描述

概述

该软件包的动机是鼓励使用请求类型适配而不是依赖于带有请求类型定义的软件包。

我们鼓励使用适配模式而不是继承请求接口

>>> from repoze.bfg.interfaces import IRequest
>>> IGZipRequest = IRequest({'http_accept_encoding': 'gzip'})

事件处理器监听INewRequest事件,并自动将请求标记为所需的接口,以适配请求到可能应用的请求类型。

为了完成上面的示例,一个请求将包含如下的HTTP环境

{‘http_accept_encoding’: ‘compress, gzip’}

由于我们已经将请求适配到‘gzip’的接受编码,适配机制将标记接口,使此环境与IGZipRequest接口匹配。

这将是子类化的替代方案,我们不需要手动设置事件监听器来解释请求环境并标记请求接口。

>>> class IGZipRequest(IRequest):
...     """Marker interface for requests for gzipped response."""

致谢

Stefan Eletzhofer <stefan.eletzhofer@inquant.de> 和 Malthe Borch <mborch@gmail.com>。

可调整的HTTP请求接口

假设我们想调整具有“http_accept_encoding”的请求,该请求要求返回gzip压缩的响应,我们将设置如下接口

>>> from repoze.bfg.interfaces import IRequest
>>> IGZipRequest = IRequest({'http_accept_encoding': 'gzip'})

现在让我们构建一个符合该接口的请求。

>>> class TestRequest(object):
...     interface.implements(IRequest)
...
...     def __init__(self, environ):
...         self.environ = environ
>>> request = TestRequest({'http_accept_encoding': 'compress, gzip'})

到目前为止,请求还没有为调整做好准备。

>>> from repoze.bfg.events import NewRequest
>>> from zope.event import notify
>>> notify(NewRequest(request))

我们期望请求实现IGZipRequest接口。

>>> IGZipRequest.providedBy(request)
True

为了获得更多灵活性,我们可以提供一个匹配函数

>>> IAlternativeGZipRequest = IRequest(
...    {'http_accept_encoding': lambda value: 'gzip' in value})
>>> notify(NewRequest(request))
>>> IAlternativeGZipRequest.providedBy(request)
True

假设现在我们还想支持德语文档的请求。

>>> IGermanLanguageRequest = IRequest({'http_accept_language': 'de'})

我们将创建一个新的请求,除了要求gzip压缩响应外,还要求内容为德语。

>>> request = TestRequest(
...     {'http_accept_encoding': 'compress, gzip', 'http_accept_language': 'de'})
>>> notify(NewRequest(request))

验证请求是否提供了调整后的接口。

>>> IGermanLanguageRequest.providedBy(request)
True
>>> IGZipRequest.providedBy(request)
True

现在,正如您所期望的,我们可以调整一个结合这两个环境的请求接口。

>>> IZippedGerman = IRequest(
...    {'http_accept_encoding': 'gzip', 'http_accept_language': 'de'})
>>> notify(NewRequest(request))
>>> IZippedGerman.providedBy(request)
True

请注意,此接口扩展了为它创建的每个环境对的两个接口。

>>> IZippedGerman.isOrExtends(IGermanLanguageRequest)
True
>>> IZippedGerman.isOrExtends(IGZipRequest)
True

让我们尝试一个不匹配的请求。

>>> IZippedFrench = IRequest(
...     {'http_accept_encoding': 'gzip', 'http_accept_language': 'fr'})
>>> notify(NewRequest(request))
>>> IZippedFrench.providedBy(request)
False

调整后的请求相对于环境是全局的

>>> IRequest({'http_accept_encoding': 'gzip'}) is IRequest({'http_accept_encoding': 'gzip'})
True

Pickle支持

调整后的接口是动态创建的,因此无法由pickle模块定位。为了解决这个问题,在包初始化时添加了一个导入钩子。

(repoze.bfg包将配置操作序列化以改进启动时间,因此调整后的接口需要可序列化非常重要。)

>>> from pickle import dumps, loads
>>> p = dumps(IGZipRequest)

现在,我们将假装尚未导入repoze.bfg.httprequest.interfaces。这将在我们加载pickle时使pickle导入它。

>>> import sys
>>> del sys.modules['repozehttprequestinterfaces']

我们将重新初始化接口模块。

>>> loads(p)
<IHTTPRequest http_accept_encoding=gzip>

项目详细信息


下载文件

下载适用于您的平台的文件。如果您不确定要选择哪个,请了解有关安装软件包的更多信息。

源分布

repoze.bfg.httprequest-0.4.2.tar.gz (6.9 kB 查看哈希值)

上传时间

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面