flask-mwoauth icon indicating copy to clipboard operation
flask-mwoauth copied to clipboard

Is it possible to override routes from the blueprint?

Open CristianCantoro opened this issue 8 years ago • 3 comments

Hi,

this is more of a documentation bug. I have posted this question on StackOverflow:

"How to override a Flask blueprint URL?"

Long story short, I would like to know if there is a way to "extend" the blueprint response for the predefined URIs. How can I do it?

CristianCantoro avatar Jul 09 '16 17:07 CristianCantoro

http://flask.pocoo.org/docs/0.11/blueprints/#registering-blueprints suggests the following:

app.register_blueprint(simple_page, url_prefix='/pages')

and it might be possible to not hook up the blueprint at all, instead using something like

@app.route('/logout')
def logout(bla):
    self.MWOAuth.logout()

valhallasw avatar Aug 01 '16 20:08 valhallasw

Hi @valhallasw, actually the solution you are proposing does not work for several reason:

  1. I do not want to mount the URLs on a different path, I want to change the behaviour so changing the url_prefix when registering the blueprint does not help;
  2. if you register the blueprint, the route is taken over by the blueprint, so if you register the blueprint on / (i.e. not passing the url_prefix parameter) then the route /logout is managed by the blueprint and there is no way to override this;
  3. you cannot use self.MWOAuth.logout() because: self would refer to the current object (whatever it is), the flask application may not be an object at all and self may not be defined;
  4. in addition to the point above, logout() is defined within the constructor of the MWOAuth() object (line 56), so it not available as a method.

My solution (if it can be called a real one) has been not registering the blueprint and re-implementing the routes defined by the blueprint itself, i.e. /login, /logout and /oauth-callback copy-pasting the code from this library and changing all instances of self with :

mwoauth_mw = MWOAuth(base_url='https://it.wikipedia.org/w',
                     clean_url='https://it.wikipedia.org/wiki',
                     consumer_key=consumer_key,
                     consumer_secret=consumer_secret
                     )

# ... other code ...

# code from flask-mwoauth
@app.route("/oauth-callback")
def oauth_authorized():
    resp = mwoauth_mw.mwoauth.authorized_response()
    next_url_key = request.args['oauth_token'] + '_target'
    default_url = url_for(mwoauth_mw.default_return_to)

    next_url = session.pop(next_url_key, default_url)

    if resp is None:
        flash(u'You denied the request to sign in.')
        return redirect(next_url)
    session['mwo_token'] = (
        resp['oauth_token'],
        resp['oauth_token_secret']
    )

    username = mwoauth_mw.get_current_user(False)
    flash('You were signed in, %s!' % username)

    return redirect(next_url)

Note that I am accessing the mwoauth member within MWOAuth which as you said in a comment on issue #15, I should not be supposed to do. Alas, I have found no alternative.

In summary, in the end I have dropped the blueprint entirely.

I am little baffled from this behaviour of blueprints, because they eliminate any possibility of redefining the behaviour of a route in an application. Also debugging becomes much more difficult.

CristianCantoro avatar Aug 03 '16 18:08 CristianCantoro

in addition to the point above, logout() is defined within the constructor of the MWOAuth() object (line 56), so it not available as a method.

Ah. Yes, that is the issue at hand here, I think. Those functions should have been class functions rather than functions hidden in __init__(), and when they are class functions, they can be called directly.

valhallasw avatar Aug 03 '16 20:08 valhallasw