April 5, 2017 Update: I’ve put together a newer version of the code/guide located here.
The following tutorial shows how to use python’s requests package to get data directly from the International Monetary Fund (IMF). The IMF’s application programming interface (API) provides access to economic and financial data of more than 180 countries over more than 60 years.
More information on the IMF Data API
The IMF offers guidance on using their data services. The API is not stable, so check the IMF data services news if you receive error messages.
More information on Python
This example works with the Anaconda distribution of Python 2.7.
A short example: Loading IMF data into pandas
Below is a short working example of loading the Australian export price index time-series from International Financial Statistics (IFS) into a pandas dataframe directly from the IMF API.
In [1]:
# Example: loading IMF data into pandas # Import libraries import requests import pandas as pd # URL for the IMF JSON Restful Web Service, # IFS database, and Australian export prices series url = 'http://dataservices.imf.org/REST/SDMX_JSON.svc/CompactData/IFS/Q.AU.PXP_IX.?startPeriod=1957&endPeriod=2016' # Get data from the above URL using the requests package data = requests.get(url).json() # Load data into a pandas dataframe auxp = pd.DataFrame(data['CompactData']['DataSet']['Series']['Obs']) # Show the last five observiations auxp.tail()
Out [1]:
@BASE_YEAR | @OBS_VALUE | @TIME_PERIOD | |
---|---|---|---|
232 | 2010 | 94.6044171093095 | 2015-Q1 |
233 | 2010 | 90.4668716801789 | 2015-Q2 |
234 | 2010 | 90.4668716801789 | 2015-Q3 |
235 | 2010 | 85.5465473860777 | 2015-Q4 |
236 | 2010 | 81.5208275090858 | 2016-Q1 |
Breaking down the URL
The ‘key’ in our request is the URL, which contains instructions about which data we want.
The URL has three parts,
- http://dataservices.imf.org/REST/SDMX_JSON.svc/CompactData/ The base for requests using the JSON restful data service;
- IFS/ the database ID, IFS, for International Financial Statistics;
- Q.AU.PXP_IX.?startPeriod=1957&endPeriod=2016 the data dimension and time period information.
The third part, data dimension and time period information, is broken down on the IMF Web Service knowledge base as:
{item1 from dimension1}+{item2 from dimension1}{item N from dimension1}.{item1 from dimension2} +{item2 from dimension2}+{item M from dimension2}? startPeriod={start date}&endPeriod={end date}
For guidance on finding dimension information and building your request, see my previous example of using the IMF API to retrieve Direction of Trade Statistics (DOTS) data.
Cleaning up the dataframe
Let’s add more meaningful headers and set the date as our index
In [2]:
# Rename columns auxp.columns = ['baseyear','auxp','date'] # Set the price index series as a float (rather than string) auxp.auxp = auxp.auxp.astype(float) # Read the dates as quarters and set as the dataframe index rng = pd.date_range(pd.to_datetime(auxp.date[0]), periods=len(auxp.index), freq='QS') auxp = auxp.set_index(pd.DatetimeIndex(rng)) del auxp['date'] # Show last five rows auxp.tail()
Out [2]:
baseyear | auxp | |
---|---|---|
2015-01-01 | 2010 | 94.604417 |
2015-04-01 | 2010 | 90.466872 |
2015-07-01 | 2010 | 90.466872 |
2015-10-01 | 2010 | 85.546547 |
2016-01-01 | 2010 | 81.520828 |
Plot the data
Now we can use matplotlib to create a line plot showing the history of the Australian export price index.
In [3]:
# import matplotlib and pyplot import matplotlib as mpl import matplotlib.pyplot as plt %matplotlib inline # Create line plot and add labels and title auxp.auxp.plot(grid=True, figsize=(9, 5), color="orange", linewidth=2,) plt.ylabel('Index') plt.xlabel('Year') plt.title('Australia: Export Price Index (baseyear=' + str(auxp.baseyear[0]) + ')');
Out [3]:
Save as a csv file
To save the data for use in another program, you can easily create a csv file.
In [4]:
auxp.to_csv('auxp.csv')
Update 2 (August 2018)
The IMF API and python have changed since my original post on using the IMF API.
The version on my newer website still works.
Here’s an updated chunk of code for the retrieval of information on Australia’s export prices. When run in a jupyter notebook cell, this version returns a graph of the 12-month percent change in the Australian export price index. The code also shows how to use a dictionary comprehension to convert the IMF API json data into a pandas series.
In [1]:
import requests import pandas as pd %matplotlib inline url = 'http://dataservices.imf.org/REST/SDMX_JSON.svc/' key = 'CompactData/IFS/Q.AU.PXP_IX' # adjust codes here r = requests.get(f'{url}{key}').json() obs = r['CompactData']['DataSet']['Series']['Obs'] (pd.Series({pd.to_datetime(i['@TIME_PERIOD']): float(i['@OBS_VALUE']) for i in obs}).pct_change(12).multiply(100) .plot(title='Australia Export Price Index Inflation Rate'))