Bottle is a great little Web application framework, but in it’s quest for simplicity, it left out a couple of key components that are needed for cu3w0rx: HTTP method overriding and basic authentication. Luckily Python’s WSGI middleware can fulfill this role.
WSGI Middleware
WSGI middleware is a handy way to add functionality to an application by adding layers to the request/response chain in between the client request and your application. Incidently, Ruby’s Rack project took inspiration from WSGI middleware.
Method Overriding
A while back I bemoaned the fact that CherryPy’s RoutedDispatcher could not handle PUT and DELETE requests from forms submitted by your typical web browser, which most often only does GET and POST requests. I submitted a patch to the CherryPy project, but I now believe that this is the wrong approach, and that middleware can handle altering the REQUEST_METHOD header in response to a submitted form with a hidden “_method” parameter, as is the accepted convention. Here is some middleware for the server side application which will resige on GAE:
# method_overide.py
# WSGI middleware to set the HTTP REQUEST_METHOD header from a submitted form
# that contains a "_method" hidden variable.
class MethodOverride(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
method = webapp.Request(environ).get('_method')
if method:
environ['REQUEST_METHOD'] = method.upper()
return self.app(environ, start_response)
And here is how you would insert it in between your bottle application:
from bottle import *
from google.appengine.ext.webapp import util
from method_override import MethodOverride
@route("/test_put",method="PUT")
def testput():
return "PUT success"
@route("/test_delete",method="DELETE")
def testdelete():
return "DELETE success"
# run in GAE
def main():
app= default_app()
# insert the method override middleware
app = MethodOverride(default_app())
util.run_wsgi_app(app)
if __name__ == '__main__':
main()
Now forms that define the REQUEST_METHOD as a hidden param “_method” will be routed to the correct function.

4 comments
November 1, 2009 at 6:37 am
Justin Sanders
You might want to take a look at juno. It’s also inspired by sinatra but doesn’t require this to get all rest operations working.
http://github.com/breily/juno/
November 2, 2009 at 5:26 pm
delagoya
Juno looked pretty similar to Bottle, with the exception that it relies on SQLALchemy for DB access (Bottle’s default is a simple key-value store) and Beaker for sessions. I didn’t see authentication, but admittedly I didn’t look too hard. Will definitely keep it on my radar, thanks!
November 3, 2009 at 7:52 am
Marcel Hellkamp
Bottle can handle any request method you like. You just have to tell the router to watch for it. The following code works with Bottle since its first release.
@route(“/test”, method=”PUT”)
@route(“/test”, method=”POST”)
@route(“/test”) #method=”GET”
def test():
return “%s success” % request.method
November 3, 2009 at 2:05 pm
delagoya
Yes, I know.
The use of middleware in the post was for setting the proper HTTP method from a request originating from a web form, which can only do GET and POST request. If you want to do a PUT request, to emulate a RESTful web API, then you need to settle on a convention to reliably alter the the HTTP REQUEST_METHOD header in the form. Most frameworks do this by specifying a hidden parameter “_method” with the value = “PUT” (or DELETE or HEAD) in the form so that the framework can “do the right thing” with the request.