def test_configure_connexion_error_handlers(): graph = Mock() configure_connexion_error_handler(graph) graph.flask.register_error_handler.assert_has_calls([ call(code, graph.connexion_error_handler.handle) for code in default_exceptions.keys() ] + [ call(Exception, graph.connexion_error_handler.handle) ]) assert_that(graph.flask.register_error_handler.call_count, is_(equal_to(len(default_exceptions.keys()) + 1)))
def configure_app(app, config=None): if config is not None: app.config.from_object(config) else: try: app.config.from_object('localconfig.LocalConfig') except ImportError: app.config.from_object('hrs.config.DevelopmentConfig') @app.after_request def add_cors_headers(response): if 'Origin' in request.headers: a = response.headers.add a('Access-Control-Allow-Origin', request.headers['Origin']) a('Access-Control-Allow-Credentials', 'true') a('Access-Control-Allow-Headers', 'Content-Type,Authorization') a('Access-Control-Allow-Methods', 'GET,PUT,PATCH,POST,DELETE') return response def make_json_error(ex): err = {'error': str(ex)} if hasattr(ex, 'data') and 'messages' in ex.data: err.update({'messages': ex.data['messages']}) return make_response(err, ex.code if isinstance(ex, HTTPException) else 500) for code in default_exceptions.keys(): app.register_error_handler(code, make_json_error)
def register_general_error_handler(blueprint_or_app, handler): error_codes = default_exceptions.keys() if isinstance(blueprint_or_app, Blueprint): error_codes.remove(500) # Flask doesn't currently allow per-Blueprint HTTP 500 error handlers for err_code in error_codes: blueprint_or_app.errorhandler(err_code)(handler)
def create_app(config_obj=None): """ Create a Flask application object. :return: a Flask application object :rtype: flask.Flask """ app = Flask(__name__) if config_obj: app.config.from_object(config_obj) else: load_config(app) if app.config[ 'PRODUCTION'] and app.secret_key == 'replace-me-with-something-random': raise Warning( 'You need to change the app.secret_key value for production') # Set the Neo4j connection URI based on the Flask config neomodel_config.DATABASE_URL = app.config.get('NEO4J_URI') init_logging(app) for status_code in default_exceptions.keys(): app.register_error_handler(status_code, json_error) app.register_error_handler(ValidationError, json_error) app.register_error_handler(ServiceUnavailable, json_error) app.register_error_handler(AuthError, json_error) app.register_blueprint(api_v1, url_prefix='/api/v1') app.after_request(insert_headers) return app
def JsonApp(app): """ The JsonApp function wraps a Flask app instance, and sets up the custom JSON error handler for every 4xx and 50x error that might occur. :param app: :return: """ def error_handling(error): if isinstance(error, HTTPException): result = { 'code': error.code, 'description': error.description, 'message': str(error) } else: description = "Sorry abort mapping isn't an object available on tis function" # abort.mapping[500].description result = { 'code': 500, 'description': description, 'message': str(error) } resp = jsonify(result) resp.status_code = result['code'] return resp for code in default_exceptions.keys(): app.register_error_handler(code, error_handling) return app
def make_json_app(import_name, **kwargs): """ Create a JSON-oriented Flask app. All error responses that you don't specifically manage yourself will have application/json content type, and will contain JSON like this (just an example): { "message": "405: Method Not Allowed" } """ def make_json_error(ex): pprint.pprint(ex) # pprint.pprint(ex.code) response = jsonify(message=str(ex)) #response = jsonify(ex) response.status_code = (ex.code if isinstance(ex, HTTPException) else 500) pprint.pprint(response) return response app = Flask(import_name, **kwargs) #app.debug = True app.secret_key = id_generator(24) for code in default_exceptions.keys(): app.error_handler_spec[None][code] = make_json_error return app
def setup_error_handlers(app): # make all error responses json for code in default_exceptions.keys(): app.register_error_handler(code, make_json_error) @app.errorhandler(APIError) def handle_api_error(e): response = jsonify(e.serialize) response.status_code = e.status_code return response @app.errorhandler(RedirectException) def handle_redirect_error(e): return redirect(url_for(e.endpoint), code=e.code) @app.errorhandler(SC.UNPROCESSABLE) def handle_flask_apispec_errors(err): exc = getattr(err, 'exc') messages = exc.messages if exc else ['Invalid request'] return jsonify({'messages': messages}), SC.UNPROCESSABLE # Catch 500's @app.errorhandler(SC.SERVERERR) def handle_exceptions(error): if config.app.debug: raise return make_json_error(error)
def register(self, app): from werkzeug.exceptions import default_exceptions for code in default_exceptions.keys(): app.register_error_handler(code, handle_http_error) app.register_error_handler(ApiError, handle_api_error) app.register_error_handler(BasicAuthError, handle_basic_auth_error) app.register_error_handler(Exception, handle_exception)
def JsonApp(app): def error_handling(error): print(error) if isinstance(error, HTTPException): result = { 'code': error.code, 'description': error.description, 'message': str(error) } else: # description = abort.mapping[500].description description = "服务器 500错误" result = { 'code': 500, 'description': description, 'message': str(error) } resp = jsonify(result) resp.status_code = result['code'] return resp print(default_exceptions) for code in default_exceptions.keys(): print(code) app.register_error_handler(code, error_handling) return app
def make_json_app(import_name, **kwargs): """ Creates a JSON-oriented Flask app. All error responses that you don't specifically manage yourself will have application/json content type, and will contain JSON like this (just an example): { "message": "405: Method Not Allowed" } http://flask.pocoo.org/snippets/83/ """ def make_json_error(ex): response = jsonify(message=str(ex)) response.status_code = (ex.code if isinstance(ex, HTTPException) else 500) return response app = Flask(import_name, static_folder='rapidpro_webhooks/static', **kwargs) for code in default_exceptions.keys(): @app.errorhandler(code) def page_not_found(error): return make_json_error(error), code return app
def init_application(): app.register_blueprint(keyboard, url_prefix="/api") app.register_blueprint(key, url_prefix="/api") for code in default_exceptions.keys(): app.register_error_handler(code, make_errors_json) app.json_encoder = JSONEncoder return app
def JsonApp(app): def error_handling(error): if isinstance(error, HTTPException): result = { 'code': error.code, 'description': error.description, 'message': str(error) } else: # the following doesnt work #description = abort.mapping[500].description result = { 'code': 500, 'description': "500 error", 'message': str(error) } resp = jsonify(result) resp.status_code = result['code'] return resp for code in default_exceptions.keys(): app.register_error_handler(code, error_handling) return app
def make_json_app(import_name, **kwargs): """ Creates a JSON-oriented Flask app. All error responses that you don't specifically manage yourself will have application/json content type, and will contain JSON like this (just an example): { "message": "405: Method Not Allowed" } """ def make_json_error(ex): pprint.pprint(ex) pprint.pprint(ex.code) # response = jsonify(message=str(ex)) response = json.dumps(ex) response.status_code = ex.code if isinstance(ex, HTTPException) else 500 return response app = Flask(import_name, **kwargs) # app.debug = True app.secret_key = id_generator(24) for code in default_exceptions.keys(): app.error_handler_spec[None][code] = make_json_error return app
def add_blueprint_error_handlers(self, blueprint): """Applys custom error handlers to the blueprint via the `flask.Flask.Blueprint.app_errorhandler' decorator. A decorator is applied for each error code present in `werkzeug.exceptions.default_exceptions` By default werkzueg exceptions are returned in HTML format. This can pose a problem for RESTful api's since the client will be expecting JSON formatted responses. A decorator is applied for each error code present in `werkzeug.exceptions.default_exceptions`. The custom decorator will convert any exceptions raised by werkzeug into JSON format. """ for code in default_exceptions.keys(): @blueprint.app_errorhandler(code) def http_exception_json_response(ex): """ Convert werkzeug http exceptions into a JSON response. `ex` is an Exception raised by `werkzueg.exceptions`. """ response = jsonify(message=str(ex)) if isinstance(ex, HTTPException): for header in ex.get_response().headers: if header[0] == 'Allow': response.headers['Allow'] = header[1] response.status_code = (ex.code if isinstance(ex, HTTPException) else 500) self.app.logger.exception(str(ex)) return response
def create_app(config_name): """Create app endpoints""" from .views.category import cat from .views.client import cli from .views.feature import feat app = Flask(__name__, static_url_path="") for code in default_exceptions.keys(): app.errorhandler(code)(make_json_error) app.json_encoder = CustomJSONEncoder app.config.from_object(app_config[config_name]) app.config.from_pyfile('config.py') app._static_folder = "../static" app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db.init_app(app) app.register_blueprint(cat) app.register_blueprint(feat) app.register_blueprint(cli) @app.route('/', methods=['GET']) def root(): return app.send_static_file("index.html") return app
def create_app(config_obj=None): """ Create a Flask application object. :return: a Flask application object :rtype: flask.Flask """ app = Flask(__name__) if config_obj: app.config.from_object(config_obj) else: load_config(app) if app.config[ 'PRODUCTION'] and app.secret_key == 'replace-me-with-something-random': raise RuntimeError( 'You need to change the app.secret_key value for production') elif app.config['ENABLE_AUTH']: base_error = 'The "{0}" configuration must be set if authentication is enabled' if not app.config['OIDC_INTROSPECT_URL']: raise RuntimeError(base_error.format('OIDC_INTROSPECT_URL')) elif not app.config['OIDC_CLIENT_ID']: raise RuntimeError(base_error.format('OIDC_CLIENT_ID')) elif not app.config['OIDC_CLIENT_SECRET']: raise RuntimeError(base_error.format('OIDC_CLIENT_SECRET')) # Set the Neo4j connection URI based on the Flask config neomodel_config.DATABASE_URL = app.config.get('NEO4J_URI') if app.config['ENABLE_AUTH']: # Import this here so that flask_oidc isn't required to run the app if authentication is # disabled from estuary.auth import EstuaryOIDC app.oidc = EstuaryOIDC(app) init_logging(app) for status_code in default_exceptions.keys(): app.register_error_handler(status_code, json_error) app.register_error_handler(ValidationError, json_error) app.register_error_handler(ServiceUnavailable, json_error) app.register_error_handler(AuthError, json_error) app.register_blueprint(api_v1, url_prefix='/api/v1') app.add_url_rule('/healthcheck', view_func=health_check) try: from estuary.api.monitoring import configure_monitoring, monitoring_api app.register_blueprint(monitoring_api, url_prefix='/monitoring') configure_monitoring(app) except ImportError as e: # If prometheus_client isn't installed, then don't register the monitoring blueprint log.warning( 'The promethus_client is not installed, so metrics will be disabled' ) if 'prometheus_client' not in str(e): raise app.after_request(insert_headers) return app
def __init__(self, worker_app=None, *args, **kwargs): super(Blueprint, self).__init__(*args, **kwargs) self.url_value_preprocessor(unquote_url_values) self.errorhandler(Exception)(json_error_handler) for code in default_exceptions.keys(): if code != 500: self.errorhandler(code)(json_error_handler) self.worker_app = worker_app
def install_error_handlers(app): def make_json_error(e): response = jsonify(message=str(e)) response.status_code = e.code if isinstance(e, HTTPException) else 500 return response for code in default_exceptions.keys(): app.register_error_handler(code, make_json_error)
def jsonify_app(app): def make_json_error(ex): response = jsonify(message=str(ex)) response.status_code = ex.code if isinstance(ex, HTTPException) else 500 return response for code in default_exceptions.keys(): app.error_handler_spec[None][code] = make_json_error
def json_app(app): def jsonify_unhandled_exceptions(e): response = jsonify(message=str(e)) response.status_code = getattr(e, 'code', 500) return response for status_code in default_exceptions.keys(): app.error_handler_spec[None][status_code] = jsonify_unhandled_exceptions return app
def _register_as_json(app): def make_json_error(ex): response = jsonify(status=ex.code, message=str(ex.description)) response.status_code = (ex.code if isinstance(ex, HTTPException) else 500) return response for code in default_exceptions.keys(): app.register_error_handler(code, make_json_error)
def register_general_error_handler(blueprint_or_app, handler): error_codes = default_exceptions.keys() if isinstance(blueprint_or_app, Blueprint): error_codes.remove( 500 ) # Flask doesn't currently allow per-Blueprint HTTP 500 error handlers for err_code in error_codes: blueprint_or_app.errorhandler(err_code)(handler)
def _configure_error_handling(app: flask.Flask): """ Registers error handlers for every kind of HTTP error :param app: """ for status_code in default_exceptions.keys(): app.register_error_handler(status_code, _handle_generic_error) app.register_error_handler(Exception, _handle_generic_error)
def wrapper(): for b in bps: if code is not None: b.errorhandler(code)(hderr) else: for c in default_exceptions.keys(): b.errorhandler(c)(hderr) ErrorHandler.failure(b)(hderr)
def register(app): """Register a JSON error handler for all HTTP exceptions on a Flask app. Parameters ---------- app : flask.Flask The Flask app to configure """ for code in default_exceptions.keys(): app.register_error_handler(code, json_errorhandler)
def abort_test(session, code): try: abort(code) except LookupError: valid_codes = ', '.join(map(str, sorted(default_exceptions.keys()))) return dict(error_format='Unknown Error Code', status_description=[ 'Invalid error code provided.', 'Valid codes are {}.'.format(valid_codes) ])
def configure_error_handlers(graph): """ Register error handlers. """ # override all of the werkzeug HTTPExceptions for code in default_exceptions.keys(): graph.flask.register_error_handler(code, make_json_error) # register catch all for user exceptions graph.flask.register_error_handler(Exception, make_json_error)
def __init_web_layer(self): self.app.json_encoder = AppKernelJSONEncoder self.app.register_error_handler(Exception, self.generic_error_handler) for code in default_exceptions.keys(): # add a default error handler for everything is unhandled self.app.register_error_handler(code, self.generic_error_handler) def set_locale_on_request(): g.locale = str(get_locale()) self.app.before_request(set_locale_on_request)
def errors_handler(app): # jsonify http errors for code in default_exceptions.keys(): @app.errorhandler(code) def handle_error(ex): return jsonify({'message': str(ex)}), code # jsonify authorization error @app.errorhandler(AuthorizationError) def handle_authorization_error(err): return jsonify({'message': str(err)}), 401
def test_echos_error(self): """Response status code reflects ``X-Code`` header.""" with self.app.app_context(): for code in default_exceptions.keys(): response = self.client.get('/', headers={ 'X-Code': code, 'X-Request-ID': '1' }) self.assertEqual( response.status_code, code, 'Response status code matches request header')
def ExceptionApp(app): def error_handler(error): if isinstance(error, ExceptionBase): return error.as_response() else: resp = jsonify({"code": error.code, "message": str(error.description)}) resp.status_code = error.code return resp for code in default_exceptions.keys(): app.register_error_handler(code, error_handler) return app
def create_app(config_obj=None): """ Create a Flask application object. :return: a Flask application object :rtype: flask.Flask """ app = Flask(__name__) if config_obj: app.config.from_object(config_obj) else: load_config(app) if app.config['ENV'] != 'development': if app.config['SECRET_KEY'] == 'replace-me-with-something-random': raise RuntimeError( 'You need to change the SECRET_KEY configuration for production' ) for config in ( 'AD_DOMAIN', 'AD_LDAP_URI', 'AD_USER_GROUPS', 'AD_ADMIN_GROUPS', 'AD_SERVICE_USERNAME', 'AD_SERVICE_PASSWORD', 'SQLALCHEMY_DATABASE_URI', ): if not app.config.get(config): raise RuntimeError(f'You need to set the "{config}" setting') init_logging(app) db.init_app(app) migrations_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'migrations') Migrate(app, db, directory=migrations_dir) app.cli.command()(create_db) for status_code in default_exceptions.keys(): app.register_error_handler(status_code, json_error) app.register_error_handler(ValidationError, json_error) app.register_error_handler(ConfigurationError, json_error) app.register_error_handler(ADError, json_error) app.after_request(insert_headers) app.register_blueprint(api_v1, url_prefix='/api/v1') jwt = JWTManager(app) jwt.token_in_blacklist_loader(BlacklistedToken.is_token_revoked) jwt.user_claims_loader(add_jwt_claims) app.cli.command()(prune_blacklisted_tokens) return app
def medea_app(import_name, **kwargs): def make_json_error(ex): response = jsonify(message=str(ex)) response.status_code = (ex.code if isinstance(ex, HTTPException) else 500) traceback.print_exc() return response app = Flask(import_name, **kwargs) for code in default_exceptions.keys(): app.error_handler_spec[None][code] = make_json_error CORS(app) return app
def make_json_app(import_name, **kwargs): def make_json_error(ex): response = jsonify(success=False, error=str(ex)) response.status_code = (ex.code if isinstance(ex, HTTPException) else 500) return response app = Flask(import_name, **kwargs) CORS(app) for code in default_exceptions.keys(): app.error_handler_spec[None][code] = make_json_error return app
def patch_exception_handlers(app): """ Patch the global werkzeug exception handlers to always return JSON responses. """ def jsonify_unhandled_exceptions(e): response = utils.jsonify(dict(message=str(e))) response.status_code = getattr(e, 'code', 500) return response for status_code in default_exceptions.keys(): app.error_handler_spec[None][status_code] = jsonify_unhandled_exceptions return app
def create_app(config_obj=None): """ Create a Flask application object. :param str config_obj: the path to the configuration object to use instead of calling load_config :return: a Flask application object :rtype: flask.Flask """ app = Flask(__name__) if config_obj: app.config.from_object(config_obj) else: load_config(app) # Configure logging default_handler.setFormatter( logging.Formatter(fmt=app.config["CACHITO_LOG_FORMAT"], datefmt="%Y-%m-%d %H:%M:%S") ) app.logger.setLevel(app.config["CACHITO_LOG_LEVEL"]) for logger_name in app.config["CACHITO_ADDITIONAL_LOGGERS"]: logger = logging.getLogger(logger_name) logger.setLevel(app.config["CACHITO_LOG_LEVEL"]) # Add the Flask handler that streams to WSGI stderr logger.addHandler(default_handler) # Initialize the database db.init_app(app) # Initialize the database migrations migrations_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "migrations") Migrate(app, db, directory=migrations_dir) # Initialize Flask Login login_manager = LoginManager() login_manager.init_app(app) login_manager.user_loader(user_loader) login_manager.request_loader(load_user_from_request) app.register_blueprint(docs) app.register_blueprint(api_v1, url_prefix="/api/v1") app.add_url_rule("/healthcheck", view_func=healthcheck) for code in default_exceptions.keys(): app.register_error_handler(code, json_error) app.register_error_handler(CachitoError, json_error) app.register_error_handler(ValidationError, json_error) app.register_error_handler(ContentManifestError, json_error) app.register_error_handler(pydantic.ValidationError, validation_error) init_metrics(app) return app
def create_app(config_obj=None): # pragma: no cover """ Create a Flask application object. :param str config_obj: the path to the configuration object to use instead of calling load_config :return: a Flask application object :rtype: flask.Flask """ app = Flask(__name__) if config_obj: app.config.from_object(config_obj) else: load_config(app) # Validate the config validate_api_config(app.config) # Configure logging default_handler.setFormatter( logging.Formatter(fmt=app.config['IIB_LOG_FORMAT'], datefmt='%Y-%m-%d %H:%M:%S')) app.logger.setLevel(app.config['IIB_LOG_LEVEL']) for logger_name in app.config['IIB_ADDITIONAL_LOGGERS']: logger = logging.getLogger(logger_name) logger.setLevel(app.config['IIB_LOG_LEVEL']) # Add the Flask handler that streams to WSGI stderr logger.addHandler(default_handler) # Initialize the database db.init_app(app) # Initialize the database migrations migrations_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'migrations') Migrate(app, db, directory=migrations_dir) # Initialize Flask Login login_manager = LoginManager() login_manager.init_app(app) login_manager.user_loader(user_loader) login_manager.request_loader(load_user_from_request) app.register_blueprint(docs) app.register_blueprint(api_v1, url_prefix='/api/v1') for code in default_exceptions.keys(): app.register_error_handler(code, json_error) app.register_error_handler(IIBError, json_error) app.register_error_handler(ValidationError, json_error) app.register_error_handler(kombu.exceptions.KombuError, json_error) return app
def __init__(self, import_name): self.prefix = config.prefix fullSwaggerPath = self.prefix + config.swagger_ui staticUrlPath = fullSwaggerPath[:fullSwaggerPath.rfind('/')] # Remove char from the end until slash is found super(API, self).__init__(import_name, static_url_path=staticUrlPath) self.oas = OpenAPI(config.app_name) # Format internal error message to JSON for code in default_exceptions.keys(): # self.error_handler_spec[None][code] = self.__make_json_error self.register_error_handler(code, self.__make_json_error) # Set headers for all response self.after_request(self.__setHeaders)
def configure_error_handlers(graph): """ Register error handlers. """ error_func = make_json_error if graph.sentry_logging.enabled: error_func = make_json_error_with_sentry # override all of the werkzeug HTTPExceptions for code in default_exceptions.keys(): graph.flask.register_error_handler(code, error_func) # register catch all for user exceptions graph.flask.register_error_handler(Exception, error_func)
def app(import_name, **kwargs): """ Creates a JSON-oriented Flask app. All error responses that you don't specifically manage yourself will have application/json content type, and will contain JSON like this (just an example): { "message": "405: Method Not Allowed" } """ app = Flask(import_name, **kwargs) for code in default_exceptions.keys(): app.error_handler_spec[None][code] = error return app
def create_app(config): """Creates a default application.""" app = Flask(__name__) app.config.from_pyfile(config) from peanuts.lib.database import db db.init_app(app) from peanuts import views views.register(app, route_base='/api') with app.app_context(): from peanuts.models.app import Application from peanuts.lib.auth import no_apps_need db.create_all() @app.before_first_request def check_admin(*args, **kargs): """Checks that there is an admin application. If not, creates it. """ if no_apps_need(): # Unless overridden by a direct database operation, the first # app to be accessed should be admin. admin_app = Application( token='6752e4b0-8122-4c9a-ad1d-19d703fdfed0', title='Admin', description='The administrative application.', slug='admin', repo_url=app.config['ADMIN_REPO'], config=json.dumps('{}') ) db.session.add(admin_app) db.session.commit() from peanuts.lib.session import PeanutsSessionInterface app.session_interface = PeanutsSessionInterface() from peanuts.lib.err import make_json_error for code in default_exceptions.keys(): app.error_handler_spec[None][code] = make_json_error return app
def api_errors(app, configuration): """ Defines error handlers and responses. :param app: The Flask application. """ def error_handler(ex): status_code = (ex.code if isinstance(ex, HTTPException) else 500) if configuration.ENVIRONMENT == configuration.ConfigurationConstants.DEVELOPMENT and ex: message = str(ex) else: message = "Error encountered" return {'status_code' : status_code, 'message' : message}, status_code for code in default_exceptions.keys(): app.error_handler_spec[None][code] = error_handler return app
def create_app(config_name='development'): """Flask factory function""" # Configure from config.py app = Flask(__name__, instance_relative_config=True) app.config.from_object(config[config_name]) config[config_name].init_app(app) db.init_app(app) # Configure Flask-Admin admin = Admin(name='demo', template_mode='bootstrap3') from .admin_views import DbView admin.add_view(DbView(Group, db.session)) admin.add_view(DbView(User, db.session)) admin.init_app(app) # Blueprints from .api import groups_bp app.register_blueprint(groups_bp, url_prefix='/api/groups') from .api import users_bp app.register_blueprint(users_bp, url_prefix='/api/users') # @app.before_first_request def create_tables(): db.create_all() # Ensure all errors thrown are json # http://flask.pocoo.org/snippets/83/ def make_json_error(ex): response = jsonify(message=str(ex)) response.status_code = (ex.code if isinstance(ex, HTTPException) else 500) return response for code in default_exceptions.keys(): app.error_handler_spec[None][code] = make_json_error return app
def create_app(config_obj=None): """ Create a Flask application object. :return: a Flask application object :rtype: flask.Flask """ app = Flask(__name__) if config_obj: app.config.from_object(config_obj) else: load_config(app) if app.config['ENV'] != 'development': if app.config['SECRET_KEY'] == 'replace-me-with-something-random': raise RuntimeError('You need to change the SECRET_KEY configuration for production') for config in ('AD_DOMAIN', 'AD_LDAP_URI', 'AD_USERS_GROUP', 'AD_ADMINS_GROUP', 'AD_SERVICE_USERNAME', 'AD_SERVICE_PASSWORD', 'SQLALCHEMY_DATABASE_URI'): if not app.config.get(config): raise RuntimeError('You need to set the "{0}" setting'.format(config)) init_logging(app) db.init_app(app) migrations_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'migrations') Migrate(app, db, directory=migrations_dir) app.cli.command()(create_db) for status_code in default_exceptions.keys(): app.register_error_handler(status_code, json_error) app.register_error_handler(ValidationError, json_error) app.register_error_handler(ConfigurationError, json_error) app.register_error_handler(ADError, json_error) app.after_request(insert_headers) app.register_blueprint(api_v1, url_prefix='/api/v1') jwt = JWTManager(app) jwt.token_in_blacklist_loader(BlacklistedToken.is_token_revoked) jwt.user_claims_loader(add_jwt_claims) app.cli.command()(prune_blacklisted_tokens) return app
def make_json_app(): """ Creates a JSON-oriented Flask app. All error responses will contain JSON like this (just an example): { "message": "405: Method Not Allowed" } """ def make_json_error(ex): response = jsonify(message=str(ex)) response.status_code = (ex.code if isinstance(ex, HTTPException) else 500) return response app = Flask(__name__) for code in default_exceptions.keys(): app.error_handler_spec[None][code] = make_json_error return app
def make_json_exception_app(name, **kwargs): ''' Taken from snippet http://flask.pocoo.org/snippets/83/ Method to make Flask app that returns all user unhandled exceptions as json by default ''' def make_json_error(error): response = jsonify(message=str(error)) response.status_code =\ error.code if isinstance(error, HTTPException) else 500 return response app = Flask(name, **kwargs) for code in default_exceptions.keys(): app.register_error_handler(code, make_json_error) return app
def make_json_app(import_name, **kwargs): """ Creates a JSON-oriented Flask app. All error responses that you don't specifically manage yourself will have application/json content type, and will contain JSON like this (just an example): { "message": "405: Method Not Allowed" } """ def make_json_error(ex): response = jsonify({'description': ex.description, 'message': str(ex)}) response.status_code = (ex.code if isinstance(ex, HTTPException) else 500) return response app = Flask(import_name, **kwargs) for code in default_exceptions.keys(): app.error_handler_spec[None][code] = make_json_error return app
def create_app(): """ Create application, using Flask. Payloads are in JSON. """ app = Flask('pikka_bird_server') app.debug = (os.environ['LOG_LEVEL'] == 'DEBUG') for r in [ 'collections', 'statics']: app.register_blueprint( getattr(getattr(pikka_bird_server.routes, r), r)) for code in default_exceptions.keys(): app.error_handler_spec[None][code] = __make_json_error __setup_logger(app.logger) return app
app = Flask(__name__) app.config.from_object('config') app.secret_key = 'some_secret2' cors = CORS(app) db = SQLAlchemy(app) def make_json_error(ex): response = jsonify(message=str(ex)) response.status_code = (ex.code if isinstance(ex, HTTPException) else 500) return response for code in default_exceptions.keys(): app.error_handler_spec[None][code] = make_json_error from flask_restful import Api from app.resources.checks import HealthCheck from app.resources.communities import CommunityResource from app.resources.matches import MatchResource, CommunityMatchesResource, MatchGoalsResource from app.resources.players import PlayersResource from app.resources.teams import TeamsResource from app.resources.teams_rating import TeamsRatingResource from app.resources.goals import GoalResource api_blueprint = Blueprint('api', __name__, url_prefix='/api') api = Api(api_blueprint) api.add_resource(HealthCheck, '/health')
def register(app): def jsonify_error(e): return jsonify(dict(status=e.code, short=e.name, data=e.description)), e.code for code in default_exceptions.keys(): app.error_handler_spec[None][code] = jsonify_error
def create_app(name=__name__, enable_security=True, debug=False, **kwargs): """ Create the server istance for Flask application """ ################################################# # Flask app instance ################################################# from confs import config template_dir = os.path.join(config.BASE_DIR, __package__) microservice = Flask(name, # Quick note: # i use the template folder from the current dir # just for Administration. # I expect to have 'admin' dir here to change # the default look of flask-admin template_folder=template_dir, **kwargs) ############################## # ERROR HANDLING # Handling exceptions with json for code in default_exceptions.keys(): microservice.error_handler_spec[None][code] = make_json_error # Custom error handling: save to log got_request_exception.connect(log_exception, microservice) # Custom exceptions @microservice.errorhandler(RESTError) def handle_invalid_usage(error): # print("ERROR", error) response = jsonify(error.to_dict()) response.status_code = error.status_code return response ############################## # Flask configuration from config file microservice.config.from_object(config) microservice.config['DEBUG'] = debug # // TO FIX: # development/production split? logger.info("FLASKING! Created application") ################################################# # Other components ################################################# ############################## # Cors from .cors import cors cors.init_app(microservice) logger.info("FLASKING! Injected CORS") ############################## # DB from .models import db db.init_app(microservice) logger.info("FLASKING! Injected sqlalchemy. (please use it)") ############################## # Flask security if enable_security: ############################################ # Should open an issue on flask-admin! """ # BUG! The following is how it should be, but we get infinite loop: File "/usr/local/lib/python3.4/dist-packages/flask_security/core.py" , line 450, in __getattr__ return getattr(self._state, name, None) RuntimeError: maximum recursion depth exceeded """ # from .security import security # security.init_app(microservice) # WORKAROUND from .security import udstore from flask_security import Security security = Security(microservice, udstore) # WORKAROUND ############################################ logger.info("FLASKING! Injected security") ############################## # Restful plugin from .rest import epo, create_endpoints logger.info("FLASKING! Injected rest endpoints") epo = create_endpoints(epo, security, debug) # Restful init of the app epo.rest_api.init_app(microservice) ############################## # Prepare database and tables with microservice.app_context(): try: if config.REMOVE_DATA_AT_INIT_TIME: db.drop_all() db.create_all() logger.info("DB: Connected and ready") except Exception as e: logger.critical("Database connection failure: %s" % str(e)) exit(1) if enable_security: from .security import db_auth # Prepare user/roles db_auth() ############################## # Flask admin if enable_security: from .admin import admin, UserView, RoleView from .models import User, Role from flask_admin import helpers as admin_helpers admin.init_app(microservice) admin.add_view(UserView(User, db.session)) admin.add_view(RoleView(Role, db.session)) # Context processor for merging flask-admin's template context # into the flask-security views @security.context_processor def security_context_processor(): return dict(admin_base_template=admin.base_template, admin_view=admin.index_view, h=admin_helpers) logger.info("FLASKING! Injected admin endpoints") ############################## # RETHINKDB # // TO FIX, not for every endpoint if RDB_AVAILABLE: @microservice.before_request def before_request(): logger.debug("Hello request RDB") # === Connection === # The RethinkDB server doesn’t use a thread-per-connnection approach, # so opening connections per request will not slow down your database. # Database should be already connected in "before_first_request" # But the post method fails to find the object! from .resources.services.rethink import try_to_connect try_to_connect() ############################## # Logging responses @microservice.after_request def log_response(response): logger.info("{} {} {}\n{}".format( request.method, request.url, request.data, response)) return response # OR # http://www.wiredmonk.me/error-handling-and-logging-in-flask-restful.html # WRITE TO FILE # file_handler = logging.FileHandler('app.log') # app.logger.addHandler(file_handler) # app.logger.setLevel(logging.INFO) ############################## # App is ready return microservice