Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
8660dcd
merge branch develop
Mar 12, 2026
e0a4089
table builder, integration tests, and more
Mar 12, 2026
c803c85
linting
Mar 12, 2026
d194a5b
merge branch develop
Mar 12, 2026
4f89b17
bit of cleanup
Mar 13, 2026
ee3753b
some more updates, cleanup, and apps.json
Mar 14, 2026
6392d98
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Mar 14, 2026
204f5f1
codespell
Mar 14, 2026
3f851ad
Merge branch 'feature/refactor-oecd' of https://github.com/OpenBB-fin…
Mar 14, 2026
26e1a76
black
Mar 14, 2026
7cb860c
integration test params and linting
Mar 14, 2026
42cfe32
mypy
Mar 14, 2026
a1e59c6
pylint
Mar 14, 2026
17f0437
black
Mar 14, 2026
cf6b9bd
more pylint
Mar 14, 2026
661482b
recapture teest cassettes
Mar 14, 2026
139af2c
black again
Mar 14, 2026
e07e5df
more linting
Mar 14, 2026
24d16d6
table presentation choices
Mar 15, 2026
5601110
black
Mar 15, 2026
fbe4186
fix merge conflict
Mar 17, 2026
ae0adb3
Merge branch 'develop' of https://github.com/OpenBB-finance/OpenBB in…
Mar 17, 2026
cd52032
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Mar 18, 2026
978c579
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Mar 19, 2026
b2de132
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Mar 22, 2026
254f70b
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Mar 24, 2026
b1a54b2
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Mar 30, 2026
89a5033
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Apr 1, 2026
12d690f
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Apr 1, 2026
3eac753
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Apr 3, 2026
3c3bc71
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Apr 4, 2026
0ce55ac
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Apr 7, 2026
2f39fe1
Merge branch 'develop' of https://github.com/OpenBB-finance/OpenBB in…
deeleeramone Apr 7, 2026
0582243
split up metadata module and reformat cache to use msgpack
deeleeramone Apr 10, 2026
9699f98
mypy
deeleeramone Apr 10, 2026
f7c93fe
regenerate lock file
deeleeramone Apr 10, 2026
c55c4ff
use json and include dependencies to make openbb-oecd a standalone in…
deeleeramone Apr 10, 2026
7b44341
pylint
deeleeramone Apr 10, 2026
40df8f6
more linting
deeleeramone Apr 10, 2026
d6cc133
serve metadata as dependency instead of assign and initialize
deeleeramone Apr 10, 2026
ef8888a
fix integration_tests_testers to not count dependency injections as p…
deeleeramone Apr 13, 2026
fb7d208
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Apr 13, 2026
1e09cfc
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Apr 14, 2026
a62ba29
Merge branch 'develop' into feature/refactor-oecd
piiq Apr 14, 2026
2224a9d
add assets to git ignore
deeleeramone Apr 14, 2026
4996c76
merge branch develop
deeleeramone Apr 18, 2026
8404770
ruff
deeleeramone Apr 18, 2026
fba38fc
merge branch develop
deeleeramone Apr 20, 2026
5d02dd7
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Apr 20, 2026
68b11ef
Merge branch 'develop' into feature/refactor-oecd
deeleeramone Apr 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ cli/openbb_cli/assets/styles/user/*

# Platform
openbb_platform/core/openbb/package/*
openbb_platform/providers/oecd/openbb_oecd/assets/*
openbb_platform/providers/imf/openbb_imf/assets/*

# Dev Container env
obb/*
Expand Down
41 changes: 41 additions & 0 deletions openbb_platform/extensions/economy/integration/test_economy_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,24 @@ def test_economy_gdp_real(params, headers):
"provider": "fred",
}
),
(
{
"country": "united_states",
"start_date": None,
"end_date": None,
"provider": "oecd",
"frequency": "quarterly",
}
),
(
{
"country": "united_states",
"start_date": None,
"end_date": None,
"provider": "oecd",
"frequency": "quarterly",
}
),
],
)
@pytest.mark.integration
Expand Down Expand Up @@ -582,6 +600,20 @@ def test_economy_fred_regional(params, headers):
"pivot": False,
}
),
(
{
"provider": "oecd",
"country": "united_states",
"symbol": "DF_PRICES_ALL::CPI",
"start_date": "2026-01-01",
"end_date": None,
"frequency": "month",
"transform": None,
"dimension_values": None,
"limit": 1,
"pivot": False,
}
),
],
)
@pytest.mark.integration
Expand Down Expand Up @@ -609,6 +641,15 @@ def test_economy_indicators(params, headers):
"symbol": None,
}
),
(
{
"provider": "oecd",
"topic": None,
"query": "balance+trade",
"dataflows": None,
"keywords": None,
}
),
],
)
@pytest.mark.integration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,15 @@ def test_economy_gdp_real(params, obb):
"provider": "fred",
}
),
(
{
"country": "united_states",
"start_date": None,
"end_date": None,
"provider": "oecd",
"frequency": "quarterly",
}
),
],
)
@pytest.mark.integration
Expand Down Expand Up @@ -549,6 +558,15 @@ def test_economy_country_profile(params, obb):
"symbol": None,
}
),
(
{
"provider": "oecd",
"topic": None,
"query": "balance+trade",
"dataflows": None,
"keywords": None,
}
),
],
)
@pytest.mark.integration
Expand Down Expand Up @@ -603,6 +621,20 @@ def test_economy_available_indicators(params, obb):
"pivot": False,
}
),
(
{
"provider": "oecd",
"country": "united_states",
"symbol": "DF_PRICES_ALL::CPI",
"start_date": "2026-01-01",
"end_date": None,
"frequency": "month",
"transform": None,
"dimension_values": None,
"limit": 1,
"pivot": False,
}
),
],
)
@pytest.mark.integration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ async def risk_premium(
APIEx(parameters={"provider": "fred", "country": "brazil"}),
APIEx(parameters={"provider": "ecb"}),
APIEx(parameters={"report_type": "summary", "provider": "ecb"}),
APIEx(parameters={"provider": "oecd"}),
APIEx(parameters={"provider": "oecd", "country": "japan"}),
APIEx(
description="The `country` parameter will override the `report_type`.",
parameters={"country": "united_states", "provider": "ecb"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,33 @@
import os
from collections.abc import Callable
from typing import (
Annotated,
Any,
Literal,
get_args,
get_origin,
)

try:
from fastapi.params import Depends as FastAPIDepends
except ImportError:
FastAPIDepends = type(None)

from openbb_core.app.provider_interface import ProviderInterface
from openbb_core.app.router import CommandMap

from .integration_tests_generator import find_extensions


def _is_depends_param(param: inspect.Parameter) -> bool:
if isinstance(param.default, FastAPIDepends):
return True
if get_origin(param.annotation) is Annotated:
metadata = get_args(param.annotation)[1:]
return any(isinstance(item, FastAPIDepends) for item in metadata)
return False


def get_integration_tests(
test_type: Literal["api", "python"], filter_charting_ext: bool | None = True
) -> list[Any]:
Expand Down Expand Up @@ -260,10 +277,12 @@ def check_integration_tests(
for function in processing_functions:
if route.replace("/", "_")[1:] == function.replace("test_", ""):
sig = inspect.signature(cm.map[route])
param_names = list(sig.parameters.keys()) + ["return"]
processing_command_params = [
{k: "" for k in param_names}
]
param_names = [
name
for name, param in sig.parameters.items()
if not _is_depends_param(param)
] + ["return"]
processing_command_params = [{k: "" for k in param_names}]
if (
not processing_command_params
or len(functions[function].pytestmark) < 2
Expand Down
187 changes: 182 additions & 5 deletions openbb_platform/providers/oecd/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,190 @@
# OpenBB OECD Provider
# OpenBB OECD Provider Extension

This extension integrates the [OECD](https://stats.oecd.org) data provider into the OpenBB Platform.
This package adds the `openbb-oecd` provider extension to the Open Data Platform by OpenBB.

It provides everything you need — endpoints, tools, and metadata — to access and explore the entirety of
https://data-explorer.oecd.org, without any previous experience working with it.

## Installation

To install the extension:
Install from PyPI with:

```bash
```sh
pip install openbb-oecd
```

Documentation available [here](https://docs.openbb.co/platform/developer_guide/contributing).
Then build the Python static assets by running:

```sh
openbb-build
```

## Quick Start

The fastest way to get started is by connecting to the OpenBB Workspace as a custom backend.

### Start Server

```sh
openbb-api
```

This starts the FastAPI server over localhost on port 6900.

### Add to Workspace

See the documentation [here](https://docs.openbb.co/python/quickstart/workspace) for more details.

### Click to Open App

Once added, click on the app to open the dashboard.

The dashboard contains widgets with metadata and information, as well as ones for exploring and retrieving the data.

## Implementation Details

OECD publishes data through a SDMX v2 REST API, and organizes everything into "dataflows". You can think of
these as databases, each with its own dimension definitions, codelists, and observation attributes.
Some definitions are shared across dataflows, others are domain-specific.

The extension ships with a bundled metadata cache that covers all OECD dataflows. It contains dimension
definitions, codelist mappings, content constraints, and the full topic taxonomy. When anything is missing
from the bundled cache, it is fetched on first use and added to a user-writable cache file that persists
across sessions.

Input is validated against the dataflow's content constraints. Codes are resolved to human-readable labels
in the output, and dataset and series metadata are returned alongside the observations.

### Indicators

In this library, we use the term "indicator" to refer to indicator-like dimensions within individual dataflows.
These are dimensions that represent what is being measured, such as `MEASURE`, `SUBJECT`, `TRANSACTION`, or
`ACTIVITY`. The specific dimension varies by dataflow.

The OECD codes for these values — `B1GQ`, `CPI`, `LI`, etc. — are used to construct ticker-like symbols.

### Symbology

The Open Data Platform refers to all time series IDs as a `symbol`.
Requesting data requires a symbol constructed from the dataflow's short ID and an identifier, joined with `::`.

The identifier can be either:

- An indicator-like code, such as `CPI`, `LI`, or `B1GQ`
- A presentation table identifier, such as `T0101`

```
DF_PRICES_ALL::CPI — Consumer Price Index, all items
DF_QNA::B1GQ — GDP, expenditure approach (Quarterly National Accounts)
DF_CLI::LI — Composite Leading Indicator
DF_EO::GDPV_USD — GDP forecast, volume (Economic Outlook)
DF_BOP::B6_USD — Current account balance
DF_QNA::T0101 — Quarterly National Accounts presentation table
```

Multiple indicators from the same dataflow can be comma-separated:

```
DF_PRICES_ALL::CPI,DF_PRICES_ALL::HICP
```

Use `obb.economy.available_indicators(provider="oecd")` to search for or list indicator symbols.

Use `obb.oecd_utils.list_tables()` and `obb.oecd_utils.get_table_detail()` to discover presentation tables and inspect their dimensions.

Use `obb.oecd_utils.get_dataflow_parameters()` to see all dimensions and valid codes for any dataflow.

### Metadata Cache

The library ships with a bundled base cache (`oecd_cache.msgpack.xz`) containing:

- All dataflow IDs, names, and version metadata
- DSD dimension definitions and codelist references for every dataflow
- All codelist code-to-label mappings
- Content constraints (valid value sets per dimension)
- The full OECD topic taxonomy (category scheme and categorisations)

When a structure is missing, it is fetched on demand and merged into a user-level cache stored in the
OpenBB user cache directory as `oecd_cache.msgpack.gz`. If that directory cannot be resolved from OpenBB
settings, the fallback location is `~/.openbb_platform/cache/oecd_cache.msgpack.gz`.

## Coverage

All data available from https://data-explorer.oecd.org can be retrieved via `obb.economy.indicators(provider='oecd', **kwargs)`.

The extension also exposes specialized fetchers for the most commonly used OECD datasets.

The extension creates a router path, `oecd_utils`, that exposes utility functions for UI integrations
and metadata lookup.

### Endpoints

**Economy**

- `obb.economy.available_indicators` — search all OECD indicator symbols
- `obb.economy.indicators` — fetch data for any OECD indicator symbol
- `obb.economy.balance_of_payments` — Balance of Payments
- `obb.economy.composite_leading_indicator` — Composite Leading Indicators
- `obb.economy.cpi` — Consumer Price Indices
- `obb.economy.country_interest_rates` — Short and long-term interest rates
- `obb.economy.gdp.nominal` — Nominal GDP
- `obb.economy.gdp.real` — Real GDP
- `obb.economy.gdp.forecast` — GDP forecasts (Economic Outlook)
- `obb.economy.house_price_index` — Residential property price indices
- `obb.economy.share_price_index` — Share price indices
- `obb.economy.unemployment` — Unemployment rates

**Utilities**

- `obb.oecd_utils.list_topic_choices` — topic dropdown choices for UI widgets
- `obb.oecd_utils.list_subtopic_choices` — subtopic dropdown choices for a selected topic
- `obb.oecd_utils.list_dataflows` — list all OECD dataflows with topic breadcrumbs
- `obb.oecd_utils.list_dataflow_choices` — dropdown choices for UI widgets
- `obb.oecd_utils.list_topics` — browse OECD topics and subtopics with dataflow counts
- `obb.oecd_utils.get_dataflow_parameters` — dimensions and valid codes for a dataflow
- `obb.oecd_utils.list_tables` — search OECD presentation tables
- `obb.oecd_utils.get_table_detail` — inspect a table's dimensions and indicator hierarchy
- `obb.oecd_utils.list_table_choices` — table dropdown choices for UI widgets
- `obb.oecd_utils.presentation_table_choices` — progressive choices for the presentation table widget
- `obb.oecd_utils.presentation_table` — retrieve formatted OECD presentation tables

"Choices" endpoints are used by OpenBB Workspace to populate widget dropdown menus.

### Example

```python
from openbb import obb

# List all available OECD indicators to find what you need
indicators = obb.economy.available_indicators(provider="oecd", query="GDP")
print(indicators.to_df())

# Fetch real GDP growth for the US, UK, and Germany
data = obb.economy.indicators(
provider="oecd",
symbol="DF_QNA::B1GQ",
country="USA,GBR,DEU",
frequency="quarterly",
)
print(data.to_df())

# Fetch a presentation table directly
table = obb.economy.indicators(
provider="oecd",
symbol="DF_QNA::T0101",
country="USA",
frequency="Q",
limit=4,
)
print(table.to_df())

# Inspect all dimensions and valid values for a dataflow
params = obb.oecd_utils.get_dataflow_parameters(
dataflow_id="DF_PRICES_ALL", output_format="json"
)
print(params.results)

# Search available presentation tables
tables = obb.oecd_utils.list_tables(query="GDP")
print(tables.results)
```
1 change: 1 addition & 0 deletions openbb_platform/providers/oecd/integration/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""OECD Utilities Router Module Integration Tests."""
Loading
Loading