Django for beginners: a very simple way to rate limit your API calls

In this article, I will demonstrate a quick and dirty way to implement some sort of limitation to your API. In this instance, I have decided that I do not want a user to make more than 3 calls per day to my API.

So, the way I have implemented it is simple:

  1. Create a model called API_Limits
  2. Every time a request is made, check whether the number of entries into the model (where date = today) is greater than 3
  3. If it is greater than 3, throw an error. If not, enter a record into the model for the current access request and proceed with the API request handling as normal.

There are of course many other ways you could choose to handle this. However, to me, this seemed quick and easy to implement in just a few minutes.

def get_summary(request, api_key):

    today = datetime.today().strftime('%Y-%m-%d')
    attempts_today = api_limits.objects.filter(key=api_key, log=today).count()
    if attempts_today >3:
        response = json.dumps([{ 'Error': 'You have exceeded 3 attempts today. Try again tomorrow.'}])
    else:
        i = api_limits.objects.create(key=api_key, log=today)
        if request.method == 'GET':
            try:
                api_key = str(api_key)
                names = ('id', 'status', 'points', 'count')
                query ='''
                SELECT category as id, status, sum(cast(points as int)) as points, count(*) as count
                FROM app_skills
                WHERE creator = (select app_apikeys.user from voxi_apikeys where key = %s)
                group by category, status'''

                response = serializers.serialize('json', skills.objects.raw(query, [api_key]), fields=names)

            except:
                response = json.dumps([{ 'Error': 'Not a valid API key'}])

    return HttpResponse(response, content_type='text/json')

When you exceed the number of API calls allowed, you will see a response like the below.

In the next article, we’ll continue to dive into API’s a little further.

Kodey