Filters¶
Filters are a collection of useful(in the authors opinion) wsgi middleware that is more client-centric than server-centric, you may find it useful too.
http_capture_filter¶
this filter captures the request and response and calls a function you provide so that you can do what you will. it’s important to note that the request and response you recieve are copies and modifying them does not effect the request or the response going to the application or client.
It is primarily used by the http_log_filter
def http_capture_filter(app, callback=lambda request, response: True):
"""
captures request and response and passes off to a callback
:rtype: :ref:`wsgi_application`
:param app: inner :ref:`wsgi_application`
:param callback: function to call
"""
def m(environ, start_response):
request = Request(environ)
response = request.get_response(app)
callback(request.copy(), response.copy())
return response(environ, start_response)
return m
http_log_filter¶
The http_log_filter will log both the request and the response to the log_level you provide. The default level is “DEBUG”, it’s handy when you need to see what the http traffic looks like in your application, but using it in production would insure you have huge log files that you would likely never read.
def http_log_filter(app, level="DEBUG"):
"""
logs the request and response to the logger http_log at whatever
level you specify
:rtype: :ref:`wsgi_application`
:param app: inner :ref:`wsgi_application`
:param level: log level
"""
level_int = logging._checkLevel(level)
log = logging.getLogger("http_log")
def _log_it(request, response):
log.log(level=level_int, msg=l.PRINT_REQ(request))
log.log(level=level_int, msg=l.PRINT_RES(response))
return http_capture_filter(app, callback=_log_it)
charset_filter¶
Some websites won’t specify a charset on the response, this can sometimes be problematic. this filter will check if the charset attribute is set, and if it isn’t it will set it to utf8 which is a pretty safe bet in most cases.
def charset_filter(app):
"""
if charset is missing, set it to a pretty much safe utf8
:rtype: :ref:`wsgi_application`
:param app: inner :ref:`wsgi_application`
"""
def m(environ, start_response):
request = Request(environ)
res = request.get_response(app)
if not res.charset:
res.charset = "utf8"
return res(environ, start_response)
return m
decode_filter¶
Websites can return compressed responses. This filter will handle de-compressing them if a compressed response is detected.
def decode_filter(app):
"""
decode the content(in case it's gzipped)
BUG: for some reason, appengine doesn't respond to this and
doesn't send gziped when asked.
:rtype: :ref:`wsgi_application`
:param app: inner :ref:`wsgi_application`
"""
def m(environ, start_response):
request = Request(environ)
request.accept_encoding = "gzip"
response = request.get_response(app)
response.decode_content()
return response(environ, start_response)
return m
assert_filter¶
Sometimes you want to raise an error if you get a response under certain conditions. This filter allows you to specify a function to do that assertion before the response is returned. The function you specify will be passed a copy of the request and response.
def assert_filter(app, assert_=lambda request, response: True):
"""
will allow for assertions to be made on the request and response.
:rtype: :ref:`wsgi_application`
:param app: inner :ref:`wsgi_application`
"""
def m(environ, start_response):
request = Request(environ)
response = request.get_response(app)
assert_(request.copy(), response.copy())
return response(environ, start_response)
return m
cookie_filter¶
Sometime when you are communicating with wsgi applications over several requests, you need to handle the cookies in order for the application to respond correctly, for example if you have to login before doing anything else. This filter handles all the gory details of cookie handling for you.
def cookie_filter(app):
"""
intercepts req/res and keeps track of cookies
:rtype: :ref:`wsgi_application`
:param app: inner :ref:`wsgi_application`
"""
jar = CookieJar()
def m(environ, start_response):
request = Request(environ)
jar.add_cookie_header(RequestCookieAdapter(request))
response = request.get_response(app)
cookies = jar.make_cookies(ResponseCookieAdapter(response),
RequestCookieAdapter(request))
for c in cookies:
jar.set_cookie(c)
return response(environ, start_response)
return m
Usage¶
Filters can be combined to suit your needs. For example you could compose a wsgi application to support cookies and compressed responses and raise an error if the inner application responds with a status code of “401”, which means access denied.
"""
using filters
"""
from webobtoolkit import filters
from webob import Request, Response
import datetime
def time_application(environ, start_response):
body = "the current time is %s " % datetime.datetime.now().isoformat()
return Response(body)(environ, start_response)
# add cookie support
application = filters.cookie_filter(time_application)
# decompress the response if it is compressed
application = filters.decode_filter(time_application)
# raise an error the app returns something other than a 200 success
# response
def assert_success(request, response):
assert response.status_int == 200, "the request was not sucessful"
application = filters.assert_filter(time_application, assert_=assert_success)
response = Request.blank("/").get_response(application)
print str(response)
Reference¶
filters for taking care of various aspects of HTTP
-
class
webobtoolkit.filters.RequestCookieAdapter(request)¶ this class merely provides the methods required for a cookielib.CookieJar to work on a webob.Request
potential for yak shaving...very high
-
class
webobtoolkit.filters.ResponseCookieAdapter(response)¶ this class merely provides methods required for a cookielib.CookieJar to work on a webob.Response
-
webobtoolkit.filters.assert_filter(app, assert_=<function <lambda>>)¶ will allow for assertions to be made on the request and response.
Return type: WSGI Application Parameters: app – inner WSGI Application
-
webobtoolkit.filters.auto_redirect_filter(app, limit=10)¶ intercepts response, if response.status is redirectish(301, 302) will make the next call
-
webobtoolkit.filters.charset_filter(app)¶ if charset is missing, set it to a pretty much safe utf8
Return type: WSGI Application Parameters: app – inner WSGI Application
intercepts req/res and keeps track of cookies
Return type: WSGI Application Parameters: app – inner WSGI Application
-
webobtoolkit.filters.decode_filter(app)¶ decode the content(in case it’s gzipped)
BUG: for some reason, appengine doesn’t respond to this and doesn’t send gziped when asked.
Return type: WSGI Application Parameters: app – inner WSGI Application
-
webobtoolkit.filters.http_capture_filter(app, callback=<function <lambda>>)¶ captures request and response and passes off to a callback
Return type: Parameters: - app – inner WSGI Application
- callback – function to call
-
webobtoolkit.filters.http_log_filter(app, level='DEBUG')¶ logs the request and response to the logger http_log at whatever level you specify
Return type: Parameters: - app – inner WSGI Application
- level – log level