I am using flask-mwoauth
to create a simple application in Flask using OAuth authentication on Mediawiki (and Wikipedia in particular).
flask-mwoauth
is a blueprint that provides some convenience methods to interact with Mediawiki Extensions:OAuth and adds the following URIs:
/login
- runs the OAuth handshake and returns the user to /
/login?next=/someurl
will return the user to /someurl
/logout
- clears the users' access tokens
/logout?next=/someurl
will return the user to /someurl
/oauth-callback
- callback from MW to finish the handshakeThe users' OAuth key and secret are stored in the session.
I would like to be able to create custom responses for some of this custom URIs. Take for example /logout
, the definition of the response in very simple (__init__.py#L56
):
@self.bp.route('/logout')
def logout():
session['mwo_token'] = None
session['username'] = None
if 'next' in request.args:
return redirect(request.args['next'])
return "Logged out!"
I would like to define in my application the route /logout
with a custom response (for example, rendering a template), however if I use the blueprint then the route @app.route("/logout")
is ignored.
What I would like to know if it is possible to "extend" the blueprint in the sense that I can define a route /logout
in my app, call the original method from the blueprint and then serve a customized response.
To use any Flask Blueprint, you have to import it and then register it in the application using register_blueprint() . When a Flask Blueprint is registered, the application is extended with its contents. While the application is running, go to http://localhost:5000 using your web browser.
App Routing means mapping the URLs to a specific function that will handle the logic for that URL. Modern web frameworks use more meaningful URLs to help users remember the URLs and make navigation simpler. Example: In our application, the URL (“/”) is associated with the root URL.
Now, this is where Flask Blueprints come into picture. Blueprints help you structure your application by organizing the logic into subdirectories. In addition to that, you can store your templates and static files along with the logic in the same subdirectory. Now you can see that you have clear separation of concerns.
If you want to completely redefine behavior of route the best way is override MWOAuth
class. Here an example which works:
import os
from flask import Flask, Blueprint
from flask_mwoauth import MWOAuth
app = Flask(__name__)
app.secret_key = os.urandom(24)
class MyMWOAuth(MWOAuth):
def __init__(self,
base_url='https://www.mediawiki.org/w',
clean_url="Deprecated",
default_return_to='index',
consumer_key=None,
consumer_secret=None,
name="Deprecated"):
# I skipped other rows. It's just an example
self.bp = Blueprint('mwoauth', __name__)
# By the way you can customize here login and oauth-callback
@self.bp.route('/logout')
def logout():
# your custom logic here...
return "My custom logout"
mwoauth = MyMWOAuth(consumer_key='test', consumer_secret='test')
app.register_blueprint(mwoauth.bp)
if __name__ == "__main__":
app.run(debug=True, threaded=True)
Let's open /logout
. You will see My custom logout
.
As you can see registration of BluePrint routes takes place in init
method of MWOAuth
.
The second way is to use request callbacks. Here an example which demonstrates the change in the body of the response after logout.
from flask import g, request
def after_this_request(f):
if not hasattr(g, 'after_request_callbacks'):
g.after_request_callbacks = []
g.after_request_callbacks.append(f)
return f
@app.after_request
def call_after_request_callbacks(r):
for callback in getattr(g, 'after_request_callbacks', ()):
callback(r)
return r
@app.before_request
def before_logout():
@after_this_request
def after_logout(response):
# check if called route == '/logout'
# in our case response.data == 'Logged out!'
# see: https://github.com/valhallasw/flask-mwoauth/blob/master/flask_mwoauth/__init__.py#L48
if request.url_rule.endpoint == 'mwoauth.logout':
# custom logic here...
# for example I change data in request
response.data = 'Data from after_logout'
Let's open /logout
. You will see Data from after_logout
.
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With