imfp

imfp

Tests PyPI Version Code style: black

imfp, created and maintained by Promptly Technologies, is a Python package for downloading data from the International Monetary Fund’s RESTful JSON API.

Installation

To install the stable version of imfp from PyPi, use pip.

pip install -q --upgrade imfp

To load the library, use import:

import imfp

Workflow

The imfp package introduces four core functions: imfp.imf_databases, imfp.imf_parameters, imfp.imf_parameter_defs, and imfp.imf_dataset. The function for downloading datasets is imfp.imf_dataset, but you will need the other functions to determine what arguments to supply to imfp.imf_dataset.

Fetching a List of Databases with imf_databases

For instance, all calls to imfp.imf_dataset require a database_id. This is because the IMF serves many different databases through its API, and the API needs to know which of these many databases you’re requesting data from.

To fetch a list of available databases, use:

# Fetch list of available databases
databases = imfp.imf_databases()

See Databases for more information.

Fetching a List of Parameters and Input Codes with imf_parameters

Requests to fetch data from IMF databases are complicated by the fact that each database uses a different set of parameters when making a request. (At last count, there were 43 unique parameters used in making API requests from the various databases!) You also have to have the list of valid input codes for each parameter.

To obtain the full list of parameters and valid input codes for a given database, use:

# Fetch list of valid parameters and input codes for commodity price database
params = imfp.imf_parameters("PCPS")

The imfp.imf_parameters function returns a dictionary of data frames. Each dictionary key name corresponds to a parameter used in making requests from the database:

# Get key names from the params object
params.keys()
dict_keys(['freq', 'ref_area', 'commodity', 'unit_measure'])

Each named list item is a data frame containing the valid input codes (and their descriptions) that can be used with the named parameter.

To access the data frame containing valid values for each parameter, subset the params dict by the parameter name:

# View the data frame of valid input codes for the frequency parameter
params['freq']
input_code description
0 A Annual
1 M Monthly
2 Q Quarterly

Supplying Parameter Arguments to imf_dataset

To make a request to fetch data from the IMF API, just call imfp.imf_dataset with the database ID and keyword arguments for each parameter, where the keyword argument name is the parameter name and the value is the list of codes you want.

For instance, on exploring the freq parameter of the Primary Commodity Price System database above, we found that the frequency can take one of three values: “A” for annual, “Q” for quarterly, and “M” for monthly. Thus, to request annual data, we can call imfp.imf_dataset with freq = ["A"].

Similarly, we might search the dataframes of valid input codes for the commodity and unit_measure parameters to find the input codes for coal and index:

# Find the 'commodity' input code for coal
print(
    params['commodity']
        .loc[params['commodity']['description'].str.contains("Coal")]
)
   input_code                                    description
14      PCOAL          Primary Commodity Prices, Coal index 
15    PCOALAU      Primary Commodity Prices, Coal, Australia
16    PCOALSA  Primary Commodity Prices, Coal, South Africa 
# Find the 'unit_measure' input code for index
print(
    params['unit_measure']
        .loc[params['unit_measure']['description'].str.contains("Index")]
)
  input_code description
0         IX       Index

Finally, we can use the information we’ve gathered to make the request to fetch the data:

# Request data from the API
df = imfp.imf_dataset(database_id = "PCPS",
         freq = ["A"], commodity = ["PCOAL"],
         unit_measure = ["IX"],
         start_year = 2000, end_year = 2015)

# Display the first few entries in the retrieved data frame
df.head()
freq ref_area commodity unit_measure unit_mult time_format time_period obs_value
0 A W00 PCOAL IX 0 P1Y 2000 39.3510230293202
1 A W00 PCOAL IX 0 P1Y 2001 49.3378587284039
2 A W00 PCOAL IX 0 P1Y 2002 39.4949091648006
3 A W00 PCOAL IX 0 P1Y 2003 43.2878876950788
4 A W00 PCOAL IX 0 P1Y 2004 82.9185858052862

The returned data frame has a time_format column that contains ISO 8601 duration codes. In this case, “P1Y” means “periods of 1 year.” The unit_mult column represents the power of 10 to which the value column should be raised. For instance, if value is in millions, then the unit multiplier will be 6 (meaning 10^6). If in billions, then the unit multiplier will be 9 (meaning 10^9). For more information on interpreting the returned data frame, see Understanding the Data Frame.

Working with the Returned Data Frame

Note that all columns in the returned data frame are character vectors, and that to plot the series we will need to convert to valid numeric or date formats:

# Convert obs_value to numeric and time_period to integer year
df = df.astype({"time_period" : int, "obs_value" : float})

Then, using seaborn with hue, we can plot different indicators in different colors:

import seaborn as sns

# Plot prices of different commodities in different colors with seaborn
sns.lineplot(data=df, x='time_period', y='obs_value', hue='commodity');

Contributing

We welcome contributions to improve imfp! Here’s how you can help:

  1. If you find a bug, please open an issue
  2. To fix a bug:
    • Fork and clone the repository and open a terminal in the repository directory
    • Install uv with curl -LsSf https://astral.sh/uv/install.sh | sh
    • Install the dependencies with uv sync
    • Install a git hook to enforce conventional commits with curl -o- https://raw.githubusercontent.com/tapsellorg/conventional-commits-git-hook/master/scripts/install.sh | sh
    • Create a fix, commit it with an “Angular-style Conventional Commit” message, and push it to your fork
    • Open a pull request to our main branch

Note that if you want to change and preview the documentation, you will need to install the Quarto CLI tool.

Version incrementing, package building, testing, changelog generation, documentation rendering, publishing to PyPI, and Github release creation is handled automatically by the GitHub Actions workflow based on the commit messages.