Skip to main content

Simple Python interface to any SDMX 2.1 REST API (Eurostat, ISTAT, and more)

Project description

opensdmx

Simple Python CLI and library for any SDMX 2.1 REST API. Default provider: Eurostat. Built-in support for ISTAT, OECD, ECB, World Bank, and more.

Best used with AI. opensdmx works well on its own, but it shines when driven by an AI agent: the CLI is designed to be composed, queried, and orchestrated step by step. For a guided, interactive experience — dataset discovery, schema exploration, filter selection, and data retrieval — pair it with the sdmx-explorer Agent Skill included in this repo.

Installation

As a CLI tool (recommended — available system-wide):

uv tool install opensdmx

As a library (for use in Python projects):

uv add opensdmx
# or
pip install opensdmx

CLI quick start

opensdmx search "unemployment"
opensdmx info une_rt_m
opensdmx constraints une_rt_m geo
opensdmx get une_rt_m --freq M --geo IT --sex T --out data.csv

Python quick start

import opensdmx

# Default provider: Eurostat
datasets = opensdmx.all_available()
print(datasets.head())

# Search by keyword
results = opensdmx.search_dataset("unemployment")

# One-liner retrieval (Eurostat default)
data = opensdmx.fetch("une_rt_m", freq="M", geo="IT", sex="T", age="TOTAL")

# Switch provider
opensdmx.set_provider("istat")
opensdmx.set_provider("oecd")
opensdmx.set_provider("ecb")

Providers

import opensdmx

# Built-in presets
opensdmx.set_provider("eurostat")   # default
opensdmx.set_provider("istat")
opensdmx.set_provider("oecd")
opensdmx.set_provider("ecb")
opensdmx.set_provider("worldbank")

# Custom provider
opensdmx.set_provider("https://mysdmx.org/rest", agency_id="XYZ", rate_limit=1.0)

# Check active provider
opensdmx.get_provider()  # returns dict with base_url, agency_id, rate_limit, language

Python API

Function Description
set_provider(name_or_url, ...) Set active provider ('eurostat', 'istat', or custom URL)
get_provider() Return active provider config dict
all_available() List all datasets → Polars DataFrame
search_dataset(keyword) Search by keyword in description
load_dataset(id) Create a dataset object (dict)
print_dataset(ds) Print dataset summary
dimensions_info(ds) Dimension metadata → Polars DataFrame
get_dimension_values(ds, dim) Codelist values for a dimension
get_available_values(ds) Values actually present in the data (via availableconstraint)
set_filters(ds, **kwargs) Set dimension filters
reset_filters(ds) Reset all filters to "." (all)
get_data(ds, ...) Retrieve data → Polars DataFrame
fetch(id, ..., **filters) One-liner: load dataset + set filters + get data
set_timeout(seconds) Get/set API timeout (default: 300 s)
parse_time_period(series) Convert SDMX time strings to dates

get_data and fetch parameters

Parameter Type Description
start_period str Start date: "2020", "2020-Q1", "2020-01"
end_period str End date (same formats)
last_n_observations int Return only last N observations per series
first_n_observations int Return only first N observations per series

Example: EU Unemployment Rate

import opensdmx
from plotnine import ggplot, aes, geom_line, geom_point, labs, theme_minimal, scale_x_date

# Eurostat monthly unemployment by sex and age
ds = opensdmx.load_dataset("une_rt_m")
ds = opensdmx.set_filters(ds, freq="M", geo="IT", sex="T", age="TOTAL", s_adj="SA", unit="PC_ACT")
data = opensdmx.get_data(ds, start_period="2015", last_n_observations=60)

import polars as pl
data = data.with_columns(pl.col("OBS_VALUE").cast(pl.Float64))

plot = (
    ggplot(data.to_pandas(), aes(x="TIME_PERIOD", y="OBS_VALUE"))
    + geom_line(color="#1f77b4", size=1)
    + geom_point(color="#1f77b4", size=0.8)
    + labs(title="Italy Unemployment Rate (Monthly)", x="Year", y="Rate (%)")
    + scale_x_date(date_breaks="2 years", date_labels="%Y")
    + theme_minimal()
)
plot.save("unemployment.png", dpi=150, width=10, height=5)

CLI

Commands

All commands accept --provider (-p) to select the provider.

Command Description
opensdmx search <keyword> [-p provider] Keyword search in dataset descriptions
opensdmx search --semantic <query> Semantic search (requires opensdmx embed)
opensdmx embed [-p provider] Build semantic embeddings cache via Ollama
opensdmx info <id> [-p provider] Show dataset metadata and dimensions
opensdmx values <id> <dim> [-p provider] Show codelist values for a dimension
opensdmx constraints <id> [dim] [-p provider] Show values actually present in the dataflow (via availableconstraint)
opensdmx get <id> [--DIM VALUE] [--start-period P] [--end-period P] [--last-n N] [--first-n N] [--out file] [-p provider] Download data (CSV/parquet/JSON)
opensdmx plot <id> [--DIM VALUE] [--out file] [-p provider] Plot data as line chart
opensdmx blacklist [-p provider] List and remove datasets from the unavailability blacklist

Examples

# Eurostat (default)
opensdmx search "unemployment"
opensdmx info une_rt_m
opensdmx constraints une_rt_m
opensdmx constraints une_rt_m geo
opensdmx get une_rt_m --freq M --geo IT --out data.csv

# Other providers
opensdmx search "disoccupazione" --provider istat
opensdmx get 151_929 --provider istat --FREQ A --REF_AREA IT --out data.csv
opensdmx search "GDP" --provider oecd
opensdmx search "inflation" --provider ecb

Semantic search setup

Requires Ollama with the nomic-embed-text-v2-moe model:

ollama pull nomic-embed-text-v2-moe
opensdmx embed              # build embeddings for default provider (eurostat)
opensdmx embed -p istat     # build embeddings for ISTAT
opensdmx search --semantic "unemployment"

Caching

Cache is namespaced per provider under ~/.cache/opensdmx/{AGENCY_ID}/.

File Content TTL
~/.cache/opensdmx/ESTAT/dataflows.parquet Eurostat catalog 24h
~/.cache/opensdmx/ESTAT/cache.db Dimensions, codelists, constraints (SQLite) 7 days
~/.cache/opensdmx/IT1/dataflows.parquet ISTAT catalog 24h
~/.cache/opensdmx/IT1/cache.db ISTAT SQLite cache 7 days

Timeout

opensdmx.set_timeout()      # get current timeout (default: 300s)
opensdmx.set_timeout(600)   # set to 10 minutes

Acknowledgements

Inspired by istatR by @jfulponi and istatapi by @Attol8.

License

MIT License — Copyright (c) 2026 Andrea Borruso

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

opensdmx-0.2.1.tar.gz (27.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

opensdmx-0.2.1-py3-none-any.whl (31.9 kB view details)

Uploaded Python 3

File details

Details for the file opensdmx-0.2.1.tar.gz.

File metadata

  • Download URL: opensdmx-0.2.1.tar.gz
  • Upload date:
  • Size: 27.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.2

File hashes

Hashes for opensdmx-0.2.1.tar.gz
Algorithm Hash digest
SHA256 a268ae5528755df4340d4ad82cd0d8743d575b9cbe930025ae2503fe025d85d9
MD5 97f1c0f503c80c2d2a61cf09fc947a2a
BLAKE2b-256 1dbe5e7ed719dc85ec9e2d17a72bf0736ce006303e9a11f20dc3ed4070f9d328

See more details on using hashes here.

File details

Details for the file opensdmx-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: opensdmx-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 31.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.2

File hashes

Hashes for opensdmx-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a9b5ea8987b3c9e42704b0498c864d261877f9f6bec6859d7900dc3b8f2d7e83
MD5 5ddd001f583d0d97a400631fc6dd035b
BLAKE2b-256 b115b0531d7cca002c6476cfaff894c3852e7573faf0c4cc14f65cb17294b371

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page