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.

Advertisement