Overwrite Route in Flask Blueprint

Overwrite Route in Flask Blueprint

There is a blueprint with a lot of useful routes defined, but I have no control over it (can not change it's code in any way) Trying to reuse it in a different app but one of the blueprint's endpoints must be overloaded. How can I achieve that?

I tried just adding a new route to blueprint on top of the existing one:

@blueprint.route('/my/route', methods=['PUT', 'POST'])
def my_new_view_func(program, project):
    # some new behavior for the endpoint

As the result there is duplicate url_rule in app.url_map.iter_rules():

<Rule '/my/route' (PUT, POST) -> my_view_func>,
<Rule '/my/route' (PUT, POST) -> my_new_view_func>,

and when requesting /my/route old viewer my_view_func gets executed

Can I somehow get rid of the old url rule? Or maybe there is a better way to overwrite the route?

2

1 Answer

There are 2 solutions which I found. First:

from flask import Flask, Blueprint


simple_page = Blueprint('simple_page', __name__, )


@simple_page.route('/my/route/')
def my():
    # for example it's a registered route somewhere...
    return 'default'


@simple_page.route('/my/route/')
def new_my():
    # new endpoint / should works instead my()
    return 'new'

# map of views which we won't register in Flask app
# you can store this somewhere in settings
SKIP_VIEWS = (
    # route, view function
    ('/my/route/', my, ),
)


class CustomFlask(Flask):

    def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
        # Flask registers views when an application starts
        # do not add view from SKIP_VIEWS
        for rule_, view_func_ in SKIP_VIEWS:  # type: str, func
            if rule_ == rule and view_func == view_func_:
                return
        return super(CustomFlask, self).add_url_rule(rule, endpoint, view_func, **options)


app = CustomFlask(__name__)
app.register_blueprint(simple_page)
app.run(debug=True)

Second way:

two.py - default blueprint with endpoint

from flask import Blueprint

bp_two = Blueprint('simple_page2', __name__, )


@bp_two.route('/my/route/')
def default():
    return 'default'

test.py - your blueprint + app

from flask import Flask, Blueprint

from two import bp_two

your_bp = Blueprint('simple_page', __name__, )


@your_bp.route('/my/route/')
def new_route():
    return 'new'


app = Flask(__name__)
# register blueprint and turn off '/my/route/' endpoint
app.register_blueprint(bp_two, **{'url_defaults': {'/my/route/': None}})
app.register_blueprint(your_bp)

app.run(debug=True)

Run app. Open /my/route/. You will see that default endpoint wasn't add/works.

Hope this helps.

3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

James H. Sterling
Author

James H. Sterling

James Sterling reports on renewable energy developments, climate policy, ecological conservation, and green tech innovations around the globe.