Skip to content

Instantly share code, notes, and snippets.

@jarmoj
Created October 17, 2013 07:13
Show Gist options
  • Save jarmoj/7020399 to your computer and use it in GitHub Desktop.
Save jarmoj/7020399 to your computer and use it in GitHub Desktop.
Using Python metaclass to create a metaclass factory that decorates all tornado handler methods with tornado.web.authenticated when a handler inherits from AuthenticatedHandler.
import tornado.web
class BaseHandler(tornado.web.RequestHandler):
pass
def MetaClassFactory(function):
class MetaClass(type):
def __new__(meta, classname, bases, classDict):
newClassDict = {}
supported_methods = ("GET", "HEAD", "POST", "DELETE", "PATCH",
"PUT", "OPTIONS")
for method_name in [m.lower() for m in supported_methods]:
if method_name not in classDict:
continue
method = classDict[method_name]
newMethod = function(method)
newClassDict[method_name] = newMethod
return type.__new__(meta, classname, bases, newClassDict)
return MetaClass
AlwaysAuthenticated = MetaClassFactory(tornado.web.authenticated)
class AuthenticatedHandler(BaseHandler):
__metaclass__ = AlwaysAuthenticated
def head(self, *args, **kwargs):
raise HTTPError(405)
def get(self, *args, **kwargs):
raise HTTPError(405)
def post(self, *args, **kwargs):
raise HTTPError(405)
def delete(self, *args, **kwargs):
raise HTTPError(405)
def patch(self, *args, **kwargs):
raise HTTPError(405)
def put(self, *args, **kwargs):
raise HTTPError(405)
def options(self, *args, **kwargs):
raise HTTPError(405)
class NotAuthenticatedHandler(BaseHandler):
def head(self, *args, **kwargs):
raise HTTPError(405)
def get(self, *args, **kwargs):
raise HTTPError(405)
def post(self, *args, **kwargs):
raise HTTPError(405)
def delete(self, *args, **kwargs):
raise HTTPError(405)
def patch(self, *args, **kwargs):
raise HTTPError(405)
def put(self, *args, **kwargs):
raise HTTPError(405)
def options(self, *args, **kwargs):
raise HTTPError(405)
class SomeHandler(NotAuthenticatedHandler):
def get(self):
self.render("index.html", user=self.current_user)
class SomeOtherHandler(AuthenticatedHandler):
def get(self):
self.render("other.html", user=self.current_user)
# ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment