summaryrefslogtreecommitdiff
path: root/repoze/bfg/wsgi.py
blob: 4efe40afc77153a801853e537244ec728424112a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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::

       <bfg:view
            view=".views.hello_world"
            name="hello_world.txt"
            context="*"
            />

    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