imf-reader
A package to access IMF data.
This package supports access to IMF data with no/limited accessibility through the API, including the World Economic Outlook (WEO) database and Special Drawing Rights (SDR) data
NOTE:
WEO data comes from the IMF’s official SDMX API for releases from April 2025 onward, and from the discontinued bulk SDMX archive for the releases before it (see Coverage and known issues below). SDR data is read by parsing pages on the IMF website, which publishes no API for it. As a result, the tools in this package are subject to breakage if the IMF changes the structure of their website, or releases corrupted data files or unexpected data formats. Please report any issues you encounter.
Installation
With pip:
$ pip install imf-reader
With conda:
$ conda install imf-reader
Usage
1. World Economic Outlook (WEO) data
WEO data is accessed through SDMX (Statistical Data and Metadata eXchange) files published by the IMF. For more information on SDMX, please visit the SDMX.org.
Tools to access WEO data can be found in the weo module.
Import the weo module and call the fetch_data function to retrieve the latest WEO data.
from imf_reader import weo
df = weo.fetch_data()
print(df)
By default, the function will return the WEO data for the latest year available. You can specify a version by passing the month and year of the version you want to retrieve. NOTE: The WEO reports are released in April and October of each year. The month of the version must be either “April” or “October”.
df = weo.fetch_data(version=("April", 2020))
If the version of the data fetched is needed, it can be
retrieved from the function attribute last_version_fetched.
df = weo.fetch_data()
print(weo.fetch_data.last_version_fetched)
# >>> ('April', 2024) or whichever version was just fetched
To see which versions are available to fetch, call get_weo_versions.
weo.get_weo_versions()
# >>> [('October', 2025), ('April', 2025), ..., ('April', 2019)]
Coverage and known issues
WEO data comes from two sources, joined at April 2025:
April 2025 onward is served by the IMF’s SDMX API.
April 2019 through April 2025 is served by the bulk SDMX archive. The IMF discontinued the bulk archive after the April 2025 release, so no further release will ever be added to it.
Both sources are translated onto one vocabulary: REF_AREA_CODE is ISO3 (e.g. USA)
or a G-prefixed aggregate code (e.g. G001) on both paths, and UNIT_CODE,
REF_AREA_LABEL, UNIT_LABEL, and CONCEPT_LABEL follow the API’s vocabulary and
codelists on both paths too. Rows with a null OBS_VALUE are dropped on both paths.
PPPGDP, PPPPC, PPPEX, and NGDPRPPPPC have a null UNIT_CODE. This is not a
bug: the IMF’s own API publishes no unit at all for these four PPP / “international
dollar” concepts, and its CL_UNIT codelist has no code for “international dollar”
to translate to.
LE, LP, and LUR carry a UNIT_CODE (PE, PT) on releases served from the
bulk archive and a null one on releases served from the API. The API publishes no
unit for these concepts, and the archive’s unit varies by area as well as by concept,
so it cannot be carried forward to areas the API adds later. Read CONCEPT_CODE or
CONCEPT_LABEL rather than UNIT_CODE when working across versions for population,
employment, or unemployment.
A REF_AREA_IMF_CODE column carries the legacy numeric IMF area code on both paths
(null for areas that never had one, e.g. LIE). It’s a compatibility column for code
migrating off the numeric area code, and is slated for removal in 3.0.
Two releases in the bulk archive, April 2021 and October 2023, are corrupt
in the IMF’s own published files: the CRC-32 of the inner XML does not match, and
re-downloading reproduces the same bytes with a stable SHA-256 matching
Content-Length. They cannot be fetched by any means. get_weo_versions() omits
them; fetching one directly raises cache.BulkPayloadCorruptError with
is_retryable=False.
NOTES and LASTACTUALDATE are only populated for releases before October 2025 —
the API does not expose observation-level notes or last-actual-date.
Cache behaviour
Caching is used to avoid multiple requests to the IMF website for the same data and to enhance performance. See the Caching section below for full details on cache location, environment variable overrides, and how to clear or redirect the cache.
For more advanced usage and tools for WEO data please use the weo-reader package.
2. Special Drawing Rights (SDR) data
The SDR is an international reserve asset created by the IMF in 1969. It is not a currency, but the holder of SDRs can exchange them for usable currencies in times of need.
Read more about SDRs at: https://www.imf.org/en/About/Factsheets/Sheets/2023/special-drawing-rights-sdr
Import the module
from imf_reader import sdr
Read allocations and holdings data.
sdr.fetch_allocations_holdings()
SDRs holdings and allocations are published at a monthly frequency. The function fetches the latest data available by default. Check the latest available date
sdr.fetch_latest_allocations_holdings_date()
To retrieve SDR holdings and allocations for a specific month and year, eg April 2021, pass the year and month as a tuple
sdr.fetch_allocations_holdings((2021, 4))
Read interest rates. This function gets the historical interest rates for SDRs up to the most recent value available.
sdr.fetch_interest_rates()
Read exchange rates. This function gets the historical exchange rates for SDRs up to the most recent value available.
sdr.fetch_exchange_rates()
By default, the exchange rate is in USDs per 1 SDR. To get the exchange rate in SDRs per 1 USD, pass the unit basis as “USD”
sdr.fetch_exchange_rates("USD")
To clear cached SDR data, see the Caching section below.
Caching
imf-reader caches data to disk to avoid redundant requests and to survive process restarts.
Cache location
The cache is stored in the platform-appropriate user cache directory, under a readerkit root
shared with other packages built on the same caching library, and segmented by package version
so that upgrading the package starts with a clean cache automatically:
Linux:
~/.cache/readerkit/v1/imf-reader/<version>/(e.g.~/.cache/readerkit/v1/imf-reader/2.0.0/)macOS:
~/Library/Caches/readerkit/v1/imf-reader/<version>/Windows:
%LOCALAPPDATA%\readerkit\Cache\v1\imf-reader\<version>\
Overriding the cache directory
Set the IMF_READER_CACHE_DIR environment variable before importing the package:
export IMF_READER_CACHE_DIR=/path/to/my/cache
If IMF_READER_CACHE_DIR is not set, BBLOCKS_CACHE_DIR is used instead. It is a family-wide
fallback shared with other bblocks packages, useful for pointing several packages at one shared
cache root:
export BBLOCKS_CACHE_DIR=/path/to/shared/cache
Or redirect programmatically at runtime:
from imf_reader import cache
cache.set_cache_dir("/path/to/my/cache")
cache.get_cache_dir() # inspect the current path
cache.reset_cache_dir() # restore to the default platformdirs path
Clearing the cache
The canonical way to clear all cached data:
from imf_reader import cache
cache.clear_cache() # clear everything
cache.clear_cache(scope="weo") # WEO data only
cache.clear_cache(scope="sdr") # SDR data only
cache.clear_cache(scope="http") # HTTP-layer cache only
cache.clear_cache(scope="all") # equivalent to no scope argument
A scoped clear only touches the named scope. cache.clear_cache(scope="sdr")
removes SDR data and leaves the WEO and HTTP caches intact. The HTTP-layer
clear additionally closes the active cached HTTP session.
The legacy module-level helpers still work but emit a DeprecationWarning pointing at
cache.clear_cache(). They will be removed in v3.0:
from imf_reader import weo, sdr
weo.clear_cache() # deprecated — use cache.clear_cache(scope="weo")
sdr.clear_cache() # deprecated — use cache.clear_cache(scope="sdr")
Disabling the cache for development
Disable the cache for the lifetime of the current process. While disabled, bulk downloads land in a system temp file used only for the current call, and dataframe results return without being persisted.
from imf_reader import cache
cache.disable_cache()
# ... work without caching ...
cache.enable_cache()
Network requests
HTTP requests carry a default connect/read timeout and retry with backoff on transient failures and server errors.
If the cache directory sits on an NFS mount, set READERKIT_LOCK_STRATEGY=strict-soft to switch
from native file locking to marker-file locking, which NFS supports more reliably.
Corrupted bulk downloads
If a WEO bulk SDMX download is corrupted, it is automatically evicted from the cache and a
cache.BulkPayloadCorruptError is raised. Re-running the same call will trigger a fresh
download:
from imf_reader import cache
try:
df = weo.fetch_data()
except cache.BulkPayloadCorruptError:
df = weo.fetch_data()
Contributing
The tools in this package are subject to breakage if the IMF changes the structure of their website or their data files (see the note on data sources above). If you encounter any issues, please report them.
Interested in contributing? Check out the contributing guidelines. Please note that this project is released with a Code of Conduct. By contributing to this project, you agree to abide by its terms.
License
imf-reader was initially created by Luca Picci and is maintained by the ONE Campaign. It is licensed under the terms of the MIT license.
Credits
imf-reader was created with cookiecutter and the py-pkgs-cookiecutter template.