Getting API into your templates with Django

It started by giving myself a project. Building a dashboard for our Customer Success team, bringing all our platforms into one UI. This, of course, meant I had to use APIs to populate the data. You can read about this more in depth here

I started to build the dashboard using Corey Schafer Django Tutorials on YouTube as I generally know more Python than anything else. Cory is the MAN!!! I have learnt so much from him, over anything else I have used included Udemy. Although I am not knocking Udemy, Cory is just an excellent teacher.

Ok, so how did I end up getting my API responses into my template.

PostMan

Postman has now for me, became an invaluable tool. It allows me to test all my APIs before putting them into code. I can dig down into the response so I know what to pull.

Code

I now know what I want to get from the API and what keys to use to get the relevant data. Making an API call in Python is pretty straight forward using Requests. Something as simple as this will get you a response from an API.

import requests

def function():
    url = 'https://swapi.co/api/starships/9/'
    r = requests.get(url)
    data = r.json()

    return data

How did I get my API data into my templates? Well, this was where the headache came from, using Cory's tutorial I was coding blind more or less. As I was learning Django from those tutorials, so when it came to be doing my tweaks I struggled.

In Cory's tutorial, we created a class called PostDetailView inherits from DetailView. This is where our client's data would live, the data was being populated from my model. I then had to create a separate file which would store my API calls, the calls would be as simple as the below: (keys and domains removed for security)

import requests
import json
import os

def jira_data():
    url = 'https://domain.atlassian.net/rest/api/2/search?jql=project=CS'
    r = requests.get(url, auth=(
        'paulb@domain.com', 'JIRA_API_KEY'))
    data = r.json()
    return data


def pendo_data():
    url = 'https://app.pendo.io/api/v1/aggregation'
    headers = {
        'x-pendo-integration-key': "PENDO_API_KEY",
        'content-type': "application/json"
    }

    r = requests.get(url, headers=headers)
    data = r.json()
    first_visit = data['metadata']['auto']['firstvisit']
    return first_visit

Nothing too complicated here...but how did I get the responses in my template? It was a major headache and a great learning curve for me, after being introduced to render_to_response function it was pretty easy to understand.

The class

I had the functions pulling the API data as I wanted in my separate file, now to get them to populate in my template. I had to use the render_to_repsonse function in my class to do this.

class PostDetailView(DetailView):
    model = Post
    template_name = 'clients/post_detail.html'

    def render_to_response(self, context, **response_kwargs):
        # pendo api
        pendo_result = api_calls.pendo_data()
        context['pendo_data'] = pendo_result

        # jira api
        jira_result = api_calls.jira_data()
        context['jira_data'] = jira_result['issues']

        return super().render_to_response(context, **response_kwargs)

Using context to fill the data into the template.

Once you have a compiled Template object, you can render a context with it. You can reuse the same template to render it several times with different contexts.

The above functions, called the functions which were calling the APIs and then putting the response data into context so I was able to use a template expression to populate the data.

The template

Once I was able to get the data out from the APIs and into my views, the rest was pretty simple. YAY! I just had to use Jinga and some template expressions. I won't go into much detail about this step but to populate the data within my template and into my HTML I used the following expression {{ pendo_data }} or {{ jira_data }} this will then render what was returned by the functions.