Last active
August 15, 2023 22:09
-
-
Save cowbert/f357391fd2d140f817e8d90e781bd15d to your computer and use it in GitHub Desktop.
class decorators with staticmethod
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from tornado.web import RequestHandler | |
class BaseHandler(RequestHandler): | |
def prepare(self): | |
self.current_user = None | |
def _render_401(self): | |
if self._req_was_rest: | |
self.set_status(401) | |
self.set_header('WWW-Authenticate', | |
'Bearer realm="{}"'.format( | |
self.request.uri | |
)) | |
self.finish() | |
else: | |
self.redirect(self._CONFIG['auth'] + | |
'/sso/auth?appname={}&orig_uri={}'.format( | |
self._CONFIG['app_name'], | |
urlparse.quote(self.request.full_url()) | |
) | |
) | |
class AuthorizedHandler(BaseHandler): | |
@staticmethod | |
def requires_login(method): | |
def decorated(self, *args, **kwargs): | |
if not self.current_user: | |
self._render_401() | |
else: | |
return method(self, *args, **kwargs) | |
return decorated | |
class FooHandler(AuthorizedHandler): | |
@AuthorizedHandler.requires_login | |
def get(self, *args, **kwargs): | |
self.render('foo.html') |
I came from the same SO post. This pattern does not work correctly with positional arguments as written. Self needs to be treated as an implicit positional argument, then pulled out from the variadic args.
@staticmethod
def requires_login(method):
def decorated(*args, **kwargs):
self=args[0]
if not self.current_user:
self._render_401()
else:
return method(self, *args, **kwargs)
return decorated
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I came from https://stackoverflow.com/questions/13852138/how-can-i-define-decorator-method-inside-class
This is a nice pattern! I'll probably use it everywhere now. =)