Fun with decorators on the Google AppEngine
Tuesday, July 22nd, 2008Well I thought I’d give writing for the Google AppEngine a try and have found it a delightful platform to work with. Easy deployment, easy scalability (the DataStore non-RDBMS is a bit harder to get your mind around), and a squeaky clean WebOb-based WSGI minimalist framework called WebApp. Anyways, in developing a simple REST service, I ran across a great place to use Python Decorators. I needed to restrict access to a specific REST method based on IP Address so I wrote the following decorator:
1 2 3 4 5 6 7 8 9 | def bind_ip(ips): def _dec(handler): def _check_ip(self, *args, **kwargs): if self.request.remote_addr in ips: return handler(self, *args, **kwargs) else: self.error(403) return _check_ip return _dec |
The decorator returns a closure which only calls the method it encapsulates if the IP address of the client is specifically allowed. Notice the @bind_ip on line 11
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import wsgiref.handlers from google.appengine.ext import webapp from util import bind_ip allowed_ips = set([ '127.0.0.1', 'ip.of.rest.client' ]) class SecretHandler(webapp.RequestHandler): @bind_ip(allowed_ips) def get(self, secret): """ Do something Secret """ self.response.out.write (secret) def main(): application = webapp.WSGIApplication([ (r'/secret/(.*)', SecretHandler) ]) wsgiref.handlers.CGIHandler().run(application) if __name__ == '__main__': main() |
Decorators are a simple way to easily annotate how functions should be called, and can be used for Authentication, Data Validation or however else you’d like to use them.

