Created
July 11, 2019 08:47
-
-
Save ReallyLiri/316c4ac98a37574efb7f6880f167a15c to your computer and use it in GitHub Desktop.
Flask resource with http method logic injection capability
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 functools import wraps | |
from flask_restplus import Resource | |
HTTP_METHODS = ["get", "post", "delete", "put", "patch"] | |
class InjectableResource(Resource): | |
def hook_all_http_methods(self, pre_execution=None, post_execution=None, exception_handler=None): | |
for method in HTTP_METHODS: | |
self.register_hook(method, pre_execution, post_execution, exception_handler) | |
def register_hook(self, method, pre_execution=None, post_execution=None, exception_handler=None): | |
""" | |
Create new hook to decorate requests | |
:param method: http method (GET/POST ..) | |
:param pre_execution: decorator to run before the exeuction of this method, will accept wrapped func as parameter | |
:param post_execution: decorator to run after the exeuction of this method, will accept wrapped func and return value as parameters | |
:param exception_handler: decorator to run in case of exeuction exception, will accept wrapped func and exception as parameters | |
""" | |
def wrap_with_hook_dec(fn, hook_pre, hook_post, hook_exception): | |
@wraps(fn) | |
def real_dec(*args, **kwargs): | |
result = None | |
try: | |
if hook_pre: | |
hook_pre(fn, args, kwargs) | |
result = fn(*args, **kwargs) | |
return result | |
except Exception as ex: | |
if hook_exception: | |
hook_exception(fn, ex) | |
raise | |
finally: | |
if hook_post: | |
hook_post(fn, result, args, kwargs) | |
return real_dec | |
if hasattr(self, method): | |
setattr(self, method, wrap_with_hook_dec(getattr(self, method), pre_execution, post_execution, exception_handler)) | |
# example usage: | |
class LocaleResource(InjectableResource): | |
"""Wrapper to set up locale attribute according to request headers""" | |
__language_options__ = ['en', 'he'] | |
def __init__(self, *args, **kwargs): | |
super(LocaleResource, self).__init__(*args, **kwargs) | |
self.locale = None | |
self.hook_all_http_methods(self.language_hook) | |
def language_hook(self, fn, args, kwargs): | |
self.locale = request.accept_languages.best_match(self.__language_options__) or "en" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment