Month: June 2019

Building a Python HTTP client that automatically refreshes access tokens

How often is it that when calling API’s you do an initial round of auth to receive a token that expires after a certain amount of time?
It is quite common these days. What isn’t common is a generic way to ensure that this authentication process is automatically restarted when the existing token expires.

The first thing to remember is that we should use some persistent storage mechanism to keep the token.

Where are we going to store this access token value then? We need to store it as it needs to be accessed between multiple requests.

The database is not a terrible place, I’ve seen it done before. Or you can use django’s cache API.

Finding an Example

I wish there was a client I could view and see how other people have implemented this in python.

Here is an apt comment from the php community:

…for other APIs I have found the decorator pattern around the HTTP client (especially a PSR-18 client, because its interface is so simple) is a great place to put the renewal logic. That’s the point where the expiry response is known, the full original request is known so can be tried again, and the renewed authentication token can be saved in the current client and saved to a persistent storage.

So I understand, here you have a stack of middleware (kind of) handlers that each wrap the request and pass back the response. On an expired token response you try renewing the token, then bounce the same request back down the chain again? The retry count allows you to give up after a number of bounces.

You could inject a closure in this middleware here to handle the persisting of the new token to storage.

JudgeJ comment on guzzle

A Javascript implementation example, the gist:

  1. Store the token
  2. Wrap every request in a decorator that reauths when a `401` is received
  3. Ensure the original request is redone

I managed to find a python implementation for python-fitbit

Storing the Token in Cache

You can store the auth token in cache like so:


from django.core.cache import cache 

@property
def session(self):
    session = requests.Session()
    session.verify = settings.VERIFY_SSL

    # Check there is a token saved
    auth_header = cache.get('auth_header')
    if not auth_header:
        auth_header = self.get_authorization(session)
        cache.set('auth_header', auth_header)

    session.headers.update(auth_header)

    return session

 

Introduction to Alerta: Open Source Aggregated Alerts

There are a number of platforms available these days to assist operations in terms of dealing with alerts. Namely Pagerduty, VictorOps and OpsGenie. These are unfortunately pay for tools/

These tools are known as monitoring aggregation

I was looking through the integrations of elastalert and found that there is an integration for alerta.io, so I checked the website and it seemed to check all the boxed of monitoring aggregation.

I used the docker compose way of setting it up quickly, but if you want to set it up proper then follow the alerta.io deployment guide.

Update some config:


docker exec -u root -it alerta_web_1 /bin/bash
apt update
apt install vim
# Edit the config in /app/alertad.conf
# Restart the container

Add the housekeeping cron job:


echo "* * * * * root /venv/bin/alerta housekeeping" >/etc/cron.daily/alerta

The default timeout period for an alert is 86400 seconds, or one day.

Check out the alerta plugins

What popular alerting and monitoring tools does alerta.io integrate with?