How to use the IMF API with Python
This guide is designed to walk you through the process of retrieving datasets from the International Monetary Fund (IMF) API using Python. Prerequisites for this tutorial include a working installation of Python as well as the following libraries:
import requests
import json
import pandas as pd
Please note, in the subsequent steps, Python’s type notations will be used. The notation str | None
stands for string values that might be absent (nullable) and str
for values that are always present (non-nullable).
Indicators
The indicators endpoint allows access to a variety of economic measures. You can fetch the available indicators from the URL https://www.imf.org/external/datamapper/api/v1/indicators
.
Here is how to fetch the data from the endpoint and create a Pandas Data Frame from it:
def get_imf_indicators():
response = requests.get(
url="https://www.imf.org/external/datamapper/api/v1/indicators"
)
response_body = json.loads(response.text)
indicators = [
{"id": key, **values} for key, values in response_body["indicators"].items()
]
indicators_df = pd.DataFrame.from_records(indicators)
return indicators_df
This is what the schema of the resulting Data Frame looks like:
Column | Type | Description | Example |
---|---|---|---|
id | str | The indicator’s unique ID | NGDP_RPCH |
label | str | None | The name | Real GDP growth |
description | str | None | A short explanation of the indicator | Gross domestic product is the most commonly us… |
source | str | None | The dataset’s original source | World Economic Outlook (April 2023) |
unit | str | None | The datapoints’ unit of measurement | Annual percent change |
dataset | str | None | An identifier for the indicator’s source. | WEO |
Countries, Geographical Regions, and Analytical Groups
The IMF API classifies its data into countries, geographical regions, and analytical groups. The URLs to access them follow the following pattern https://www.imf.org/external/datamapper/api/v1/<groups | regions | countries>
.
Here is a function to fetch the group you need. The group_type
can be either 'groups'
for analytical groups, 'regions'
or 'countries'
.
def get_imf_groups(group_type: str):
response = requests.get(
url=f"https://www.imf.org/external/datamapper/api/v1/{group_type}"
)
response_body = json.loads(response.text)
results = [
{"id": key, **values} for key, values in response_body[group_type].items()
]
df = pd.DataFrame.from_records(results)
return df
This is what the schema of the resulting Data Frame looks like:
Column | Type | Description | Example |
---|---|---|---|
id | str | The group’s unique ID | FRA |
label | str | None | The name | France |
Indicator Data
You can retrieving specific indicator data from https://www.imf.org/external/datamapper/api/v1/<indicator_id>
. You need to specify an indicator’s id
to fetch a given dataset.
Here's a function to fetch the data from the endpoint and create a Pandas Data Frame from it. The indicator_id
is the one we can find in the indicators dataset and the group_ids
we can find in the group’s dataset.
def get_imf_indicator_data(
indicator_id: str, group_ids: list[str] = [], years: list[str] = []
):
indicator_url = "https://www.imf.org/external/datamapper/api/v1"
groups_url_path = "/".join(group_ids)
years_query_param = "?periods=" + ",".join(years)
response = requests.get(
url=f"{indicator_url}/{indicator_id}/{groups_url_path}{years_query_param}"
)
response_body = json.loads(response.text)
response_values = response_body.get("values")
if not response_values:
return pd.DataFrame()
indicator_df = pd.DataFrame.from_records(
response_body["values"][indicator_id]
).sort_index()
return indicator_df
The resulting Data Frame schema is dynamic:
- The index will be the year (as a string) of the recorded datapoints
- The column names will be set to the group ids
- A value’s type will depend on the given dataset, values can be absent (nullable).
Limiting the request to certain groups and years is optional. By not specifying any you can request the complete dataset. If you specify groups and/or years not existing in the requested indicator the resulting Data Frame will be empty.
Be aware that the indicators often only include a subset of the available countries, geographical regions and analytical groups.
You can request data using all three different groups in the same request, for example data from the US (country), as well as Central America (geographical region).
Putting it into Practice
Here an example for how to fetch the indicator “GDP, current prices” ('NGDPD'
) for the United States ('USA'
) and France ('FRA'
) for the years 2022 and 2023:
# 1st step: fetch indicator codes
indicators = get_imf_indicators()
# 2nd step: fetch country codes
countries = get_imf_groups('countries')
# Find the entry for 'GDP, current prices'
indicator = indicators.loc[indicators.label == 'GDP, current prices'].iloc[0]
# Find the entries for the United States and France
selected_countries = countries.loc[countries.label.isin(['United States', 'France'])]
# 3rd step: fetch indicator data
indicator_data = get_imf_indicator_data(indicator.id, selected_countries.id, ['2022', '2023'])
indicator_data
If you run the code in a notebook it will return the following Data Frame:
USA | FRA | |
---|---|---|
2022 | 25464.475 | 2784.020 |
2023 | 26854.599 | 2923.489 |