From 95b14bdd6c911c584d81a33e5ef42a5d67efdfe8 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 19 Jul 2008 23:45:57 +0000 Subject: Add wsgiapp decorator. --- repoze/bfg/tests/test_wsgi.py | 33 ++++++++++++++++++++++++++++++++ repoze/bfg/wsgi.py | 44 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 repoze/bfg/tests/test_wsgi.py create mode 100644 repoze/bfg/wsgi.py (limited to 'repoze') diff --git a/repoze/bfg/tests/test_wsgi.py b/repoze/bfg/tests/test_wsgi.py new file mode 100644 index 000000000..d905350d6 --- /dev/null +++ b/repoze/bfg/tests/test_wsgi.py @@ -0,0 +1,33 @@ +import unittest + +class WSGIAppTests(unittest.TestCase): + def test_decorator(self): + body = 'Unauthorized' + headerlist = [ ('Content-Type', 'text/plain'), + ('Content-Length', len(body)) ] + status = '401 Unauthorized' + def real_wsgiapp(environ, start_response): + start_response(status, headerlist) + return [body] + from repoze.bfg.wsgi import wsgiapp + wrapped = wsgiapp(real_wsgiapp) + context = DummyContext() + request = DummyRequest({}) + response = wrapped(context, request) + self.assertEqual(response.status, status) + self.assertEqual(response.headerlist, headerlist) + self.assertEqual(response.app_iter, [body]) + +class DummyContext: + pass + +class DummyRequest: + def __init__(self, environ): + self.environ = environ + + + + + + + diff --git a/repoze/bfg/wsgi.py b/repoze/bfg/wsgi.py new file mode 100644 index 000000000..4efe40afc --- /dev/null +++ b/repoze/bfg/wsgi.py @@ -0,0 +1,44 @@ +from webob import Response + +def wsgiapp(wrapped): + """ Decorator to turn a WSGI application into a repoze.bfg view callable. + + E.g.:: + + @wsgiapp + def hello_world(environ, start_response): + body = 'Hello world' + start_response('200 OK', [ ('Content-Type', 'text/plain'), + ('Content-Length', len(body)) ] ) + return [body] + + Allows the following view declaration to be made:: + + + + The wsgiapp decorator will convert the result of the WSGI + application to a Response and return it to repoze.bfg as if the + WSGI app were a repoze.bfg view. + """ + def _curried(context, request): + caught = [] + def catch_start_response(status, headers, exc_info=None): + caught[:] = (status, headers, exc_info) + environ = request.environ + body = wrapped(environ, catch_start_response) + if caught: + status, headers, exc_info = caught + response = Response() + response.app_iter = body + response.status = status + response.headerlist = headers + return response + else: + raise RuntimeError('WSGI start_response not called') + _curried.__name__ = wrapped.__name__ + return _curried + -- cgit v1.2.3