from flask import has_request_context, _request_ctx_stack __all__ = ['after_request', 'defer', 'FlaskDefer'] def defer(func, *args, **kwargs): # If we are not in a request/app context, then just execute if not has_request_context(): return func(*args, **kwargs) ctx = _request_ctx_stack.top # We are in a request/app context, defer until request/app teardown params = dict(func=func, args=args, kwargs=kwargs) if not hasattr(ctx, 'deferred_tasks'): setattr(ctx, 'deferred_tasks', []) ctx.deferred_tasks.append(params) # Alias `defer` as `after_request` after_request = defer class FlaskDefer(object): def __init__(self, app=None): if app is not None: self.init_app(app) def init_app(self, app): app.teardown_request(self._execute_deferred) def _execute_deferred(self, exception): ctx = _request_ctx_stack.top if hasattr(ctx, 'deferred_tasks'): for params in ctx.deferred_tasks: params['func'](*params['args'], **params['kwargs'])