Using mwoauth2 in a Flask tool
The basic setup of a Flask tool using mwoauth2 goes as follows:
Create the Flask app:
app = flask.Flask(__name__)
Load the configuration from some secure source. For instance, a Toolforge tool may use Toolforge envvars:
app.config.from_prefixed_env('TOOL', loads=yaml.safe_load)
This would then load OAuth configuration from the following environment variables:
$ toolforge envvars create TOOL_OAUTH__CLIENT_ID 'abcde'
$ toolforge envvars create TOOL_OAUTH__CLIENT_SECRET
Enter the value of your envvar (Hit Ctrl+C to cancel): 12345
Alternatively (or in addition), you may use a configuration file,
optionally using the toolforge.load_private_yaml() helper:
app.config.from_file('config.yaml', load=toolforge.load_private_yaml, silent=True)
Whichever configuration sources you use,
app.config['OAUTH']['CLIENT_ID'] and app.config['OAUTH']['CLIENT_SECRET'] should be set
to the client ID and client secret of an OAuth 2 client you registered.
Set up a user agent string to use
(in accordance with the policy),
perhaps using toolforge.set_user_agent() in the case of a Toolforge tool:
user_agent = toolforge.set_user_agent('example-tool', email='tool@example.com')
# or
user_agent = 'example-tool (tool@example.com) other-details...'
Create the OAuth management instance.
If you’re going to use mwapi, use MWOAuth2FlaskMWApi:
oauth = MWOAuth2FlaskMWApi(
host='https://meta.wikimedia.org', # the wiki where OAuth authorization will happen
user_agent=user_agent,
app=app,
)
Otherwise, use MWOAuth2Flask:
oauth = MWOAuth2Flask(
host='https://meta.wikimedia.org',
user_agent=user_agent,
app=app,
)
When targeting non-Wikimedia wikis, you may have to specify a custom api_path= parameter if it is not /w/api.php.
Also, if you are migrating a tool from OAuth 1.0a to OAuth 2, the check_access_token_before_request=True parameter may be useful
(see the API documentation for details).
Now the oauth instance is ready to use.
To check if the user is logged in, use has_access_token():
@app.route(...)
def something():
if oauth.has_access_token():
# user is logged in
...
else:
# logged out, show a login link
...
To log in, redirect the user to the authorization_url():
@app.route('/login')
def login():
return flask.redirect(oauth.authorization_url())
In the OAuth callback (the URL of which you configured in our OAuth client registration),
call fetch_token() to finish logging in:
@app.route('/oauth/callback')
def oauth_callback():
oauth.fetch_token()
flask.session.permanent = True
return flask.redirect(flask.url_for('index'))
Now the user is logged in and OAuth is ready to use.
If you use mwapi, use mwapi_session():
@app.route('/userinfo')
def userinfo():
session = oauth.mwapi_session()
if session is None:
return 'not logged in'
response = session.get(action='query', meta='userinfo')
return flask.jsonify(response['query']['userinfo'])
Otherwise, use oauth2_session():
@app.route('/userinfo')
def userinfo():
session = oauth.oauth2_session()
if session is None:
return 'not logged in'
response = session.get('https://meta.wikimedia.org/w/api.php',
params={'action': 'query', 'meta': 'userinfo', 'format': 'json'})
return flask.jsonify(response.json()['query']['userinfo'])
To log the user out, call pop_access_token():
@app.route('/logout')
def logout():
try:
oauth.pop_access_token()
except KeyError:
pass
flask.session.permanent = False
return flask.redirect(flask.url_for('index'))