IMF API with Python: Metadata and advanced requests
In part 3, we obtain the metadata related to our request from part 1 and show how to make a slightly more advanced request, which includes more than one element in a dimension. Specifically, we calculate the U.K.'s share of goods imports that originate in the EU.
Obtaining the metadata
Part 2 explains how to generalize the example in part 1 by finding the codes which correspond to our data of interest and return successful API requests. However, the CompactData
method used in part 1 does not return any metadata, such as full country names, the units of measure, or the indicator name.
Metadata are obtained by using the GenericMetadata
method, demonstrated for the U.K. import price example from part 1 as follows:
In[1]:
import requests # Python 3.6
url = 'http://dataservices.imf.org/REST/SDMX_JSON.svc/'
key = 'GenericMetadata/IFS/M.GB.PMP_IX'
metadata = requests.get(f'{url}{key}').json()
country = metadata['GenericMetadata']['MetadataSet']\
['AttributeValueSet'][1]['ReportedAttribute']\
[1]['ReportedAttribute'][3]['Value']['#text']
indicator = metadata['GenericMetadata']['MetadataSet']\
['AttributeValueSet'][2]['ReportedAttribute']\
[1]['ReportedAttribute'][4]['Value']['#text']
print(f'Country: {country}; Indicator: {indicator}')
Out[1]:
Country: United Kingdom;
Indicator: Import Price Index, All Commodities
The GenericMetadata
method returns several options for country and indicator names, so it may be helpful to step into the JSON data and examine what is available directly.
More complex requests
Perhaps we are interested in the share of goods the U.K. imports from the European Union, which requires information on both trade between the U.K and the EU, and on total U.K. trade. The API allows you to combine along a single dimension by adding '+'. For example, searching for the dimension 4 (CL_COUNTERPART_AREA_DOT
) code using the technique described in part 2 returns B0
as the code for the EU, and W00
as the code for the world (total trade).
Pandas is used for calculations and to make a simple line plot of the result.
In[2]:
import pandas as pd # pandas version 0.22
# key includes two partners, B0 and W00 for EU and world
key = 'CompactData/DOT/M.GB.TMG_CIF_USD.B0+W00'
# Retrieve data from IMF API
data = requests.get(f'{url}{key}').json()
# Convert results to pandas dataframe
df = pd.DataFrame({s['@COUNTERPART_AREA'] : {pd.to_datetime(i['@TIME_PERIOD']) :
round(float(i['@OBS_VALUE']), 1) for i in s['Obs']}
for s in data['CompactData']['DataSet']['Series']})
# 12 month moving average of EU share of total
eu_share = (df['B0'].div(df['W00']) * 100).rolling(12).mean()
# Create a line plot and print most recent value as x label
title = "U.K. imports of goods: European Union share of total"
recent = f"{eu_share.index[-1].strftime('%B %Y')}: {eu_share[-1].round(1)}%"
ax = eu_share.plot(title=title)
ax = ax.set_xlabel(recent)
Out[2]:
Additional resources
IMF API documentation:
The Data Services section of the IMF's website offers useful guidance on the APIs, and has a separate news section, which is a good place to check if something breaks. Finally, some guidance on handling large queries is available here:
Learning python for exploratory data analysis:
R package by Mingjer Lee to access the IMF API: https://github.com/mingjerli/IMFData