Skip to content

Instantly share code, notes, and snippets.

@ReallyLiri
Created July 11, 2019 08:47
Show Gist options
  • Save ReallyLiri/316c4ac98a37574efb7f6880f167a15c to your computer and use it in GitHub Desktop.
Save ReallyLiri/316c4ac98a37574efb7f6880f167a15c to your computer and use it in GitHub Desktop.
Flask resource with http method logic injection capability
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