3

I have some error handling calls across many of my flask apps. For example, my 404 response is defined using the @app.errorhandler decorator:

@app.errorhandler(404)
def page_not_found(e):
    return jsonify({'status': 'error',
                    'reason': '''There's no API call for %s''' % request.base_url,
                    'code': 404}), 404

Since I have a significant amount of boilerplate code, I would like to put it in a common file and inherit, or import, my flask app from a single place.

Is it possible to inherit or import flask boilerplate code from a different module?

Adam Matan
  • 128,757
  • 147
  • 397
  • 562
  • Perhaps you could write a boilerplate flask extension? http://flask.pocoo.org/docs/extensiondev/ – msvalkon Jul 01 '14 at 11:18
  • use `Blueprint.app_errorhandler`: https://stackoverflow.com/questions/12768825/flask-error-handler-for-blueprints – Jinsong Li Oct 19 '17 at 14:52

1 Answers1

7

Sure there is, but you need to parameterise the registrations.

Instead of using decorators, move the registration to a function:

def page_not_found(e):
    return jsonify({'status': 'error',
                    'reason': '''There's no API call for %s''' % request.base_url,
                    'code': 404}), 404


def register_all(app):
    app.register_error_handler(404, page_not_found)

then import register_all and call it with your Flask() object.

This uses the Flask.register_error_handler() function instead of the decorator.

To support blueprints too, you'll need to wait for a next release of Flask (one including this commit), or use the decorator function directly:

app_or_blueprint.errorhandler(404)(page_not_found)

For a lot of these tasks, you can use a Blueprint as well, provided you use Blueprint.app_errorhandler():

common_errors = Blueprint('common_errors')


@common_errors.errorhandler(404)    
def page_not_found(e):
    return jsonify({'status': 'error',
                    'reason': '''There's no API call for %s''' % request.base_url,
                    'code': 404}), 404

Not everything can be handled by a Blueprint, but if all you are registering is error handlers, a Blueprint is a good approach.

Import the blueprint as usual and register it to your app:

from yourmodule import common_errors
app.register_blueprint(common_errors)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thanks! nice to see you again. If I understand you correctly, this solution only applies to error handling and not to other utility functions (like the one [in your previous answer](http://stackoverflow.com/a/24238851/51197). Would blueprints be the solution for that? – Adam Matan Jul 01 '14 at 11:29
  • @AdamMatan: the decorators in that answer can be reused anywhere. They are *already* reusable. – Martijn Pieters Jul 01 '14 at 11:30
  • Meaning that I can put them in a blueprint and register them elsewhere in an app? – Adam Matan Jul 01 '14 at 11:32
  • @AdamMatan: Blueprints can be used to add template filters, template globals, template tests, request hooks, context processors, url defaults, etc. etc. – Martijn Pieters Jul 01 '14 at 11:32
  • 1
    @AdamMatan: Just about anything you normally register *on the app* can also be registered *on a blueprint*, to either apply just to routes on the blueprint, or to everything (anything with `app_` in the name applies to all routes, everywhere). – Martijn Pieters Jul 01 '14 at 11:33
  • Thanks. That seems like a very useful tool - started reading the documentation. – Adam Matan Jul 01 '14 at 11:37