How to get real users' genetic insights

Getting started with OAuth authorization flow


This tutorial covers the procedures for acquiring the following genetic insights of a real Genomelink user:

  • Eye color
  • Beard thickness
  • Morning person

For this tutorial, we will start with registering your app to Genomelink and then run the sample web app ( Python/Flask or Node/Express ) on localhost to request users' genetic insights using OAuth authorization flow.

If you are unfamiliar with OAuth, you can refer to a quick overview at OAuth 2 Simplified by Aaron Parecki.

1. Register your app


Before you can begin the OAuth process, you must first register a new app with the service. When registering a new app, you usually register basic information such as application name, website, a logo, etc. In addition, you must register a redirect URI to be used for redirecting users to for web server, browser-based, or mobile apps.

OAuth 2.0 Simplified by Aaron Parecki

1. Create your account

First, if you do not yet have a Genomelink account, create a new one on the SIGN UP page.

2. Register your app

Navigate to My apps and click on [Register a new app] to register your application for OAuth. Fill in the form as provided below:


Key Value
Name my-python-app
Redirect URIs http://127.0.0.1:5000/callback
Key Value
Name my-node-app
Redirect URIs http://127.0.0.1:3000/callback

The service will only redirect users to a registered URI, which helps prevent some attacks. Any HTTP redirect URIs must be protected with TLS security, so the service will only redirect to URIs beginning with "https". This prevents tokens from being intercepted during the authorization process.

OAuth 2.0 Simplified by Aaron Parecki

Click on [Save] to finish the app registration. The next page will provide you with new Client ID and Client secret for your app. You will use these to configure your app later in this tutorial.

3. Setting the scope

In the [Authorization scopes] tab, click on [Edit] to define the scope (whitelist) of reports that the app will request. For this tutorial, please tick Eye color, Beard thickness, and Morning person and click on [Save].


2. Request user's data via OAuth


Fetching a protected resource after obtaining an access token can be extremely simple. However, before accessing resources you will need to obtain a few credentials from your provider and authorization from the user for whom you wish to retrieve resources for.

github.com/requests/requests-oauthlib

1. Download the sample web app

Python/Flask web app or Node/Express web app

2. Run the app server on localhost

After downloading the sample code, set GENOMELINK_CLIENT_ID, GENOMELINK_CLIENT_SECRET and GENOMELINK_CALLBACK_URL as environmental variables and run the sample web app server on localhost.


To do so, open Command Line Tool on Windows or Terminal on Unix (Mac).

1. Navigate to the sample app folder

$ cd /path/to/api-oauth-example-flask

2. Install required modules

$ pip install -r requirements.txt

3. Export your Client ID and secret of the app

$ export GENOMELINK_CLIENT_ID=your_client_id
$ export GENOMELINK_CLIENT_SECRET=your_client_secret
$ export GENOMELINK_CALLBACK_URL="http://127.0.0.1:5000/callback"

4. Run the app on your localhost!

$ python app.py

1. Navigate to the sample app folder

$ cd /path/to/api-oauth-example-node-express

2. Install required modules

$ npm install

3. Export your Client ID and secret of the app

$ export GENOMELINK_CLIENT_ID=your_client_id
$ export GENOMELINK_CLIENT_SECRET=your_client_secret
$ export GENOMELINK_CALLBACK_URL="http://127.0.0.1:3000/callback"

4. Run the app on your localhost!

$ node app.js

3. Launching the app in the browser

Open http://127.0.0.1:5000 in your web browser.

How it works?

When a new user visits the app for the first time the Genomelink account will not yet be connected to the app. The app requires his Genomelink data, so he will need to be connected to Genomelink. It's like using the Facebook login and user profile data to link to a third-party app.

The app puts a "Connect with genome" button with authorize_url link in the index page, so that he can connect his Genomelink's data to the app. The authorize_url is a link to https://genomelink.io/oauth/authorize with client params such as client_id.

from flask import Flask, render_template
import genomelink

# ...

app = Flask(__name__)

@app.route('/')
def index():
    authorize_url = genomelink.OAuth.authorize_url(scope=['report:eye-color report:beard-thickness report:morning-person'])

    # ...

    return render_template('index.html', authorize_url=authorize_url, reports=reports)
app.py#L8-L10
<a href="{{ authorize_url }}" class="btn btn-default">Connect with genome</a>
templates/index.html#L24
Open http://127.0.0.1:3000 in your web browser.

How it works?

When a new user visits the app for the first time the Genomelink account will not yet be connected to the app. The app requires his Genomelink data, so he will need to be connected to Genomelink. It's like using the Facebook login and user profile data to link to a third-party app.

The app puts a "Connect with genome" button with authorize_url link in the index page, so that he can connect his Genomelink's data to the app. The authorize_url is a link to https://genomelink.io/oauth/authorize with client params such as client_id.

const express = require('express');
const session = require('express-session');
const genomeLink = require('genomelink-node');

const app = express();

// ...

app.get('/', async (req, res) => {
  const scope = 'report:eye-color report:beard-thickness report:morning-person';
  const authorizeUrl = genomeLink.OAuth.authorizeUrl({ scope: scope });

  // ...

  res.render('index', {
    authorize_url: authorizeUrl,
    reports: reports,
  });
});
app.js#L19-L20
app.js#L35-L38
<a href="<%= authorize_url %>" class="btn btn-default">Connect with genome</a>
views/index.ejs#L12-L14

4. Connect with Genomelink

CAUTION

If you have already logged in to Genomelink with your developer account, log out of your account first since you probably have not registered your genome data yet! Instead, use test users below. These accounts have their genome data already registered, so you can see what will happen when real users come to the sample app.

Username Password
test-user-1 genomelink.io
test-user-2 genomelink.io
test-user-3 genomelink.io

After clicking the "Connect with genome" button, you will be redirected to login page of Genomelink if you are not logged in. Once you login, you will be asked to grant the sample web app access to report data of the account.

How it works?

When you click "Authorize", you will be redirected back to localhost, which you set as GENOMELINK_CALLBACK_URL as environmental variable and is also registered in My Apps console.

@app.route('/callback')
def callback():
    # ...

With this redirection comes an authorization code included in the request URL. We will use that to obtain an access token.

    token = genomelink.OAuth.token(request_url=request.url)

Once access token is obtained, we can request his report data. In this sample code we store the token to session cookie and will use it later in index page.

    session['oauth_token'] = token
    return redirect(url_for('index'))
app.py#L20-L36

Finally, we use the token to get his reports and render them.

@app.route('/')
def index():
    # ...

    # Fetching a protected resource using an OAuth2 token if exists.
    reports = []
    if session.get('oauth_token'):
        for name in ['eye-color', 'beard-thickness', 'morning-person']:
            reports.append(genomelink.Report.fetch(name=name, population='european', token=session['oauth_token']))

    return render_template('index.html', authorize_url=authorize_url, reports=reports)
app.py#L12-L18
<tbody>
  {% for report in reports %}
  <tr>
    <th scope="row">{{ report.phenotype.display_name }}</th>
    <td>{{ report.summary.text }}</td>
  </tr>
  {% endfor %}
</tbody>
templates/index.html#L35-L40

How it works?

When you click "Authorize", you will be redirected back to localhost, which you set as GENOMELINK_CALLBACK_URL as environmental variable and is also registered in My Apps console.

app.get('/callback', async (req, res) => {
  // ...
});
app.js#L41

With this redirection comes an authorization code included in the request URL. We will use that to obtain an access token.

  req.session.oauthToken = await genomeLink.OAuth.token({ requestUrl: req.url });
app.js#L45

Once access token is obtained, we can request his report data. In this sample code we store the token to session cookie and will use it later in index page.

  res.redirect('/');
app.js#L49

Finally, we use the token to get his reports and render them.

app.get('/', async (req, res) => {
  // ...

  // Fetching a protected resource using an OAuth2 token if exists.
  let reports = [];
  if (req.session.oauthToken) {
    const scopes = scope.split(' ');
    reports = await Promise.all(scopes.map( async (name) => {
      return await genomeLink.Report.fetch({
        name: name.replace(/report:/g, ''),
        population: 'european',
        token: req.session.oauthToken
      });
    }));
  }

  res.render('index', {
    authorize_url: authorizeUrl,
    reports: reports,
  });
});
app.js#L22-L39
<tbody>
<% for (let report of reports) { %>
  <tr>
    <th scope="row"><%= report.phenotype.display_name %></th>
    <td><%= report.summary.text %></td>
  </tr>
  <% } %>
</tbody>
index.ejs#L24-L31

Next steps


Congratulations! You have successfully obtained the real users' genetic insights via OAuth.

Resources