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

James H. Sterling

Environmental Science & Climate Journalist

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

Share this article
Twitter Facebook Pinterest