wsgi.py
author Tero Marttila <terom@fixme.fi>
Mon, 16 Feb 2009 19:02:59 +0200
changeset 77 bef7196f7682
parent 72 5160b9e0edf1
permissions -rw-r--r--
add tree_parse test and fix treeparse to handle other than filesystem paths
7
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
"""
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
    WSGI application implementation
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
"""
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
# for error reporting
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
import sys, traceback
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
# for Request/Response
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
import http
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
31
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    12
class Application (object) :
7
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
    """
31
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    14
        Our WSGI application, implements the wsgi __call__ interface
7
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
    """
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
31
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    17
    def __init__ (self, handler) :
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    18
        """
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    19
            Initialize to use the given handler for requests
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    20
        """
30
a86a25a9f75b route requests through sites/www.qmsk.net, although still hardcoded
Tero Marttila <terom@fixme.fi>
parents: 7
diff changeset
    21
31
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    22
        self.handler = handler
7
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
    
31
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    24
    def handle_request (self, env, start_response) :
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    25
        """
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    26
            The actual request handling code
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    27
        """
7
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
31
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    29
        # build Request object
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    30
        request = http.Request(env)
7
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
31
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    32
        try :
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    33
            # request -> response using our handler
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    34
            response = self.handler.handle_request(request)
7
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
31
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    36
        except http.ResponseError, err :
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    37
            # just use the generated response
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    38
            response = err.get_response()
7
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
31
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    40
        # send response
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    41
        assert response, "No response"
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    42
        
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    43
        # send response status/headers
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    44
        start_response(response.get_status(), response.get_headers())
7
d6a8258bd90e YES YES MOAR WSGI - Hello World
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
31
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    46
        # send respones data
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    47
        yield response.get_data()
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    48
72
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    49
    def handle_error (self, exc_info, env, start_response) :
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    50
        """
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    51
            Handle errors thrown by handle_request. This should call start_response with the exc_info and return the
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    52
            error message (i.e. str), otherwise the error will be thrown up yet another level.
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    53
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    54
            Note that e.g. unicode is a failure...
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    55
        """
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    56
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    57
        # try and send 500 ISE to browser, if no headers yet...
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    58
        start_response("500 Internal Server Error", [('Content-type', "text/plain; charset=UTF-8")], exc_info)
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    59
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    60
        # format traceback
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    61
        data = ''.join(traceback.format_exception(*exc_info))
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    62
        
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    63
        # no unicode, kplzthx
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    64
        return data.encode('utf-8')
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    65
    
31
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    66
    def __call__ (self, env, start_response) :
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    67
        """
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    68
            Wraps handle_request to trap errors
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    69
        """
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    70
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    71
        try :
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    72
            # passthrough request_handler
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    73
            for chunk in self.handle_request(env, start_response) :
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    74
                yield chunk
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    75
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    76
        except :
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    77
            # execption info
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    78
            info = sys.exc_info()
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    79
72
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    80
            # handle
5160b9e0edf1 move wsgi.Application error handling to handle_error method
Tero Marttila <terom@fixme.fi>
parents: 46
diff changeset
    81
            yield self.handle_error(info, env, start_response)
31
107062ebb6f9 bloat code with even more layers of indirection, split off the filesystem-based stuff into a separate lib.filesystem package (next, move it to sites/www.qmsk.net)
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
    82