FULL-COVERAGE ingest of IMF Data via the new SDMX 2.1 REST API (api.imf.org). Enumerates EVERY dataflow, then pulls each one fully via SDMX-CSV and writes ONE grouped Parquet per dataflow (or per dataflow+frequency for the giants) to data/clean_full/imf/<DATAFLOW_ID>[__<FREQ>].parquet with columns:…
International Monetary Fund. Retrieved from https://data.imf.org. Compiled and redistributed by the Elkassabgi Data Library.
Processing: Retrieved from the official source, normalized to a long {series_key, obs_date, value} schema (period-start dates), de-duplicated, and stored as zstd Parquet. Compiled and redistributed by the Elkassabgi Data Library.
FULL-COVERAGE ingest of IMF Data via the new SDMX 2.1 REST API (api.imf.org). Enumerates EVERY dataflow, then pulls each one fully via SDMX-CSV and writes ONE grouped Parquet per dataflow (or per dataflow+frequency for the giants) to data/clean_full/imf/<DATAFLOW_ID>[__<FREQ>].parquet with columns: series_key (the joined SDMX dimension values), obs_date, value, freq. Why SDMX-CSV + detail=dataonly + all-key: * The new API's JSON serializer throws JsonGenerationException on multi-series queries and SDMX-ML returns 500; SDMX-CSV (Accept application/vnd.sdmx.data+csv) is reliable. (Confirmed against the legacy IMF connector + live probing.) * `/all?dimensionAtObservation=AllDimensions` returns the ENTIRE dataflow in one request (every country x indicator x frequency series). * `detail=dataonly` strips the bulky per-row metadata columns (FULL_DESCRIPTION, METHODOLOGY, ...) WITHOUT changing the observation count -- verified identical row counts (FDI: 70,848 obs both ways), ~28x smaller transfer. GIANT dataflows (BOP, DIP, IIP, PIP, ...) are frequency-CHUNKED: we read the DSD dimension order, locate FREQUENCY, and issue one positional-key request per frequency value (e.g. BOP key '....A', '....Q', '....M'). Each chunk is a smaller, independent, restart-safe request and lands in its own parquet part. (The IMF SDMX server supports neither HTTP Range resume nor c[DIM]=val component filtering -- both verified to fail -- so positional keys are the chunking mechanism.) Coverage policy: * Pull all 102 BASE (latest) dataflows = the current data. * SKIP the 91 *_VINTAGE dataflows: each is a point-in-time re-release snapshot of a base dataflow (e.g. BOP_2026_JAN_VINTAGE is a snapshot of BOP). Pulling every vintage would duplicate enormous amounts of identical series. --vintages adds them. Ordering: small/medium dataflows first (banked quickly), known giants last, so a process kill (the host OOM-kills the many concurrent ingest jobs periodically) costs at most one chunk, never blocks the rest. Memory is bounded: each HTTP body streams to a temp .gz, then parses row-by-row and flushes to the Parquet writer in RecordBatches; no dataflow is held whole in RAM. License: imf-terms (re-serveable; must disclose data is available free of charge). Usage: python jobs/ingest_imf_full.py --list # enumerate catalog, no data python jobs/ingest_imf_full.py --only FDI,CPI # just these dataflows python jobs/ingest_imf_full.py --skip-existing # full run, resume python jobs/ingest_imf_full.py # full run (all 102 base) python jobs/ingest_imf_full.py --vintages # also include vintage snapshots
{
"@context": "https://schema.org/",
"@type": "Dataset",
"name": "IMF Data",
"description": "FULL-COVERAGE ingest of IMF Data via the new SDMX 2.1 REST API (api.imf.org). Enumerates EVERY dataflow, then pulls each one fully via SDMX-CSV and writes ONE grouped Parquet per dataflow (or per dataflow+frequency for the giants) to data/clean_full/imf/<DATAFLOW_ID>[__<FREQ>].parquet with columns:…",
"url": "https://econdatalibrary.com/imf.html",
"identifier": "imf",
"isAccessibleForFree": true,
"publisher": {
"@type": "Organization",
"name": "Econ Data Library",
"url": "https://econdatalibrary.com"
},
"creator": {
"@type": "Organization",
"name": "IMF Data"
},
"license": "imf-terms",
"keywords": [
"prices",
"rates",
"imf"
],
"temporalCoverage": "1960-01-01/2026-04-01",
"repeatFrequency": "P1M",
"creditText": "Source: IMF -- this data is available free of charge",
"citation": "International Monetary Fund. Retrieved from https://data.imf.org. Compiled and redistributed by the Elkassabgi Data Library.",
"sameAs": [
"https://huggingface.co/datasets/econdatalibrary-imf",
"https://zenodo.org/communities/econdatalibrary"
],
"distribution": [
{
"@type": "DataDownload",
"encodingFormat": "text/csv",
"contentUrl": "https://econdatalibrary.com/download.html?source=imf"
}
]
}{
"@context": {
"@language": "en",
"@vocab": "https://schema.org/",
"cr": "http://mlcommons.org/croissant/",
"data": {
"@id": "cr:data",
"@type": "@json"
},
"dataType": {
"@id": "cr:dataType",
"@type": "@vocab"
},
"sc": "https://schema.org/",
"conformsTo": "dct:conformsTo",
"dct": "http://purl.org/dc/terms/"
},
"@type": "sc:Dataset",
"conformsTo": "http://mlcommons.org/croissant/1.0",
"name": "imf",
"description": "FULL-COVERAGE ingest of IMF Data via the new SDMX 2.1 REST API (api.imf.org). Enumerates EVERY dataflow, then pulls each one fully via SDMX-CSV and writes ONE grouped Parquet per dataflow (or per dataflow+frequency for the giants) to data/clean_full/imf/<DATAFLOW_ID>[__<FREQ>].parquet with columns:…",
"url": "https://econdatalibrary.com/imf.html",
"creator": {
"@type": "sc:Organization",
"name": "IMF Data"
},
"publisher": {
"@type": "sc:Organization",
"name": "Econ Data Library",
"url": "https://econdatalibrary.com"
},
"license": "imf-terms",
"keywords": [
"prices",
"rates"
],
"temporalCoverage": "1960-01-01/2026-04-01",
"citation": "International Monetary Fund. Retrieved from https://data.imf.org. Compiled and redistributed by the Elkassabgi Data Library.",
"distribution": [
{
"@type": "cr:FileObject",
"@id": "imf-csv",
"name": "imf-csv",
"description": "Per-series CSV, downloadable with a free API key.",
"contentUrl": "https://econdatalibrary.com/download.html?source=imf",
"encodingFormat": "text/csv"
}
]
}