def func(*args, **kwargs): if before: metric = get_metric(None) before(metric) else: metric = None exception = None start_time = default_timer() try: try: # execute the handler function response = f(*args, **kwargs) except Exception as ex: # let Flask decide to wrap or reraise the Exception response = current_app.handle_user_exception(ex) except Exception as ex: # if it was re-raised, treat it as an InternalServerError exception = ex response = make_response('Exception: %s' % ex, 500) total_time = max(default_timer() - start_time, 0) if not metric: if not isinstance(response, Response) and request.endpoint: view_func = current_app.view_functions[ request.endpoint] # There may be decorators 'above' us, # but before the function is registered with Flask while view_func and view_func != f: try: view_func = view_func.__wrapped__ except AttributeError: break if view_func == f: # we are in a request handler method response = make_response(response) elif hasattr(view_func, 'view_class') and isinstance( view_func.view_class, MethodViewType): # we are in a method view (for Flask-RESTful for example) response = make_response(response) metric = get_metric(response) metric_call(metric, time=total_time) if exception: try: # re-raise for the Flask error handler raise exception except Exception as ex: return current_app.handle_user_exception(ex) else: return response
def _check_unused_args_empty(response): if not g.unused_args or response.status_code >= 300: return response # exception raised here will not be passed to handlers # so, to be consistent, we call handler directly return current_app.handle_user_exception( exc.UnknownArgument(g.unused_args.pop()))
def batch(): """ Execute multiple requests, submitted as a batch. :statuscode 207: Multi status """ # TODO: we could probably turn off csrf protection for each requests # and only use the CSRF in the header of the parent request requests, err = RequestSchema().load(request.get_json(), many=True) responses = [] status_code = 207 for req in requests: method = req['method'] url = req['url'] body = req.get('body', None) headers = req.get('headers', {}) with current_app.app_context(): headers.setdefault('accept', 'application/json') with current_app.test_request_context(url, method=method, data=body, headers=headers): try: # Can modify flask.g here without affecting # flask.g of the root request for the batch # Pre process Request rv = current_app.preprocess_request() if rv is None: # Main Dispatch rv = current_app.dispatch_request() except Exception as e: rv = current_app.handle_user_exception(e) response = current_app.make_response(rv) # Post process Request response = current_app.process_response(response) # Response is a Flask response object. # _read_response(response) reads response.response # and returns a string. If your endpoints return JSON object, # this string would be the response as a JSON string. responses.append({ "status_code": response.status_code, "body": response.data.decode('utf-8'), "headers": [{'name': k, 'value': v} for k, v in response.headers.items()] }) # if error response if (response.status_code % 400 < 100) or (response.status_code % 400 < 100): status_code = response.status_code break return json.dumps(responses), status_code
def batch(): """ Execute multiple requests, submitted as a batch. :status code 207: Multi status :response body: Individual request status code Batch Request data Example: [ { "method": "PATCH", "path": "/party-api/v1/respondents/email", "body": respondent_email_3, "headers": <headers> }, { "method": "PATCH", "path": "/party-api/v1/respondents/email", "body": respondent_email_0, "headers": <headers> }, ] """ try: requests = json.loads(request.data) except ValueError as e: abort(400) responses = [] for index, req in enumerate(requests): method = req['method'] path = req['path'] body = req.get('body', None) headers = req.get('headers', None) with current_app.app_context(): with current_app.test_request_context(path, method=method, json=body, headers=headers): try: rv = current_app.preprocess_request() if rv is None: rv = current_app.dispatch_request() except Exception as e: rv = current_app.handle_user_exception(e) response = current_app.make_response(rv) response = current_app.process_response(response) responses.append({ "status": response.status_code, }) return make_response(json.dumps(responses), 207)
def handle_login_error(e): """Redirect to the login page when LoginError is raised. If the user is logged in but doesn't have permission, don't try to log in, it will result in an infinite loop. Raise 403 Forbidden instead. """ if not current_user.authenticated: return redirect_for('auth.login', next=request.path) # abort(403) # can't raise other handled exception from error handler, results in 500 # so simulate what flask would do try: abort(403) except Exception as e: return current_app.handle_user_exception(e)
def _default_invalid_session_handler(self): try: raise Unauthorized() except Exception as e: response = current_app.handle_user_exception(e) return response