Consuming an API with Python

A hands-on tutorial that demonstrates the first steps for consuming a simple API with Python.

consuming apis

This tutorial is for you if you have some basic programming knowledge but have never consumed an API. We'll walk through a practical use case with the BASF Periodic Table of Elements API and implement a short Python script to do API requests and calculations on the resulting data.

We have chosen Python for the tutorial primarily for two reasons. One is that we hope its beginner-friendly syntax helps you follow along even if your previous programming knowledge is from a different language. The other is that Python is commonly used for data science applications, even by users who are not necessarily developers.

Our Scenario

The scenario is a basic exercise that you may or not remember from chemistry class in school. Every chemical element, or atom, has an atomic mass. You can find this number on a periodic table of elements. To calculate the molar mass of a chemical compound or molecule, you have to add the atomic mass of each element in it, multiplied by its count.

For example, let's calculate the molar mass of water. Water has the molecular formula H2O, which indicates that it consists of two hydrogen atoms and one oxygen atom. Thus, to calculate its mass, you'd have to follow these steps:

  1. Look up the atomic mass for hydrogen.
  2. Multiply it by 2.
  3. Look up the atomic mass for oxygen.
  4. Add it to the previous number.

The steps listed above are a simple algorithm, and you can run it by hand with pen, paper, and any printed periodic table. The next step is converting this algorithm into something the computer can do programmatically.

The API

BASF provides the Periodic Table of Elements API, which enables you to query the periodic table and retrieve all kinds of information about chemical elements.

Understanding the API

We assume you came here from the Introduction to APIs. If not, please check out that document to learn the basics of APIs before continuing.

The Periodic Table of Elements API follows the CRUD/RESTful paradigm but implements only a subset. Specifically, the periodic table is read-only and allows HTTP GET requests exclusively. It is also limited to one resource called "element."

The base URL for the API is https://dev.api.basf.com/chemical/. Every endpoint starts with this URL.

For the elements, there are two endpoints. The first is a collection endpoint that allows you to either retrieve the full periodic table or request a subset of elements through filter parameters. It is called a collection endpoint because it always returns a collection data structure containing multiple items. The second is an individual resource endpoint that allows you to retrieve a single element.

In the Periodic Table of Elements API, as in most properly designed APIs following this paradigm, the collection endpoint is the base URL followed by the pluralized name of the resource. The endpoint URL for a single resource is the related collection endpoint, followed by a slash and the identifier of the resource.

From this structure, it follows that

  • https://dev.api.basf.com/chemical/elements is the collection endpoint for elements and
  • https://dev.api.basf.com/chemical/elements/{id} is the resource endpoint for a single element.

What you've seen above at the end of the URL is a placeholder, commonly written with curly brackets. You remove those brackets as you replace the placeholder with an actual name. The id can be either the number or the symbol of the element. For example, the endpoint for the Helium element would be https://dev.api.basf.com/chemical/elements/He.

The API provides a JSON structure for each element with multiple description attributes. That is the representation of the resource, and it looks like this:

{
  "number": 2,
  "symbol": "He",
  "group": "18",
  "period": 1,
  "name": "helium",
  "atomic_mass": 4.002602,
  "covalent_radius": 0.93,
  "atomic_volume": 19.5,
  "cas_registry_no": "7440-59-7",
  "electrical_conductivity": null,
  "specific_heat": 5.193,
  "heat_of_fusion": null,
  "heat_of_vaporization": 0.0845,
  "thermal_conductivity": 0.152,
  "polarizability": 0.198,
  "heat_atomization": 0,
  "year_discovered": 1895
}

Prerequisites for Use

All BASF APIs require authentication. The Periodic Table of Elements API uses an app-only context with an API key. If you haven't done so, please read the introduction, terminology, and app-only context sections of the Authentication and Authorization guide. You can skip the part on the app and user context and OAuth as it is not required for this API.

To use authentication, you need to create an account and an application. The process gives you a Client ID, which you can then use as your API key. If you do not have an API key, follow the steps outlined in the Get Started guide. Make sure you select the API product BASF Periodic Table while creating your app.

Running Python

To try Python programming without installation, you can try one of the various free cloud services that give you a Python sandbox, such as Trinket or Repl. If you prefer to work locally, keep reading.

To run Python scripts on your computer, you need to install the Python interpreter, which you can download from the official website.

You can write scripts with any text editor, store them as plain text files with the .py extension and then run them from the command line by typing python {{filename}}.py. We recommend using a text editor or IDE that supports syntax highlighting, for example, Visual Studio Code.

Integrating Algorithm and API

After learning about the scenario's algorithm and the API, we can put them together and see how we can implement the algorithm with support from the API.

The API can help us with the two lookup steps in the periodic table. As we need information only about particular elements, we can make multiple requests to the individual resource endpoint for the respective elements. The collection endpoint is not useful as its parameters do not allow retrieving just the elements we need, and we do not want to retrieve more elements than necessary or implement complex filters for the data after retrieval.

To implement the lookup step for an element, we have to build the URL by including the element name. Then, we have to make an HTTP GET request to that URL. While making this request, we also have to include information about authentication. The Periodic Table of Elements API allows you to provide your API key as the query parameter called x-api-key. Query parameters are the (typically) final part of the URL, starting with a question mark (?).

Also, since we're interested in the atomic mass of an element, we have to parse the resulting JSON to get the atomic_mass field.

Requests in Python

Python has a library called requests that you can use to make external HTTP requests, such as API calls. To do so, first, you have to write a line to import the library:

import requests

Then, you can make a request, by calling the method that corresponds to the desired HTTP verb and providing the URL as a parameter, also replacing the string APIKEY with the previously generated key:

response = requests.get("https://dev.api.basf.com/chemical/elements/H?x-api-key=APIKEY")

Make sure you replace APIKEY with This method call stores the result from the server in a variable called response. The response is in JSON, so the next step is parsing it to make Python understand individual attributes:

parsed_response = response.json()

Finally, we can output the result field we're interested in:

print(parsed_response['atomic_mass'])

Implementing Abstractions

In the previous section, we learned how to make an API call and get the required information. Before we add the molar mass calculation to our Python code, let's do two abstractions to improve the structure of our code.

First, we store the API key in a variable, so we can reuse it in multiple locations, if necessary, without having to change it in more than one place. Enter the following and replace APIKEY with your API key:

api_key = "APIKEY"

Then, we create a function called atomic_mass() that encapsulates the logic of retrieving an element and reading its atomic mass:

def atomic_mass(name):
    response = requests.get("https://dev.api.basf.com/chemical/elements/" + name + "?x-api-key=" + api_key)
    parsed_response = response.json()
    return parsed_response['atomic_mass']

As you can see, the function takes the name as a parameter and includes this parameter as well as the API key variable when building the URL through string concatenation. Instead of printing the atomic mass, we let the function return it.

Using the Function

After implementing a function, we can now use it to achieve our original goal. That is, calculating the molar mass of a chemical compound. Taking the example of H2O, we can now do the calculation by calling our function and doing arithmetics in Python:

print(atomic_mass("H") * 2 + atomic_mass("O"))

Putting it all together

You can copy the import statement, the api_key variable, the function definition, and the line using the function together in one Python script. Then, you can run it on the command line or in a cloud sandbox.

The output should be 18.01535.

To try different calculations, try changing the last line, for example, to calculate the molar mass of carbon dioxide – CO2:

print atomic_mass("C") + atomic_mass("O") * 2

You can also download the atomic_mass.py file, which contains a working example. Don't forget to add your API key, though!

Jupyter Notebooks

Project Jupyter is an application through which you can use interactive notebooks containing Python code and explanations in Markdown-formatted text. You can install it from the official website or use a hosted provider such as Microsoft Azure Notebooks.

Then, you can download the atomic_mass.ipynb file (TODO: add file), which contains a Jupyter version of this tutorial.

Final Remarks

Congratulations on making it through the tutorial! We hope it deepened your understanding of APIs. Feel free to contact developer@basf.com with feedback and questions.