可调整的请求接口。
repoze.bfg.httprequest的Python项目详细描述
概述
此包的动机是鼓励使用请求 类型调整,而不是依赖于具有请求类型的包 定义。
我们鼓励 适应模式:
>>> 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."""
学分
斯特凡·埃勒佐夫和马尔特·博奇 <;mborch@gmail.com>;。
可调整的http请求接口
假设我们希望对“http-accept-u编码”的请求进行调整 这需要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模块定位。为了解决这个问题,一个导入钩子 在包初始化时添加。
(repoze.bfgpackages pickle配置操作以便 提高启动时间,因此 接口是可选择的。)
>>> from pickle import dumps, loads >>> p = dumps(IGZipRequest)
现在,我们假设repoze.bfg.httprequest.interfaces有 尚未导入。这将使pickle在加载时导入它 把泡菜倒回去。
>>> import sys >>> del sys.modules['repozehttprequestinterfaces']
我们将重新初始化接口模块。
>>> loads(p) <IHTTPRequest http_accept_encoding=gzip>