openbb-v5.0.0
openbq-org/OpenBBopenbb-v5.0.0Sep 30, 2026by deeleeramone
Upgrading?
AI Summary
OpenBB V5 is a major version update introducing a new package line for the platform, CLI, and API, featuring a license change to Apache-2.0, a shift to hatchling/uv packaging, and extensive refactoring of core components and providers.
Key Highlights
- License changed from AGPL-3.0-only to Apache-2.0
- Migration from Poetry to hatchling/uv packaging
- Introduction of OBBStream for streaming output
- Decoupled charting system (openbb-charting 4.0.0)
- New provider: openbb-jodi
Breaking Changes
- License changed from AGPL-3.0-only to Apache-2.0
- Eighteen directories removed (16 provider packages, regulators extension, test-only famafrench tree)
- poetry.lock removed and replaced with uv.lock
- Dependencies now target the V5 package line (openbb metapackage is 5.0.0)
New Features
- Layered openbb.toml configuration system
- Spec-driven platform-api and MCP proxies
- CLI 2.0 with .spec files and codegen
- Provider-owned routers with conditional registration
- AsyncIterator support for streaming output
Full Release Notes
# OpenBB V5 Changelog
OpenBB V5 is the new major-version line of the kept packages under `openbb_platform/` and `cli/`.
The `openbb` metapackage is now 5.0.0; the core, CLI, API, MCP server, routers and most providers are 2.0.0; exceptions include openbb-devtools (1.6.8 -> 2.0.1), openbb-charting (3.0.0 -> 4.0.0) and openbb-imf (2.1.3 -> 2.1.2 -> 3.0.0).
The repository license changed from AGPL-3.0-only to Apache-2.0 in [#7677](https://github.com/OpenBB-finance/OpenBB/pull/7677), in the root `LICENSE`, every `pyproject.toml` and the desktop app.
Eighteen directories present on develop are absent on v5 (sixteen provider packages, the openbb-regulators extension and the test-only `extensions/famafrench` tree); one provider, openbb-jodi 2.0.0, is new.
Headline changes: hatchling/uv packaging, the `openbb-core[pandas]` extra, ruff and ty, layered `openbb.toml` config, `OBBStream` streaming, decoupled charting, CLI 2.0 with `.spec` files and codegen, spec-driven platform-api and MCP proxies, provider-owned routers with conditional registration, 16 provider refactors plus the new openbb-jodi provider, package 2.0 releases, the `openbb` 5.0.0 metapackage, charting 4.0, refreshed extension catalogs and a root-package publishing workflow.
The root `openbb` metapackage was migrated from Poetry 4.7.3 to hatchling/PEP 621 version 5.0.0 in direct commit `6d8e44100ab`; its dependencies now target the V5 package line, router extensions are grouped in the `routers` extra, `poetry.lock` was removed and `uv.lock` added.
<details>
<summary><h2>Pull requests</h2></summary>
<details>
<summary><h3>Core and packaging</h3></summary>
| PR | Merged | Author | Title |
|---|---|---|---|
| [#7482](https://github.com/OpenBB-finance/OpenBB/pull/7482) | 2026-04-28 | Danglewood | [Feature] OpenBB V5: Initial `openbb-core` Refactor |
| [#7484](https://github.com/OpenBB-finance/OpenBB/pull/7484) | 2026-04-30 | Danglewood | [V5] `openbb-core`: 100% Test Coverage |
| [#7492](https://github.com/OpenBB-finance/OpenBB/pull/7492) | 2026-05-07 | Danglewood | [V5] `openbb-core`: Add Backwards-Compatible Layered Config System (openbb.toml) |
| [#7537](https://github.com/OpenBB-finance/OpenBB/pull/7537) | 2026-06-18 | Danglewood | [V5] [BugFix] Fix for Breaking Changes in FastAPI 0.137+ |
| [#7524](https://github.com/OpenBB-finance/OpenBB/pull/7524) | 2026-06-22 | Danglewood | [V5] Refactor Shared Pass Through Router Extensions For Hatchling |
| [#7264](https://github.com/OpenBB-finance/OpenBB/pull/7264) | 2026-09-24 | Boris Li | Enterprise Flask Migration Toolkit |
| [#7622](https://github.com/OpenBB-finance/OpenBB/pull/7622) | 2026-09-25 | Dex Hunter | perf(core): vectorize the date conversion in `basemodel_to_df` |
| [#7681](https://github.com/OpenBB-finance/OpenBB/pull/7681) | 2026-09-26 | Danglewood | [Release] `openbb-core-v2.0.0rc1`: Testing Publish Pipeline |
</details>
<details>
<summary><h3>CLI</h3></summary>
| PR | Merged | Author | Title |
|---|---|---|---|
| [#7433](https://github.com/OpenBB-finance/OpenBB/pull/7433) | 2026-06-01 | Danglewood | [V5] CLI 2.0 - Pluggable Backends, Non-TTY Default, HTTP Dispatcher, Spec Files + Codegen |
| [#7586](https://github.com/OpenBB-finance/OpenBB/pull/7586) | 2026-07-14 | Dex | fix(cli): resolve modular OpenAPI references |
| [#7589](https://github.com/OpenBB-finance/OpenBB/pull/7589) | 2026-07-14 | Danglewood | [V5] `openbb-cli`: Modular OpenAPI Refs |
| [#7597](https://github.com/OpenBB-finance/OpenBB/pull/7597) | 2026-07-20 | Monte Hoover | Update generated tests to get python parameter names instead of raw API-provider parameter names. |
| [#7598](https://github.com/OpenBB-finance/OpenBB/pull/7598) | 2026-07-20 | Monte Hoover | Update the record-vs-envelope heuristic in the payload processing code to not treat a record that happens to have a list datatype as an entire envelope. |
| [#7599](https://github.com/OpenBB-finance/OpenBB/pull/7599) | 2026-07-20 | Monte Hoover | Update class generation code to handle empty data that php-style serialization emits as []. |
| [#7606](https://github.com/OpenBB-finance/OpenBB/pull/7606) | 2026-09-25 | Lucas Zimmermann | fix(cli): inherit path-item-level OpenAPI parameters |
</details>
<details>
<summary><h3>API, MCP and streaming</h3></summary>
| PR | Merged | Author | Title |
|---|---|---|---|
| [#7494](https://github.com/OpenBB-finance/OpenBB/pull/7494) | 2026-06-20 | Danglewood | [V5] `openbb-platform-api`: Refactor for V5 Spec, Config, Packaging, Test Coverage |
| [#7530](https://github.com/OpenBB-finance/OpenBB/pull/7530) | 2026-06-22 | Danglewood | add full support for AsyncIterator response type for streaming output |
| [#7495](https://github.com/OpenBB-finance/OpenBB/pull/7495) | 2026-09-24 | Danglewood | [V5] `openbb-mcp-server`: Refactor for v5 - Spec, Config, Packaging, Test Coverage |
</details>
<details>
<summary><h3>Charting and toolkit extensions</h3></summary>
| PR | Merged | Author | Title |
|---|---|---|---|
| [#7507](https://github.com/OpenBB-finance/OpenBB/pull/7507) | 2026-05-29 | Danglewood | [V5] `openbb-news`: Refactor News for V5 and Add Configurable RSS Endpoint |
| [#7506](https://github.com/OpenBB-finance/OpenBB/pull/7506) | 2026-05-29 | Danglewood | [V5] `openbb-quantitative`: Refactor for V5 |
| [#7502](https://github.com/OpenBB-finance/OpenBB/pull/7502) | 2026-05-29 | Danglewood | [V5] `openbb-technical`: Refactor for V5 & Add More Quick Win Endpoints |
| [#7505](https://github.com/OpenBB-finance/OpenBB/pull/7505) | 2026-06-01 | Danglewood | refactor econometrics for v5 |
| [#7545](https://github.com/OpenBB-finance/OpenBB/pull/7545) | 2026-07-01 | Danglewood | [V5] `openbb-charting`: Refactor for V5 and Decouple |
| [#7602](https://github.com/OpenBB-finance/OpenBB/pull/7602) | 2026-07-23 | Danglewood | add drugs.com and brutalist as news rss feeds |
</details>
<details>
<summary><h3>Providers — refactors and additions</h3></summary>
| PR | Merged | Author | Title |
|---|---|---|---|
| [#7413](https://github.com/OpenBB-finance/OpenBB/pull/7413) | 2026-05-15 | Danglewood | [V5] Refactor `openbb-oecd` for full SDMX 2 API Exposure and V5 Packaging |
| [#7509](https://github.com/OpenBB-finance/OpenBB/pull/7509) | 2026-05-25 | Danglewood | [V5] `openbb-oecd`: Rename `oecd_utils` as `oecd` |
| [#7508](https://github.com/OpenBB-finance/OpenBB/pull/7508) | 2026-05-29 | Danglewood | [V5] `openbb-imf`: Refactor for V5 |
| [#7518](https://github.com/OpenBB-finance/OpenBB/pull/7518) | 2026-06-01 | Danglewood | [V5] `openbb-bls`: Refactor for V5 + Add Many Endpoints |
| [#7503](https://github.com/OpenBB-finance/OpenBB/pull/7503) | 2026-06-01 | Danglewood | [V5] `openbb-famafrench`: Refactor for V5 |
| [#7528](https://github.com/OpenBB-finance/OpenBB/pull/7528) | 2026-06-08 | Danglewood | [V5] `openbb-congress-gov`: Refactor for V5 + Convert To Using Bulk Files Instead of `api.congress.gov`. |
| [#7560](https://github.com/OpenBB-finance/OpenBB/pull/7560) | 2026-09-23 | Danglewood | [V5] `openbb-ecb`: Refactor for V5 and Expand Coverage |
| [#7561](https://github.com/OpenBB-finance/OpenBB/pull/7561) | 2026-09-23 | Danglewood | [V5] `openbb-federal-reserve`: Refactor for V5 + FFIEC & Regional Fed Routers |
| [#7584](https://github.com/OpenBB-finance/OpenBB/pull/7584) | 2026-09-23 | Danglewood | [V5] `openbb-eia`: Refactor for V5 + Add Full API Implementation |
| [#7604](https://github.com/OpenBB-finance/OpenBB/pull/7604) | 2026-09-23 | Danglewood | [V5] `openbb-government-us`: Refactor for V5 + Move `uscongress` |
| [#7593](https://github.com/OpenBB-finance/OpenBB/pull/7593) | 2026-09-23 | Danglewood | [V5] Feature: Add JODI World Oil & Gas Database |
| [#7615](https://github.com/OpenBB-finance/OpenBB/pull/7615) | 2026-09-23 | Danglewood | [V5] `openbb-cftc`: Refactor for V5 + Add OIS, Forward Curve, and FX Trade Analysis |
| [#7668](https://github.com/OpenBB-finance/OpenBB/pull/7668) | 2026-09-23 | Danglewood | [V5] `openbb-tmx`: Refactor extension for V5 |
| [#7670](https://github.com/OpenBB-finance/OpenBB/pull/7670) | 2026-09-23 | Danglewood | [V5] `openbb-nasdaq`: Refactor provider for V5. |
| [#7669](https://github.com/OpenBB-finance/OpenBB/pull/7669) | 2026-09-23 | Danglewood | [V5] `openbb-fred`: Refactor as V5 extension. |
| [#7617](https://github.com/OpenBB-finance/OpenBB/pull/7617) | 2026-09-23 | Danglewood | [V5] `openbb-cboe`: Refactor for V5 + Add Payoff Diagrams |
| [#7674](https://github.com/OpenBB-finance/OpenBB/pull/7674) | 2026-09-23 | Danglewood | [V5] `openbb-deribit`: Refactor provider for V5 |
| [#7525](https://github.com/OpenBB-finance/OpenBB/pull/7525) | 2026-09-24 | Danglewood | [V5] `openbb-sec`: Refactor for V5 |
| [#7676](https://github.com/OpenBB-finance/OpenBB/pull/7676) | 2026-09-24 | Danglewood | [V5] `openbb-finra`: Refactor for V5 |
</details>
<details>
<summary><h3>Provider removals</h3></summary>
| PR | Merged | Author | Title |
|---|---|---|---|
| [#7486](https://github.com/OpenBB-finance/OpenBB/pull/7486) | 2026-05-29 | Danglewood | remove stockgrid provider |
| [#7485](https://github.com/OpenBB-finance/OpenBB/pull/7485) | 2026-05-29 | Danglewood | [V5] remove wsj provider and related code |
| [#7523](https://github.com/OpenBB-finance/OpenBB/pull/7523) | 2026-06-01 | Danglewood | delete biztoc |
| [#7522](https://github.com/OpenBB-finance/OpenBB/pull/7522) | 2026-06-01 | Danglewood | [V5] Remove `openbb-alpha-vantage` |
| [#7521](https://github.com/OpenBB-finance/OpenBB/pull/7521) | 2026-06-01 | Danglewood | [V5] Remove `openbb-benzinga` |
| [#7570](https://github.com/OpenBB-finance/OpenBB/pull/7570) | 2026-07-08 | Danglewood | remove seeking alpha provider |
| [#7573](https://github.com/OpenBB-finance/OpenBB/pull/7573) | 2026-07-08 | Danglewood | remove tradier provider |
| [#7574](https://github.com/OpenBB-finance/OpenBB/pull/7574) | 2026-07-08 | Danglewood | remove tiingo provider |
| [#7575](https://github.com/OpenBB-finance/OpenBB/pull/7575) | 2026-07-08 | Danglewood | remove intrinio provider |
| [#7576](https://github.com/OpenBB-finance/OpenBB/pull/7576) | 2026-07-08 | Danglewood | remove yfinance provider from repo |
| [#7577](https://github.com/OpenBB-finance/OpenBB/pull/7577) | 2026-09-14 | Danglewood | remove finviz |
| [#7578](https://github.com/OpenBB-finance/OpenBB/pull/7578) | 2026-09-14 | Danglewood | remove trading economics provider |
| [#7610](https://github.com/OpenBB-finance/OpenBB/pull/7610) | 2026-09-14 | Danglewood | remove openbb-multpl from repository |
| [#7665](https://github.com/OpenBB-finance/OpenBB/pull/7665) | 2026-09-14 | Danglewood | remove fmp provider extension from repository |
| [#7675](https://github.com/OpenBB-finance/OpenBB/pull/7675) | 2026-09-23 | Danglewood | remove openbb-econdb provider |
</details>
<details>
<summary><h3>License and repository tooling</h3></summary>
| PR | Merged | Author | Title |
|---|---|---|---|
| [#7677](https://github.com/OpenBB-finance/OpenBB/pull/7677) | 2026-09-24 | Danglewood | [V5] Update Repository License to Apache 2.0 |
</details>
<details>
<summary><h3>Direct commits</h3></summary>
Commits on `v5` that are not squash-merged PRs, deduplicated across packages. Bodies are available with `git log -1 --format=%B <sha>`.
- `932a895a069` fix cli renderer helper with figure object JSON (adds `PackageBuilder._distribution_version`, the CLI figure renderer and `_display_dict_result`)
- `1fa72f80d72` test coverage
- `aba09afb1c5` fixes for docstring generation (`_normalize_code_annotations`, `ruff --fix-only`, dev_install refinements, `.build.lock` gitignored)
- `1cbb24d8b7a` bump devtools and repoint pyproject.toml (openbb-devtools 2.0.0 -> 2.0.1 across 35 consumer pyprojects; editable devtools path source removed from the CLI and router extensions)
- `4fe1bbcb94f` fix tag grouping in swagger docs (composite tags, `x-tagGroups`, `docExpansion: none`)
- `35ce305fba9` fix charting conftest and missing coverage in 3.10
- `34716a17f38` unpin ruff (also thread-safe `SingletonMeta`, reference.json regeneration)
- `90d427c5a52` restore test coverage to 100% in openbb_core
- `d8fd8f06da4` some ty items and add requests-types stubs for ty in devtools
- `caf49e818cb` FieldInfo import
- `38d636a7a6f` linter
- `976a4fd098e` fix test drift
- `f56a44ec0ce` bump dependencies
- `e79623ceef0` remove comment chatter
- `3a2bfbcbafd` unpack POST parameters from params: Model
- `b455cf240a3` fix docstring generator and body param unwrapping
- `70bbf37caaa` test_system_settings
- `a18a2921311` ruff UP007
- `3a978b654ca` update for deprecated pydantic syntax (`SystemSettings` instance-mode `model_validator`)
- `f18493c293b` missing coverage
- `f899588da97` fix docstring generator for nested models
- `73b05163667` package builder fixes
- `5f4dda273b8` fix the figure font when rendered (`strip_theme_colors` in the CLI)
- `a07534cfa4a` fix ty check failures exposed by newer version
- `2c14e26acfb` fixes for ty
- `99e5c8618e2` fix new ty issues
- `1ad72fd756a` unused ty ignore
- `dc71797e063` fix lint errors (adds `PLR0917` to ruff ignores in several packages)
- `d0090d60dcd` fix lint errors (`JsonDict` annotations, `list(...)` choices in federal_reserve, bls, cftc, tmx, finra)
- `478235ca196` fix oecd lint error
- `5b1bc33e579` update pre-commit, noxfile, and uv locks (rewrote `.pre-commit-config.yaml`, `noxfile.py`, `dev_install.py`, the platform README and 35 `uv.lock` files)
- `ab707f2fe88` refactor cookiecutter
- `78ee668a2a2` bump cookiecutter packagge version (0.6.0 -> 1.0.0)
- `768e52c6358` fix merge widgets
- `bf0cb48465f` markdown linting
- `2c81a8cbb10` fix markdown lint errors
- `9bbc49675d4` consolidate lint job
- `14c0042f784` general lint setup
- `0980d4f1e11` fogot that file
- `74d9b58623b` general-linting
- `c06074f1dd7` workflow cleanup"
- `04825708836` remove v4 platform workflow
- `5d376a44141` remove that annoying labeler action
- `fd98854bf39` also run integration test in CI
- `b9730ad658a` openbb-core publish workflow
- `b6c2c79a0f0` actions
- `39e85422fe7` actions
- `fae87660088` fix publish workflows (checkout ref `develop` -> merge commit SHA in 29 publish workflows)
- `9b0e799148f` project ty.toml file
- `b6b472a511d` codespell
- `0ff1a54706e` codespell
- `30f84a3e811` charting pyproject version
- `67ebf4a4652` plotly 7 handling for mapbox namespace change
- `a2a1456dbca` fix for plotly 7 breaking change to schemas
- `b59b2b18bd2` add charting coverage
- `fbcd512905e` remove integration tests from extensions that were moved into the famafrench provider (deletes `extensions/famafrench`)
- `89b8c00b338` downgrade aiohttp in devtools for vcrpy (later reverted by `21ed5fe3672`)
- `21ed5fe3672` add httpx2 to devtools for starlette test client
- `0aa60395322` missing test coverage that appeared in famafrench..
- `32b6d4a2802` fix warnings raised by federal_reserve on some xlsx workbook parsing
- `7a70de9b722` fix sec test by adding fixture (XBRL linkbase retry and offline Apple 10-K fixtures)
- `07bf0873ae5` fix desktop environments test
- `f0258c93366` fix publish workflows with missing tag job, some tests and bump fastapi (adds a tag job to 31 publish workflows; `fastapi>=0.136.3` -> `>=0.137.2`, `aiohttp>=3.13.3` -> `>=3.14.2`; `openbb-core` dev group gains `pandas`, `pycountry`, `bs4`, `polars`; new coverage for `extension_loader.py`, `ast_analysis.py`/`introspector.py`/`loader.py`, `build.py`, `update_country_data.py`, `update_exchange_data.py`; `OpenBBField.choices` typed as `JsonValue`; `reference_generator.py` regex-match fix; version `2.0.0rc1` -> `2.0.0`)
- `4d5017ad4d9` fix python 3.10 test failure in core (`test_build.py`: assert `SystemExit` instead of mocking `sys.exit`, which Python 3.10's CI run didn't intercept)
- `45feafe11a3` actually fix python 3.10 test failure in core (`test_build.py`: reorders the `@patch("builtins.__import__")`/`@patch("...subprocess.run")` stack — on Python 3.10, `unittest.mock`'s dotted-target resolver calls the bare `__import__` builtin, so with the wrong decorator order the already-patched `__import__` intercepted `subprocess.run`'s own target resolution and let the real subprocess execute; fixed on 3.14+ only because `unittest.mock` there resolves targets via `pkgutil.resolve_name` instead)
- `220ffb7798a` Merge origin/develop into v5 (ours strategy: keep v5 as source of truth) — kept v5's copy of `openbb_platform/pyproject.toml` and `desktop/package.json`, discarding develop's pin bumps
- `86e0787e595` Merge develop into v5 (resolve conflicts in favor of v5)
- `ba81abcbc0d` merge branch develop (conflict resolution raised the devtools `ty` floor from `>=0.0.1a14` to `>=0.0.40`)
- `4fe1a41ed78`, `7007a878db1`, `7fd1d89d52c`, `074842ed4f9` merge branch develop
</details>
</details>
<details>
<summary><h2>Cross-cutting patterns</h2></summary>
- Packaging: every package moved from Poetry to hatchling with a PEP 621 `[project]` table, `[dependency-groups] dev = ["openbb-devtools>=2.0.1"]`, a committed `uv.lock` and no `poetry.lock`. The follow-up release work removed local `openbb-core` source overrides so standalone package builds resolve core 2.0.0 from PyPI. Evidence: openbb-core, openbb-cli,
openbb-platform-api, openbb-mcp-server, openbb-technical, openbb-quantitative, openbb-econometrics, openbb-charting, the nine pass-through routers, openbb-news, openbb-devtools, all 17 providers, openbb-cookiecutter.
- Core dependency floors: packages that use pandas declare `openbb-core[pandas]>=2.0.0` (cli, technical, quantitative, econometrics, charting, news, bls, cboe, cftc, deribit, ecb, us-eia, famafrench, federal-reserve, finra, fred, government-us, imf, jodi, nasdaq, oecd, sec, tmx); the nine routers,
platform-api and mcp-server declare plain `openbb-core>=2.0.0`. `pandas` itself is an optional extra of openbb-core and `require_optional("pandas")` raises `OpenBBError` with an install hint when absent.
- Lint and type checking: ruff is the only formatter and linter (`select = ["D","E","W","F","S","UP","I","PLC","PLE","PLR","PLW","SIM","T20"]`, `pydocstyle convention = "numpy"`, `line-length = 88`) and `ty` the only type checker (`[tool.ty]` per package, root `ty.toml`), with `# ty: ignore[code]`
replacing blanket `# type: ignore`. `.pylintrc` is deleted and `# pylint: disable` directives were stripped from core, cli, platform-api, mcp-server, technical, econometrics, the routers, news, deribit, cftc, sec and most providers (leftovers: `openbb_core/app/config/loader.py`, quantitative
`views/*.py`, cboe `futures_curve.py`, 22 tmx model files, `validate_corpus.py` in sec).
- Docstrings: numpy style with `Parameters`/`Returns`/`Raises` sections on public functions; `PythonEx` examples that named removed providers were dropped from quantitative and most econometrics commands.
- Test conventions: `class TestX` suites in role-named files; real installable fixture extensions instead of mocks (`openbb-fake-integration` in core's integration suite, `openbb-cli-fake` in the CLI conftest, `openbb-mcp-fixture` in mcp-server); offline unit suites driven by monkeypatched
transports or JSON fixtures (deribit, finra, nasdaq, tmx, jodi, bls, news); VCR cassettes kept where they still fit (fred, oecd, imf, ecb, famafrench, cftc, sec, us-eia, government-us); live checks moved to `integration/` packages behind an `integration` marker with an in-process uvicorn fixture
(technical, quantitative, econometrics, charting, news, cboe, cftc, deribit, ecb, famafrench, finra, jodi, nasdaq, oecd, tmx, government-us, fred).
- 100% coverage gate: `pytest tests --cov=<pkg> --cov-fail-under=100` in the 22 `test-unit-openbb-*.yml` provider and extension workflows plus `test-unit-mcp-server.yml` (branch coverage there), with `# pragma: no cover` reserved for annotated unreachable branches; core, cli and platform-api have
per-package test workflows without the fail-under flag.
- Per-package CI and release: a `test-unit-openbb-<pkg>.yml` (build once with `uv build --no-sources`, ruff check, ruff format --check, `ty check`, a 9-cell Python 3.10-3.14 OS matrix) and a `publish-openbb-<pkg>.yml` gated on a merged `release/openbb-<pkg>-v<version>` branch whose name must match
`[project].version`, a PyPI existence check and trusted publishing; 35 publish workflows exist on v5, with none for openbb-devtools or openbb-cookiecutter.
- Layered `openbb.toml` configuration: the core loader from [#7492](https://github.com/OpenBB-finance/OpenBB/pull/7492) (`load_layered_config`, `load_config`, `.env` files, `OPENBB_*` promotion) is reused by openbb-cli (`[tool.openbb-cli]`, `[specs.<ns>]`, `[settings]`), openbb-platform-api
(`--config-file`, `[launcher]`, `[env]`, `[middleware]`, `[spec]`), openbb-mcp-server (`[mcp]`, `[mcp.spec]`, `[mcp.auth]`, `[mcp.middleware]`, `[env]`), openbb-news (`[news.rss_feeds]`, `[news.rss_providers]`) and the `openbb-sec` console script (`cache_directory`).
- Spec files: the CLI writes `.spec` documents (`SPEC_VERSION = 5`, `content_sha256` integrity hash); openbb-platform-api (`--spec`, `[spec]`) and openbb-mcp-server (`--spec`, `[mcp.spec]`) synthesize aiohttp-backed proxy FastAPI apps from them with the same integrity, header-injection and zero-time
date-trimming behavior; `--generate-extension` turns a spec into an installable hatchling extension.
- Streaming: core's `OBBStream`, `Fetcher.stream_data`, `text/event-stream` route registration and `StreamingResponse` wrapper ([#7530](https://github.com/OpenBB-finance/OpenBB/pull/7530)); the CLI follows SSE streams in one-shot and REPL modes and generates streaming fetchers; the platform-api
widgets builder skips event-stream routes.
- Charting decoupling ([#7545](https://github.com/OpenBB-finance/OpenBB/pull/7545)): core resolves the engine through `ChartingManager` and the `openbb_charting_backend`/`openbb_charting_hooks` entry-point groups, with `charting_extension`/`charting_backend` system settings; views in the routers
load `openbb_charting` through `importlib.import_module` and technical moved its imports inside functions; openbb-charting is a dev-group dependency only for technical, quantitative and econometrics, an optional extra for the CLI, cboe and tmx; new `openbb_charting_extension` registrations come
from openbb-quantitative (`QuantitativeViews`) and openbb-imf (`ImfViews`).
- Provider-owned routers with conditional registration: providers ship an `openbb_core_extension` router (new on bls, cboe, deribit, ecb, us-eia, finra, fred, jodi, nasdaq, sec, tmx, government-us; replaced on federal-reserve; renamed on imf and oecd) and use `find_spec("openbb_<extension>")` flags
so standard-model fetcher keys stay standard when the owning extension is installed and switch to `Provider*` aliases plus fallback commands when it is not (bls, cboe, deribit, ecb, federal-reserve, finra, fred, imf, nasdaq, oecd, sec, tmx); us-eia and government-us gate only the fallback commands and keep standard keys.
- POST body models: data-processing commands take a single `params: XxxQueryParams` argument and return typed `Data` rows; core's `MethodDefinition.query_params_model` unpacks the model into kwargs for the static package and `filter_inputs` repacks it; every such QueryParams carries `__category__`
and `__output_columns__` (technical, quantitative, econometrics).
- Request and response plumbing: on-disk `diskcache` stores under the user cache directory with `OPENBB_<PKG>_*` overrides (cftc, ecb, federal-reserve, fred, government-us, sec, tmx) and a persisted static-asset proxy cache under `<user cache>/eia_proxy/` in us-eia; shared `aiohttp-client-cache` SQLite backends with per-URL TTLs and size sweeps (cboe, deribit, nasdaq,
tmx); per-event-loop pooled aiohttp sessions (deribit via a `loop.close` hook, tmx closed by the router lifespan); a shared `curl_cffi` Chrome-impersonating session helper for bot-managed hosts (federal-reserve, government-us, tmx, us-eia); a process-wide EDGAR rate limiter (sec); `AnnotatedResult` metadata for units,
sources and assessments (cftc, jodi, oecd, nasdaq, econometrics `garch`).
- Workspace metadata lives in code: `widget_config=` on `@router.command`, `x-widget_config` in `json_schema_extra` (endpoint-backed dropdowns, `cellOnClick`/`groupBy`, `chartDataType`), `x-unit_measurement`/`x-frontend_multiply` on rate fields, and a bundled `assets/apps.json` served at
`/<provider>/apps.json` with widget-id rewriting when the owning extension is absent; committed `widgets.json` files exist only in sec and federal-reserve.
- Static assets are real files under `assets/` loaded via `Path(__file__)` with single-pass token substitution (cli `figure.html`, us-eia `data_browser.html` and `rss_feed.html`, government-us HTML widgets, tmx screener builder, sec `filing_viewer_app.html`, ecb, federal-reserve and finra JSON
assets).
- Build-time generated catalogs: hatch custom build hooks materialize generated assets from live APIs when absent (gitignored `bls_cache.zip`, `ecb_cache.json.xz`, `eia_catalog.json.xz`, `imf_cache.json.xz`; `oecd_cache.json.xz`, claimed gitignored without a matching rule; finra's committed `security_types.json.gz`) with `generate-<pkg>-cache`/`generate-*` console
scripts and `OPENBB_<PKG>_FORCE_*_REBUILD` env flags; CI seeds the asset from the built wheel and caches it by the generator script hash.
- MCP: openbb-mcp-server switched to stateless BM25 tool discovery with `search_tools`/`call_tool` and a `run_pipeline` chaining tool; us-eia and sec ship per-extension FastMCP servers that run as subprocesses and are reverse-proxied through the provider router with a `Depends`-injected plain dict
instead of a `Request`.
- License: `license = { text = "Apache-2.0" }` in every `pyproject.toml`, `APISettings.license_name = "Apache-2.0"`, Apache text in the root and desktop `LICENSE` files.
</details>
<details>
<summary><h2>Removals</h2></summary>
Removed packages (present on develop, absent on v5):
| Package | Last develop version | Removed by | Where the functionality went |
|---|---|---|---|
| openbb-alpha-vantage | 1.6.1 | [#7522](https://github.com/OpenBB-finance/OpenBB/pull/7522) | none |
| openbb-benzinga | 1.6.1 | [#7521](https://github.com/OpenBB-finance/OpenBB/pull/7521) | none |
| openbb-biztoc | 1.6.1 | [#7523](https://github.com/OpenBB-finance/OpenBB/pull/7523) | none |
| openbb-congress-gov | 1.2.3 | [#7604](https://github.com/OpenBB-finance/OpenBB/pull/7604), after the in-place refactor in [#7528](https://github.com/OpenBB-finance/OpenBB/pull/7528) | openbb-government-us: `openbb_government_us.congress`, provider name `congress_gov`, router `uscongress` and command paths preserved; data now from GovInfo bulk files |
| openbb-econdb | 1.5.1 | [#7675](https://github.com/OpenBB-finance/OpenBB/pull/7675) | none |
| openbb-finviz | 1.5.1 | [#7577](https://github.com/OpenBB-finance/OpenBB/pull/7577) | none |
| openbb-fmp | 1.6.1 | [#7665](https://github.com/OpenBB-finance/OpenBB/pull/7665) | none |
| openbb-intrinio | 1.6.1 | [#7575](https://github.com/OpenBB-finance/OpenBB/pull/7575) | none |
| openbb-multpl | 1.3.1 | [#7610](https://github.com/OpenBB-finance/OpenBB/pull/7610) | none |
| openbb-regulators | 1.6.2 | [#7525](https://github.com/OpenBB-finance/OpenBB/pull/7525) | openbb-sec router: the eight `obb.regulators.sec.*` commands are now `obb.sec.*` / `/api/v1/sec/*` |
| openbb-seeking-alpha | 1.6.1 | [#7570](https://github.com/OpenBB-finance/OpenBB/pull/7570) | none |
| openbb-stockgrid | 1.6.1 | [#7486](https://github.com/OpenBB-finance/OpenBB/pull/7486) | none |
| openbb-tiingo | 1.6.1 | [#7574](https://github.com/OpenBB-finance/OpenBB/pull/7574) | none |
| openbb-tradier | 1.5.1 | [#7573](https://github.com/OpenBB-finance/OpenBB/pull/7573) | none |
| openbb-tradingeconomics | 1.6.1 | [#7578](https://github.com/OpenBB-finance/OpenBB/pull/7578) | none |
| openbb-wsj | 1.6.1 | [#7485](https://github.com/OpenBB-finance/OpenBB/pull/7485) | none; the `etf.discovery` sub-router it served was deleted with it |
| openbb-yfinance | 1.6.3 | [#7576](https://github.com/OpenBB-finance/OpenBB/pull/7576) | none |
| `extensions/famafrench` (integration tests only, no pyproject) | n/a | direct commit `fbcd512905e`, after [#7503](https://github.com/OpenBB-finance/OpenBB/pull/7503) | `providers/famafrench/integration/` (rewritten; `test_famafrench_factor_choices` dropped) |
The early removal PRs (wsj, stockgrid, benzinga, alpha-vantage, biztoc) also pruned `assets/extensions/provider.json`, `dev_install.py`, README rows and router examples; the later ones touched only their provider directory, so v5 still carries provider.json entries for eleven removed packages, all
seventeen removed distributions in `openbb_platform/poetry.lock`, fmp/econdb/congress-gov in the desktop installer's `alwaysInclude` list, a yfinance smoke test in `build/pypi/openbb_platform/publish.py`, and 164 router `APIEx` examples plus 395 integration-test parameter sets naming removed
providers, plus `regulators` references in the mcp_server README and platform_api test fixtures, removed-provider samples in core docs (`core/README.md`, `config/loader.py`), the `examples/` tree, the mcp_server README, the `use_openbb_cli` skill, `mcp_server` help strings (`cli_tools.py`,
`pipeline.py`), the platform_api provider display-name map (`utils/widgets.py`) and `PythonEx`/docs examples in openbb-technical and openbb-charting.
Removed commands, models and modules inside kept packages:
- openbb-core: the `html5lib` dependency; `Linters.black()` (`Linters.run` accepts `Literal["ruff"]` only); `LoggingSettings.user_id`, `user_email`, `user_primary_usage` and the `%(userId)s` log-prefix field (no `hub_session` reference remains); `integration/test_obbject.py`; `poetry.lock`.
- openbb-core standard models (from [#7669](https://github.com/OpenBB-finance/OpenBB/pull/7669)): `BondIndicesData` lost `symbol` and `value`; `CommercialPaperData` lost `symbol`, `maturity`, `rate`, `title`; `MortgageIndicesData` lost `symbol`, `name`, `rate`; `SpotRateData` lost `rate`. Each now
carries only `date` plus one column per requested series.
- openbb-cli: `Settings.HUB_URL` and `Settings.BASE_URL` (and the `--dev` repointing); `exe --url` and the OpenBB Hub routine download path (`ROUTINE_DEFAULT_FILES`, `ROUTINE_PERSONAL_FILES`); `record --public/-p` and `SESSION_RECORDED_PUBLIC`; the module-level `PLATFORM_ROUTERS` dict; `pytz`; every
direct `openbb_charting` import; rich-table row/column truncation and the "Allowed number of rows/columns exceeded" notices; `MenuText._format_cmd_name` truncation; the top-level `system` REPL command; the `fastapi = "0.136.3"` pin; `poetry.lock`.
- openbb-platform-api: the bundled "Example BLS App" dashboard in `assets/default_apps.json` (removed by [#7518](https://github.com/OpenBB-finance/OpenBB/pull/7518)); the README tutorial sections (Markdown/Table/Metric Widget, Query Parameters, Easy Date Picker, Annotated Query Params, Annotated
Table Fields, Export apps.json, Installation, Usage, Launch Custom App); the pandas import in `OmniWidgetResponseModel.validate_model`.
- openbb-mcp-server: the admin tools `activate_tools`, `deactivate_tools`, `activate_category`; `ToolInfo.active`; `CategoryIndex.has_tool()`; settings `cache_expiration_seconds`, `on_duplicate_tools`, `on_duplicate_resources`, `on_duplicate_prompts`, `resource_prefix_format`, `dependencies`,
`deprecation_warnings` and their env aliases; `TokenAuthProvider.authorize()` and its `resource_server_url`/`authorization_url`/`token_url`; the default exclusion of `econometrics`, `quantitative`, `technical` from `module_exclusion_map`; `ProcessedRouteData.removed_routes` (renamed
`excluded_routes`); `key:value` dict parsing in the CLI parser; the `Env()` instantiation in `parse_args`; `tests/app/test_tool_execution.py`, `tests/utils/test_compress_schema.py`, `poetry.lock`.
- openbb-technical: `openbb_technical/technical_router.py` (all 27 commands moved to `indicators/`, `signals/`, `multi/`); `kc.mamode` values `wma`, `hma`, `zlma`; the `DMP_<n>`/`DMN_<n>` columns of `adx` (moved to the new `di` endpoint); `fib` fields `min_date`, `max_date`, `min_pr`, `max_pr`,
`lvl_text`; the forward-projected `span_*` rows of `ichimoku`; the string-formatted `r^2`/`fit_coef`/`factor` columns of `clenow`; `tests/test_technical_helpers.py`; `poetry.lock`.
- openbb-quantitative: `openbb_quantitative/quantitative_router.py`; the `performance/`, `rolling/`, `stats/` sub-router packages (now flat modules); `openbb_quantitative/models.py` (`TestModel`, `NormalityModel`, `ADFTestModel`, `KPSSTestModel`, `UnitRootModel`, `OmegaModel`, `SummaryModel`,
`CAPMModel`); `openbb_quantitative/statistics.py` (helpers moved to private `_stats_helpers.py`); the unused `pandas-ta-openbb` dependency; `unitroot_test(fuller_reg="nc")`; all `PythonEx` examples; `poetry.lock`.
- openbb-econometrics: `openbb_econometrics/econometrics_router.py`; the `OLSRegressionResults` pydantic model; the `pandas-ta-openbb` dependency; six of nine `PythonEx` examples (kept on `correlation_matrix`, `ols_regression`, `variance_inflation_factor`); `poetry.lock`.
- openbb-charting: `poetry.lock`; the 29-test live-network API and Python integration suites (replaced by five deterministic in-process cases); the Examples/Methods docstring sections on `Charting.to_chart`, `OpenBBFigure` and `PlotlyTA`; `Charting._extension_views` (replaced by lazy
`_get_extension_views()`).
- Pass-through routers: `obb.etf.discovery.gainers`, `obb.etf.discovery.losers`, `obb.etf.discovery.active` (models `ETFGainers`, `ETFLosers`, `ETFActive`, wsj-only) and the `openbb_etf.discovery` subpackage; the Python-side `test_equity_shorts_short_volume`; benzinga, stockgrid and alpha_vantage
examples and test cases; all `# pylint:`/`# flake8:`/`# noqa: PLR0912` directives; `poetry.lock` in all nine.
- openbb-news: `obb.news.world` no longer resolves (no v5 provider implements `WorldNews`, so core drops the route); `obb.news.company` keeps only the tmx and nasdaq providers, both gated on openbb-news being installed; the benzinga examples; the develop `test_news_world`/`test_news_company`
integration tests; `poetry.lock`.
- openbb-devtools: `pylint`, `mypy`, `black`, `poetry`, `pytest-freezegun`; the `ruff<0.16` ceiling; `poetry.lock`.
- openbb-bls: the 27 static `assets/*_series.xz`/`*_codes.json` files and `bls_assets.json`; helpers `get_survey_asset`, `download_category_series_ids`, `open_asset`, `update_static_asset`; the `EI` survey from the `cpi` category (now `ixp`); the `choices` list on `BlsSearchQueryParams.category`;
`poetry.lock`.
- openbb-cboe: the module-level `ConstituentsEu` Literal in `models/index_constituents.py`; unconditional `EtfHistorical` registration (now only when openbb-etf is installed); `poetry.lock`.
- openbb-cftc: the `COT`/`COTSearch` fetcher keys (renamed `CftcCot`/`CftcCotSearch`); the standard-model base classes of the COT models; `CftcCotSearchData.__alias_dict__` entries `units`/`commodity`; the `HYPERLIQUID` special case; the `/cftc/get_cot_choices` route (now `/cftc/cot_choices`); the
startup lifespan prefetch; `reports_dict` in `utils/__init__`; `openbb-platform-api` as a runtime dependency; `poetry.lock`.
- openbb-deribit: `DERIBIT_OPTIONS_SYMBOLS`, `OptionsSymbols`, `DERIBIT_FUTURES_CURVE_SYMBOLS`, `FuturesCurveSymbols`, `get_ticker_data`, `check_ohlc_symbol` and the `async_lru` import in `utils/helpers.py`; the `async-lru` dependency; the five VCR cassettes and `tests/test_deribit_fetchers.py`;
every `# pylint:` directive; `poetry.lock`.
- openbb-ecb: `utils/ecb_helpers.py` and `get_series_data`; all use of the `data-detail-api` endpoint; the aiohttp SQLite yield-curve cache; the `assets_issuer_sector_mfi`/`_government`/`_other` portfolio-investment series; `poetry.lock`.
- openbb-us-eia: `utils/total_energy_map.json`; the README "OpenBB Hub" credentials section and hand-written WPSR/STEO tables; the hand-maintained `WpsrCategoryChoices`/`WpsrTableChoices` lists (now derived from the Literal types); every `# pylint: disable` directive; `poetry.lock`.
- openbb-famafrench: the misspelled `famafranch` entry-point key; `poetry.lock`; the `factor_choices` integration tests.
- openbb-federal-reserve: fetcher keys `SvenssonYieldCurve` and `TotalFactorProductivity` (TFP re-homed at `sf/total_factor_productivity`; the `economy` and `fixedincome` routers still declare both models with no provider); `openbb_federal_reserve/router.py`; the `openbb-economy` and
`openbb-fixedincome` dependencies; the "Svensson Yield Curve" and "Total Factor Productivity" apps.json tabs; `poetry.lock`.
- openbb-finra: `utils/data_storage.py` (sqlite short-volume cache); helpers `get_finra_weeks`, `get_finra_data`, `get_full_data`, `aget_finra_weeks`, `aget_finra_data`, `aget_full_data`, `get_adjusted_date`, `get_short_interest_dates`; the VCR cassettes and `tests/test_finra_fetchers.py`;
`poetry.lock`.
- openbb-fred: the synchronous `Fred` client (`utils/fred_base.py`); `utils/ice_bofa_indices.csv` and `get_ice_bofa_series_id`; `get_cp_series_id`, `get_cpi_options`; the `YIELD_CURVE_*` constants except `YIELD_CURVES`; `FREDCommercialPaperData.asset_type`; `FredBondIndicesData.maturity`/`title`;
`FREDSpotRateData.__alias_dict__` and `value_validate`; the repo-level `providers/fred/py.typed`; `poetry.lock`.
- openbb-government-us: the `government_us` provider and entry point; the `GovernmentUs*`/`GovernmentUS*` fetcher classes and `openbb_government_us.models`; `CommodityPsdReport` params `commodity`/`year`/`month`; `use_cache` on committee documents; `bill_url`/`amendment_url` (now
`bill_id`/`amendment_id`); the Congress.gov-API-only sections of `committee_info` markdown; congress.gov URLs in `amendment_text`; six of the eight congress VCR cassettes; `poetry.lock`.
- openbb-imf: the `imf_utils` entry point and every `/imf_utils/*` route; the HTML/`raw` mode of `presentation_table`; the pickled `assets/imf_cache.pkl.gz`; the monolithic `utils/metadata.py`; the hard `openbb-platform-api` and `openbb-economy` dependencies; `integration/test_imf_utils_*.py`;
`poetry.lock`.
- openbb-nasdaq: the `TopRetail` fetcher (the standard model now has no provider); `openbb_nasdaq/app.py` and its routes; `utils/query_params.py` (`DataLinkQueryParams`); the `api_key` credential and Quandl instructions; the `nasdaq-data-link` and `openbb-platform-api` dependencies; all VCR
cassettes, `tests/record/expected_*.json`, `tests/test_nasdaq_app.py`, `tests/test_nasdaq_fetchers.py`; the `NasdaqCalendarIpoData` alias dict and validators; `poetry.lock`.
- openbb-oecd: `CustomHttpAdapter`, `get_legacy_session`, `fetch_data`, `oecd_xml_to_df`, `parse_url`, `check_cache_exists_and_valid`, `write_to_cache`, `query_dict_to_path`, `get_possibly_cached_data`; every `COUNTRY_TO_CODE_*`/`CODE_TO_COUNTRY_*` map; the `defusedxml` dependency; the `Countries`
Literal on the CLI query; `poetry.lock`.
- openbb-sec: the `aiohttp-client-cache`/`aiosqlite` dependencies and every `CachedSession` block; the Form 4 SQLite cache and its helpers; `FISCAL_PERIODS`/`FISCAL_PERIODS_DICT`; the `hmrc-dpl` taxonomy choice; `SecRssLitigationData.published`/`summary`/`link`; the "No valid forms provided"
validation; `poetry.lock`.
- openbb-tmx: `get_data_from_gql`, `get_random_agent`, `get_companies_backend`, `get_indices_backend`, `response_callback`; the lowercase `*_query`/`*_payload` dicts in `utils/gql.py` (including `getIndexBySymbol` and `getIndexPriceHistory`); the `backend` argument of `get_data_from_url`; all 23 VCR
cassettes and `tests/test_tmx_fetchers.py`; `poetry.lock`.
- Repository: `.pylintrc`; the black, ruff-pre-commit, pydocstyle, mirrors-mypy, pylint and codespell-project pre-commit hooks; `general-linting.yml` (renamed and rewritten as `lint-openbb-platform.yml`); `test-unit-platform.yml`; the srvaroa labeler step and `.github/labeler.yml`;
`publish-`/`test-unit-openbb-congress-gov.yml`; cookiecutter `poetry.lock`, `MANIFEST.in`, `cookiecutter.json` and the template's `.coveragerc`, `.secrets.baseline`, `pytest.ini`, `ruff.toml`, `routers/depends.py`, `models/ohlc_example.py`.
</details>
<details>
<summary><h2>Breaking changes</h2></summary>
Grouped by package. Packaging, license and dependency-floor changes are listed once per package; the per-package sections below carry the full detail.
**openbb-core**
- Poetry to hatchling/PEP 621 (1.6.13 -> 2.0.0); `pandas` moved to the `openbb-core[pandas]` extra, so `OBBject.to_dataframe/to_polars/to_numpy`, `basemodel_to_df`, `Metadata`, `Fetcher.test` and pandas-backed validators raise `OpenBBError` with an install hint when pandas is absent.
- Dependency floors: uvicorn `>=0.48.0`, fastapi `>=0.137.2` (exact pin dropped; raised from the initial `>=0.136.3` by `f0258c93366` — core's `route_iter.py` uses the private `_IncludedRouter`/`.effective_route_contexts()` API from FastAPI's 0.137.0 router-inclusion refactor), requests `>=2.34.2`, pyjwt `>=2.13.0`, pydantic `>=2.12.3,<3.0.0`, aiohttp `>=3.14.2` (raised from `>=3.13.3` by the same commit), python-multipart `>=0.0.29`, ruff `>=0.15`, plus `tomli>=2.0.0` on Python <3.11; `html5lib` dropped.
- License AGPL-3.0-only -> Apache-2.0 and `APISettings.license_name` default `"AGPLv3"` -> `"Apache-2.0"` (visible in the served OpenAPI info block).
- `OBBject.to_llm()` is annotated `-> str` and returns `"[]"` for empty JSON; `OBBject.to_polars()` raises `OpenBBError` instead of `ImportError` when polars is missing.
- `openbb_core/api/router/commands.py` no longer imports `Charting` from `openbb_charting`; `Charting = ChartingManager.get_charting_class()`; the missing-charting error text is now "No charting extension is installed. Install `openbb-charting` or set `system_settings.charting_extension` to your
engine."
- `Linters.run()` accepts only `linter: Literal["ruff"]`; generated-package linting runs `ruff check --fix-only --unsafe-fixes`.
- `LoggingSettings` lost `user_id`, `user_email`, `user_primary_usage`; the log prefix format lost `%(userId)s`.
- `SingletonMeta` is no longer `Generic[T]`; `Credentials.show()` now unmasks raw `SecretStr` values and prints only declared fields.
- Standard models `BondIndicesData`, `CommercialPaperData`, `MortgageIndicesData`, `SpotRateData` are `date`-only wide layouts (fields listed under Removals); seven standard-model fields became Optional (`CompositeLeadingIndicatorData.value`, `CountryInterestRatesData.date`/`.value`,
`FuturesCurveData.price`, `GdpNominalData.country`, `GdpRealData.country`, `RetailPricesData.description`, `TipsYieldsData.value`).
- FastAPI 0.137+ route iteration: `CommandMap`, coverage maps and `add_command_map` iterate through `iter_api_routes`; exception handlers are registered with `app.add_exception_handler`; `FastAPI(strict_content_type=False)`; `AppLoader.add_openapi_tags` and `rest_api` now override `app.openapi`.
- The committed `openbb/assets/reference.json` changed from a 14-line stub to a 10,207-line snapshot of a developer's local build that references `yfinance` and `equity@1.6.1` — reverted back to the clean 14-line stub by `d377ba941e3` ([#7681](https://github.com/OpenBB-finance/OpenBB/pull/7681)).
**openbb-cli**
- Poetry to hatchling/PEP 621 (1.4.2 -> 2.0.0); runtime dependency `openbb[all]` replaced by `openbb-core[pandas]>=2.0.0`, so `pip install openbb-cli` installs no router extensions or providers; `httpx`, `pyyaml`, `tomli` (py<3.11) added; `pywry` moved to the `interactive` extra; new `charting` and
`all` extras.
- Default mode is non-TTY one-shot: `openbb <command.path> --key value` dispatches once and prints a JSON line; the REPL needs `-i/--interactive`; `main(argv=None) -> int`; the legacy `parse_args_and_run` flags (`-t`, `-m`, `-f`, `--HistoryManager.hist_file`) are unreachable from the `openbb` entry
point.
- `Settings.USE_INTERACTIVE_DF` defaults to False; new `Settings.OUTPUT_MODE` (`rich|json|tsv|html`, default `tsv`, REPL command `output`); `-i` flips both to interactive defaults.
- `Session` is lazy (`_obb`, `prompt_session`, `backend` properties; `_get_prompt_session` -> `_build_prompt_session`; new `output_adapter`, `is_interactive`); the backend class is resolved through `openbb_core.app.charting.get_charting_backend_class()` then
`ChartingManager.get_charting_class().get_backend_class()`.
- `CLIController.__init__` gained keyword-only `backend`; `CHOICES_COMMANDS`/`CHOICES_MENUS` are per-instance (class lists are `CHOICES_COMMANDS_BUILTIN`/`CHOICES_MENUS_BUILTIN = ["settings", "user", "feature"]`); `run_cli`, `main`, `launch` accept `backend=`.
- `PlatformControllerFactory.__init__(platform_router=None, *, backend=None, router_name=None, reference=None)` raises without `backend` or `platform_router`; `router_name`/`controller_name` are read-only properties; `PlatformController.__init__` gained `paths` and a changed `ValueError` message.
- `ArgparseClassProcessor._build_paths` lost `depth` and no longer recurses (`"subpath"` only); `Registry.all` returns `obbject.model_dump(exclude={"results"})` so `command`/`register_key` live under `extra`; `Registry.register` accepts any OBBject whose `results is not None`.
- `BaseController.check_path` accepts digits, `_` and `-`; `parse_input` prepends `home` for inputs starting with `/` and protects `-f/--file` paths; `results` gained `-i`/`-k` aliases and `db`/`sqlite`/`sqlite3` export choices and renders through `output_adapter`.
- OBBject results in `PlatformController` render through `session.output_adapter.display(...)` and `extract_dataframe(obbject)`; `SettingsController` enumerates `session.settings.__class__.model_fields`.
- `LocalBackend.routers` skips `user`, `system`, `account` and names starting with `_` (develop excluded any `obb` attribute containing `_`), so routers with underscores now appear; the `system` command is gone and `user` is a `/user/` menu.
- The test workflow installs with `uv pip install --system -e ".[charting]" --group dev` on a 9-cell matrix; README moved to "ODP Command-Line Interface" and the docs link to `docs.openbb.co/odp/cli`.
**openbb-platform-api**
- Poetry to hatchling/PEP 621 (1.3.6 -> 2.0.0); `openbb-core>=2.0.0`; `tomli>=2.0` on py<3.11; license Apache-2.0. The release cleanup removed `poetry.lock`; `uv.lock` remains.
- `main.py` is a thin bootstrap (`--help`/`-h` short-circuit, TOML bootstrap, `globals().update` re-export of `app.app`); `utils/api.py`, `query_models.py`, `response_models.py`, `utils/merge_agents.py`, `utils/merge_apps.py` are lazy or re-export shims over `app/`, `models/`, `service/` and
`utils/network.py`; `check_for_platform_extensions` moved to `app/bootstrap.py`.
- Route discovery uses `iter_api_routes(app)` and `getattr(route, "original_route", route).endpoint` instead of `isinstance(route, APIRoute)`; `import_app` installs the six exception handlers inline and applies CORS through `apply_cors_from_system_service`; the default `rest_api.app` is imported
only when no `--app`/`--spec` app is supplied.
- widgets.json generation: `format: "date"` fields emit `cellDataType: "dateString"` (`date-time` keeps `"date"`); a `date` column gets `"sort": "desc"`; `fiscal_year`, `year`, `year_born`, `calendar_year` emit `cellDataType: "text"` with `formatterFn: "none"`; routes with a 2xx `event-stream`
response are skipped; SSRM routes are auto-promoted to `ssrm_table`.
- `--spec` and `--app` are mutually exclusive (`ValueError` at startup).
- The bootstrap pushes TOML `[system]`/`[user]` onto `SystemService`/`UserService` and applies `.env` and `OPENBB_*` promotion before the launcher imports.
**openbb-mcp-server**
- Poetry to hatchling/PEP 621 (1.4.1 -> 2.0.0); `openbb-core>=2.0.0`, `fastapi>=0.138.2`, `fastmcp>=4.0.9` (was `>=3.2.0`), `tomli>=2.0` on py<3.11; license Apache-2.0.
- Console script `openbb-mcp` targets `openbb_mcp_server.main:main`; `parse_args()` moved to `app/args.py` and returns `{app, transport, mcp_overrides, uvicorn_overrides}` instead of an `Args` object; `import_app` moved to `app/bootstrap.py`; `cl_doc` renamed `LAUNCH_SCRIPT_DESCRIPTION` (lazy
aliases kept in `utils/app_import.py`).
- Tool discovery is stateless: route tools stay enabled but hidden behind `OpenBBToolCatalog` (`search_tools`/`call_tool`); `default_tool_categories` is ignored in that mode; `mcp_config.enable: false` no longer disables a tool when discovery is on; `available_tools` is synchronous and returns name
plus description only.
- `allowed_tool_categories` is now enforced (routes outside it are never registered); `module_exclusion_map={}` hides nothing; `exclude_args` is applied to tool input schemas.
- `create_mcp_server(auth=...)` accepts `AuthProvider | tuple[str, str] | list[str] | None` and raises `TypeError` otherwise; `TokenAuthProvider` subclasses fastmcp `TokenVerifier` and takes a `(username, password)` tuple; `get_auth_provider(auth)` no longer takes settings.
- The three `on_duplicate_*` settings collapsed into `on_duplicate` (`OPENBB_MCP_ON_DUPLICATE`); `--version` sets `MCPSettings.version` instead of reaching uvicorn; `write_to_file` omits a default `default_skills_dir`.
- Non-GET tools on multi-method paths get a `_<method>` suffix; `output_schema` is `None` for routes without a JSON 2xx response; `StaticPrompt.render` returns `fastmcp.prompts.base.Message` objects; `execute_prompt(prompt_name=...)` became `get_prompt(name=...)`.
- `process_fastapi_routes_for_mcp` no longer rewrites `app.router.routes`; exclusions are `MCPType.EXCLUDE` RouteMaps and routes are walked with `fastapi.routing.iter_route_contexts`.
**openbb-technical**
- Poetry to hatchling/PEP 621 (1.6.2 -> 2.0.0); `openbb-core[pandas]>=2.0.0`; new required `scipy>=1.11`, `statsmodels>=0.14`; entry point `openbb_technical.router:router`; license Apache-2.0; hard dependency on `openbb_core.app.route_iter.iter_api_routes`.
- Every command takes a single `params: XxxQueryParams` body (all HTTP params move from the query string into the JSON body) and returns typed `XxxData` rows containing only `date` plus renamed indicator columns; warm-up rows are dropped (`.dropna()`) for the pandas-ta backed indicators (exceptions:
`demark`, `ichimoku`, `realized_volatility` with `clean=False`, `supertrend`, `pivot_points`, `clenow`).
- Defaults: `bbands.length` 50 -> 20, `adx.length` 50 -> 14, `kc.scalar` 20 -> 2.0; `bbands.std` `NonNegativeFloat` -> `PositiveFloat`; `atr.drift`, `stoch` periods, `adx.drift`, `rsi/macd/aroon/sma/ema/wma/hma/zlma` lengths -> `PositiveInt`; `rsi/adx/aroon.scalar` -> `PositiveFloat`;
`cones.trading_periods` -> `PositiveInt | None`.
- Column renames: `bbands` -> `lower, middle, upper, bandwidth, percent`; `kc`/`donchian` -> `lower, middle, upper`; `macd` -> `macd, signal, histogram`; `aroon` -> `aroon_up, aroon_down, aroon_oscillator`; `ichimoku` -> `tenkan_sen, kijun_sen, senkou_a, senkou_b, chikou_span`; `fisher` ->
`fisher, signal`; `stoch` -> `k, d`; `cones` -> `lower`/`upper`; `fib` -> `level`/`price`; `demark` rows are `date, up, down`; `clenow` returns per-bar float rows.
- Signal endpoints live under `/technical/signals/*` (`obb.technical.signals.*`); `relative_rotation` takes a single `params` model and is categorised `multi`.
**openbb-quantitative**
- Poetry to hatchling/PEP 621 (1.6.2 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, explicit `numpy>=1.24`, `scipy>=1.11`, `statsmodels>=0.14`; entry point `openbb_quantitative.router:router`; license Apache-2.0.
- Every command takes a single `params: XxxQueryParams`; `normality` and `unitroot_test` responses are flattened (`kurtosis_statistic`, `adf_statistic`, `kpss_p_value_interpolated` and the other fields listed in the openbb-quantitative section); `summary` percentiles renamed `p25/p50/p75`; rolling
columns lose the window suffix (`skew`, `variance`, `stdev`, `kurtosis`, `mean`, `median`/`quantile`); `stats.*` return a single typed record; `sharpe_{window}` -> `sharpe_ratio`; the sortino column (formerly named after the target) -> `sortino_ratio`; `date` is emitted as a literal key.
- `rolling.quantile` raises `KeyError('date')` for a non-`date` `index`; `quantile_pct` is constrained `ge=0.0, le=1.0`; `capm` resamples to month-start closes and regresses on `mkt_rf` directly (no double risk-free subtraction); `get_fama_raw` columns are `mkt_rf, smb, hml, rf` on index `date`;
`validate_window` message changed; `CAPMModel` -> `CapmData` and all non-list responses subclass `Data`; `OmegaModel` -> `OmegaRatioData` with a `bins` parameter.
**openbb-econometrics**
- Poetry to hatchling/PEP 621 (1.7.2 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, direct `statsmodels>=0.14`, `scipy>=1.11`, open floors `arch>=7.2`, `linearmodels>=6`; entry point `openbb_econometrics.router:router`; license Apache-2.0.
- Every command takes a single `params: <X>QueryParams` and returns typed `Data`: `ols_regression` returns coefficient rows; `ols_regression_summary` returns `OlsRegressionSummaryData`; `autocorrelation.score` -> `durbin_watson`; `residual_autocorrelation` keys ->
`lm_statistic/lm_p_value/f_statistic/f_p_value`; `cointegration` -> `pair/c/gamma/alpha/adf_stat/p_value` rows; `causality` -> `test/statistic/p_value/lag` rows; `unit_root` keys -> `adf_stat/p_value/used_lag/nobs/ic_best` plus `critical_values`; all `panel_*` return `PanelRegressionData`
coefficient rows; `variance_inflation_factor` is long-format; `correlation_matrix.comp_to` is `str`.
- `panel_fixed` now fits without a constant and with `entity_effects=True` by default; integration tests no longer fetch from fmp/yfinance.
**openbb-charting**
- Version stays 3.0.0 on both branches, so the publish workflow will refuse a release if 3.0.0 is already on PyPI until `[project].version` is bumped.
- Poetry to hatchling/PEP 621; `openbb-core[pandas]>=2.0.0`; `plotly>=6.3.1` without an upper bound (Plotly 7 handled); `pandas-ta-openbb>=0.4.24`; `pywry` extra floor lowered to `>=2.0.0`; license Apache-2.0; entry point moved to `[project.entry-points."openbb_obbject_extension"]`.
- `Charting._extension_views` (eager class attribute) replaced by lazy `_get_extension_views()` with `_extension_views_cache`; `create_line_chart`/`create_bar_chart` always return the figure; `Charting.__init__` builds the backend from `get_backend_class()` (entry-point override or built-in
`Backend`).
- Platform interfaces (core `commands.py`, package builder, command runner, the CLI) resolve the engine through `ChartingManager` instead of importing `openbb_charting` by name; the missing-charting error text changed.
- openbb-technical no longer imports `openbb_charting` at import time; openbb-cli no longer pulls openbb-charting transitively.
**Pass-through router extensions**
- Nine packages (commodity 1.5.2, crypto/currency/derivatives/economy/equity/etf/fixedincome/index 1.6.2) moved to 2.0.0 on hatchling/PEP 621 with `openbb-core>=2.0.0`, entry points under `[project.entry-points.*]` and license Apache-2.0.
- `EtfViews` return annotations became `tuple[Any, dict[str, Any]]`; the session-scoped `obb` fixture now `pytest.skip`s when integration tests are disabled; the eight `obb.regulators.sec.*` commands are `obb.sec.*` (a stale `obb.regulators.sec.institutions_search` example survives in
`ownership_router.py`).
**openbb-news**
- Poetry to hatchling/PEP 621 (1.6.2 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, new `feedparser>=6.0`, `lxml>=5.0`; entry point `openbb_news.router:router`; description "RSS news feeds extension for OpenBB"; license Apache-2.0.
- `news.world` has no provider on v5 and `news.company` is served only by tmx and nasdaq; the metapackage still pins `openbb-news = "^1.6.2"`.
**openbb-devtools**
- Poetry to hatchling/PEP 621 (1.6.8 -> 2.0.1); `pylint`, `mypy`, `black`, `poetry`, `pytest-freezegun` dropped; `ty>=0.0.40`, `httpx2>=2.0.0`, `types-requests`, `pytest-freezer>=0.4.9` added; `pytest-recorder>=1.0.0` (whose deps are now ruff/ty/vcrpy 8.3.0); `ruff>=0.15` unbounded; license
Apache-2.0.
- Consumers that no longer path-source devtools (cli, platform-api, mcp-server, the 13 router/toolkit extensions) resolve `openbb-devtools>=2.0.1` from an index that nothing in the repo publishes.
**openbb-bls**
- Poetry to hatchling/PEP 621 (1.3.1 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, new `requests`, `beautifulsoup4`, `lxml`, `openpyxl`; license Apache-2.0; building needs network access to download.bls.gov (or an existing `bls_cache.zip`); the metapackage still pins `openbb-bls = "^1.3.1"`, which does not admit 2.0.0.
- `BlsSeries` default window is the earliest `begin_year` of the requested symbols (fallback 20 years) instead of 3 years; chunking is 50 symbols/20 years with a key and 25/10 without; new `category` param; `BlsSeriesData` gained chart widget config and `formatterFn: percent` on percent-change
columns.
- `BlsSearch` gained a no-op `symbol` param, recency ordering, synthesized titles and the `ixp` category (EI series left `cpi`); several category display names changed.
- `/bls/search`, `/bls/series`, `/bls/calendar` register only when openbb-economy is absent; the calendar fetcher key switches between `EconomicCalendar` and `BlsEconomicCalendar`; searching without the shipped `bls_cache.zip` raises `KeyError`.
- `BlsSeries` still lacks `require_credentials = False`, so `obb.bls.series` raises "Missing credential 'api_key'" through the command path although the README says no key is required.
**openbb-cboe**
- Poetry to hatchling/PEP 621 (1.6.1 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, `aiohttp-client-cache>=0.11`, `aiosqlite>=0.20`; license Apache-2.0; new `openbb_core_extension` router at `/cboe`; the metapackage pins `openbb-cboe ^1.6.0` (develop `^1.6.1`), which cannot resolve 2.0.0.
- Fetcher keys are conditional on openbb-equity/etf/index/derivatives (`Cboe*` aliases otherwise); `EtfHistorical` only with openbb-etf.
- `IndexConstituents.symbol` is `CONSTITUENTS_EU | CONSTITUENTS_AU` with a new `session` param and many new fields; `IndexSnapshots.region` adds `au`, symbols lose the `^` prefix and gain `name`; percent columns and OHLC values are no longer rounded; `EquityQuote` drops `multiple_items_allowed`
(fetcher still splits on commas).
- Daily index history comes from per-symbol `_History.csv` files (no `volume`); multi-date `FuturesCurve` returns a wide shape and `expiration` became `str | None`; options `dte` is anchored to 16:00 ET; default dates use the New York session; caching is a shared per-loop backend with per-URL TTLs;
model imports instantiate `SystemService()` at import time.
**openbb-cftc**
- Poetry to hatchling/PEP 621 (1.4.2 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, new `xlrd`, `openpyxl`, `diskcache`, `pyarrow`; `openbb-platform-api` dropped; license Apache-2.0.
- `COT` -> `CftcCot`, `COTSearch` -> `CftcCotSearch` fetcher keys and router models; the COT models no longer subclass the core standard models; `query` default `""` -> `None`; `/cftc/get_cot_choices` -> `/cftc/cot_choices`; `apps.json` moved under `assets/`; the startup lifespan prefetch is gone;
`reports_dict` moved to `utils/constants`; COT responses are disk-cached for one hour.
**openbb-deribit**
- Poetry to hatchling/PEP 621 (1.2.1 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, `aiohttp-client-cache>=0.11`, `aiosqlite>=0.20`; `async-lru` dropped; license Apache-2.0; new `openbb_core_extension` router at `/deribit`.
- The five standard keys (`FuturesCurve`, `FuturesHistorical`, `FuturesInfo`, `FuturesInstruments`, `OptionsChains`) register only with openbb-derivatives installed (`Deribit*` aliases and `/deribit/futures/*`, `/deribit/options/chains` otherwise).
- `FuturesCurve.symbol` is a plain `str` (no `validate_symbol`), `hours_ago` is `str | None`, the curve is priced off `mark_price` and excludes the perpetual; `FuturesHistorical` lost its query-time symbol validator and `volume_notional` is Optional; `FuturesInfo` fields
`best_bid_price/best_ask_price/best_bid_amount/best_ask_amount` -> `bid/ask/bid_size/ask_size` and `change_percent` is no longer divided by 100.
- Options chains: any listed root is accepted; `mark_iv`, `bid_iv`, `ask_iv`, `price_change` are no longer divided by 100 and `interest_rate` is multiplied by 100; `contract_size` comes from the instrument spec; several list fields lost their `default_factory`; websocket timeout 2 s -> 15 s.
- Helper API: `get_instruments(currency="any", kind=None, expired=False)`; constants moved to `utils/constants` (`Currencies` no longer includes `"all"`); `BASE_URL` moved to `utils/client` and includes `/api/v2`.
**openbb-ecb**
- Poetry to hatchling/PEP 621 (1.6.1 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, new `requests`, `defusedxml`, `diskcache`, `beautifulsoup4`, `markdownify`; license Apache-2.0; a hatch build hook fetches the SDMX catalogue when `ecb_cache.json.xz` is absent; new `openbb_core_extension` router at
`/ecb`; the metapackage pins `openbb-ecb ^1.6.0`, which cannot resolve 2.0.0.
- `BalanceOfPayments`, `CurrencyReferenceRates`, `YieldCurve` keys register only with openbb-economy/currency/fixedincome installed (`Ecb*` aliases otherwise).
- The yield curve is fetched as one OR-joined SDMX key within a 14-day window per date (single-date misses raise `EmptyDataError` instead of resolving to the nearest earlier date); `BalanceOfPayments` gained `start_date`/`end_date`/`use_cache`, `aextract_data` returns flat observation records,
series ids lost the `BPS.` prefix and several keys were renamed to the standard field names; `CurrencyReferenceRates.extract_data` returns a `{"time", "rates"}` dict; importing the package loads the catalogue.
**openbb-us-eia**
- Poetry to hatchling/PEP 621 (1.3.1 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, new `curl-cffi`, `fastmcp>=2.0`, `feedparser`; license Apache-2.0; cold builds need an EIA key and network access; new `openbb_core_extension` router `eia` (`obb.eia`).
- `petroleum_status_report` and `short_term_energy_outlook` register under `obb.eia` only when openbb-commodity is absent; STEO periods are parsed with explicit formats; `response_callback` raises `OpenBBError` on any `error` envelope.
**openbb-famafrench**
- Poetry to hatchling/PEP 621 (1.2.1 -> 2.0.0); `openbb-core[pandas]>=2.0.0`; the provider entry-point key `famafranch` corrected to `famafrench`; license Apache-2.0; integration tests moved into the provider and self-host uvicorn.
**openbb-federal-reserve**
- Poetry to hatchling/PEP 621 (1.6.2 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, `openbb-platform-api>=2.0.0`, new `diskcache`, `defusedxml`, `curl-cffi`, `pdfplumber`; `openbb-economy`/`openbb-fixedincome` dropped; license Apache-2.0.
- Core-extension entry point moved to `openbb_federal_reserve.federal_reserve_router:router` (an OpenBB `Router`), creating the `obb.federal_reserve` namespace; the 11 surviving standard keys are conditional on openbb-economy/fixedincome (`FederalReserve*` aliases and fallback commands otherwise).
- `MoneyMeasures` values are dollars (x1e9); `PrimaryDealerFails` and `PrimaryDealerPositioning` drop the standard bases and return wide per-date records; `CentralBankHoldings` lost its x1000 frontend-multiply metadata; caching moved to `diskcache` (`OPENBB_FEDERAL_RESERVE_CACHE_DIR`); FOMC document
lists refresh at the next FOMC date.
**openbb-finra**
- Poetry to hatchling/PEP 621 (1.6.1 -> 2.0.0); `openbb-core[pandas]>=2.0.0`; license Apache-2.0; new `openbb_core_extension` router at `/finra`; fetcher keys conditional on openbb-equity/fixedincome (`Finra*` aliases otherwise).
- Short interest reads `otcMarket/consolidatedShortInterest` (sqlite CSV cache gone), decodes `market_class`, sorts by `(symbol, settlement_date)` and raises `EmptyDataError` when empty; OTC without a symbol returns only the latest week and with a symbol returns full history (no 52-week cap);
`BondPrices` rejects `country`, `isin`, `lei`, `currency`, `issued_amount_min/max` and unfiltered MBS/CMO searches; empty results surface as HTTP 204.
**openbb-fred**
- Poetry to hatchling/PEP 621 (1.6.2 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, `diskcache>=5.6`; license Apache-2.0; new `openbb_core_extension` router `fred`; 32 standard keys switch to `Fred*` aliases when the owning extension is absent.
- Percent values are no longer divided by 100 across roughly twenty models (Ameribor, BalanceOfPayments, BondIndices, CommercialPaper, ConsumerPriceIndex, EuroShortTermRate, FederalFundsRate, HighQualityMarketCorporateBond, ManufacturingOutlookNY/Texas, MortgageIndices, NonFarmPayrolls,
OvernightBankFundingRate, RetailPrices, SeniorLoanOfficerSurvey, SOFR, SurveyOfEconomicConditionsChicago, TipsYields, UniversityOfMichigan, YieldCurve).
- `CommercialPaper`, `BondIndices`, `MortgageIndices` are wide (one column per series); `SpotRate` rows are `{date, maturity, rate}`; nine fetchers switched from `extract_data` to `aextract_data`; Chicago survey columns renamed to the standard names; `fred_get_many` re-raises the first failure;
`FederalFundsRate` default `start_date` logic changed; `use_cache` added to every model.
**openbb-government-us**
- Poetry to hatchling/PEP 621 (1.6.1 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, new `curl-cffi`, `defusedxml`, `diskcache`, `httpx`, `openpyxl`, `xlrd`; license Apache-2.0.
- The single `government_us` provider is replaced by `congress_gov`, `us_treasury` and `usda` with routers `uscongress`, `ustreasury`, `usda`; `provider="government_us"` no longer exists (the commodity and fixedincome routers still carry stale `government_us` examples); fetcher classes renamed
`Us*`/`Usda*`; `openbb_congress_gov.*` -> `openbb_government_us.congress.*`.
- Congress identifiers are `bill_id`/`amendment_id` (`119-hr-29`, `119-hamdt-2`) instead of URLs; data comes from GovInfo bulk files, the API key is optional (fallback for Congresses before 108); `CommodityPsdData` is pivoted wide with marketing-year columns; `CommodityPsdReport` is a POST `urls`
download; `TreasuryPrices` gained a required `date`; the `uscongress` router warms an on-disk SQLite cache at API startup.
**openbb-imf**
- Poetry to hatchling/PEP 621; version 2.1.3 -> 2.1.2 (lower); `openbb-core[pandas]>=2.0.0`, `requests>=2.31`; `charting` extra `openbb-charting>=3.0.0`; `openbb-platform-api` and `openbb-economy` dropped; license Apache-2.0.
- Core-extension entry point `imf_utils` -> `imf`: every `/api/v1/imf_utils/*` route and `obb.imf_utils.*` command is now `/api/v1/imf/*` / `obb.imf.*`; `list_port_id_choices` moved to `/imf/portwatch/`; `presentation_table` returns AG-Grid rows only (no HTML/`raw`), `country` is single-select and
the category is "IMF Data".
- Fetcher keys switch to `Imf*` aliases without openbb-economy; the metadata cache is xz JSON (`imf_cache.json.xz`, gitignored, generated at build); `utils/metadata.py` became a mixin package; router commands take a `Depends`-injected `ImfMetadataDependency`;
`ImfAvailableIndicatorsFetcher.extract_data` is async; unknown `dimension_values` raise `ValueError`; CPI `symbol` is the raw `series_id` and `country` defaults to `"USA"`; importing `openbb_imf` loads the catalogue.
**openbb-nasdaq**
- Poetry to hatchling/PEP 621 (1.6.3 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, new `aiohttp-client-cache`, `aiosqlite`, `python-dateutil`, `data-link` extra `pdfplumber`; `nasdaq-data-link` and `openbb-platform-api` dropped; no credentials; license Apache-2.0; new `openbb_core_extension` router
`nasdaq`.
- Fetcher keys are conditional on the owning extension (`Nasdaq*` aliases otherwise); `TopRetail` is gone (the `obb.equity.discovery.top_retail` command has no provider); `website`/`repr_name` changed.
- `HistoricalDividends.symbol` drops `multiple_items_allowed` and resolves the asset class via the listing directory; `EquityScreener.market_cap` and `CalendarEarnings.market_cap` are `float | None`; the screener uses the `download=true` endpoint; IPO calendar sorts per status and raises a
differently worded `EmptyDataError`; the symbol directory is fetched over HTTPS; `get_headers()` drops the `Host` header; JSON requests go through a SQLite HTTP cache.
**openbb-oecd**
- Poetry to hatchling/PEP 621 (1.6.1 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, `requests>=2.31`; `defusedxml` dropped; license Apache-2.0; core-extension entry point `oecd` (renamed from `oecd_utils` in [#7509](https://github.com/OpenBB-finance/OpenBB/pull/7509)); fetcher keys switch to `Oecd*`
aliases without openbb-economy.
- Country slugs were regenerated from SDMX constraints (`czech_republic` -> `czechia`, `turkey` -> `turkiye`, `south_korea` -> `korea`, `oecd_total` -> `oecd`, `slovakia` -> `slovak_republic`, and others); result `country` values are OECD labels; validators normalize instead of rejecting; four
fetchers switched from `aextract_data` to sync `extract_data`.
- House price index `yoy`/`period` values are divided by 100 and the monthly-to-quarterly fallback triggers on any exception; CPI lost its CSV cache, uses `TRANSFORMATION` codes, accepts multiple `expenditure` values and gained required fields; every migrated fetcher wraps failures in `OpenBBError`
so `EmptyDataError` no longer surfaces; `oecd_date_to_python_date` returns `None` instead of raising.
**openbb-sec**
- Poetry to hatchling/PEP 621 (1.6.7 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, `openbb-platform-api>=1.3.6`, `fastmcp>=3.2.0`, `diskcache>=5.6.3`; license Apache-2.0; new `openbb_core_extension` router `sec`.
- All commands moved from `obb.regulators.sec.*` / `/api/v1/regulators/sec/*` to `obb.sec.*` / `/api/v1/sec/*`; standard equity/ETF fetcher keys become `Sec*` aliases (and `obb.sec.*` commands) when openbb-equity/openbb-etf are absent.
- `compare_company_facts.fiscal_period` -> `calendar_period` (with derived standalone Q4 and `calendar_year`/`calendar_period` output fields); `SecRssLitigationData` fields `published/summary/link` -> `date/excerpt/url` plus `body`, `author` and a `limit` param; `SecBaseFiling` -> `Filing` (alias
kept); `hmrc-dpl` -> `frc-core`/`frc-dpl`; `url` params are `str | None` with strict sec.gov host validation; `use_cache` narrowed to `bool` on four query models; caching moved to one `diskcache` store under `<cache>/sec` with a 9 req/s rate limiter.
**openbb-tmx**
- Poetry to hatchling/PEP 621 (1.5.2 -> 2.0.0); `openbb-core[pandas]>=2.0.0`, new `curl-cffi`, `diskcache`, `lxml`, `pyarrow`, `tzdata`, `python-dateutil`, `pdfplumber`; extras `charting`, `builder`, `all`; license Apache-2.0; new `openbb_core_extension` router `tmx`; every standard fetcher key is
conditional on the owning extension (`Tmx*` aliases otherwise).
- `EquitySearch` reads the QuoteMedia symbology with new `country`/`symbol_only`/`limit` params (default 200 Canadian listings) and raises `EmptyDataError` on no match; `IndexConstituents` uses GraphQL, `market_value` alias `quotedmarketvalue` -> `quotedMarketValue`, `aextract_data` returns a list;
`EquityHistorical.high/low` are Optional; `CalendarEarnings` raises `EmptyDataError` on empty windows; `EtfSearch.div_freq` widened; options chains come from QuoteMedia with greeks; `helpers.get_data_from_url` lost `backend`; `utils/gql.py` was rewritten with uppercase constants;
`normalize_symbol` no longer strips `.TSXV` for `PriceTargetConsensus`.
**Repository and tooling**
- Root `LICENSE` and every package are Apache-2.0; `.pylintrc` deleted; `ruff.toml` line-length 122 -> 88 (rule `Q` dropped, `E501`/`D206`/`D300` ignored, `[format]` section added); `ty.toml` added; the pre-commit `ty` hook points at the untracked `.github/scripts/ty_per_package.sh`.
- `dev_install.py` is a uv-based installer with a single `--routers` flag (`-e/--extras` and `-c/--cli` are gone); `noxfile.py` installs uv and calls `dev_install.py --routers`; `test-unit-cli.yml` and the platform lint workflow were rewritten; `general-linting.yml` and `test-unit-platform.yml` are
gone.
- openbb-cookiecutter 0.6.0 -> 1.0.0 on hatchling; the template generates hatchling projects with `openbb-core[pandas]>=2.0.0`, entry points under `[project.entry-points.*]` and an `obbject_name` default of `template_ext`.
- At the initial inventory, the root `openbb` metapackage was still on Poetry and the legacy `build/` publish/nightly scripts were incompatible with V5. The metapackage was migrated to hatchling/PEP 621 version 5.0.0 in direct commit `6d8e44100ab`; `openbb_platform/poetry.lock` and the obsolete scripts were removed, and `uv.lock` is now committed.
- The desktop app's vite/vitest/esbuild bumps from develop were discarded by the same merge; `publish-openbb-jodi.yml` still checks out `base.ref || 'develop'`.
</details>
<details>
<summary><h2>openbb-core</h2></summary>
openbb-core 1.6.13 -> 2.0.0 is the V5 foundation. The packaging and lint migration, the package-builder split and the first coverage push came in [#7482](https://github.com/OpenBB-finance/OpenBB/pull/7482) and [#7484](https://github.com/OpenBB-finance/OpenBB/pull/7484);
the layered `openbb.toml` config loader in [#7492](https://github.com/OpenBB-finance/OpenBB/pull/7492); streaming in [#7530](https://github.com/OpenBB-finance/OpenBB/pull/7530); the engine-agnostic charting layer in [#7545](https://github.com/OpenBB-finance/OpenBB/pull/7545);
FastAPI 0.137+ route iteration in [#7537](https://github.com/OpenBB-finance/OpenBB/pull/7537); the Flask migration toolkit in [#7264](https://github.com/OpenBB-finance/OpenBB/pull/7264); the vectorized `basemodel_to_df` in [#7622](https://github.com/OpenBB-finance/OpenBB/pull/7622);
the license flip in [#7677](https://github.com/OpenBB-finance/OpenBB/pull/7677). [#7485](https://github.com/OpenBB-finance/OpenBB/pull/7485) pinned the dev group, [#7669](https://github.com/OpenBB-finance/OpenBB/pull/7669) reshaped four FRED-backed standard models, and
[#7494](https://github.com/OpenBB-finance/OpenBB/pull/7494)/[#7495](https://github.com/OpenBB-finance/OpenBB/pull/7495) only regenerated `openbb/assets/reference.json`. Twenty-two direct commits (listed above) added POST-body unpacking, docstring-generator fixes, the swagger tag grouping and the
thread-safe singleton.
**Removed**
- `html5lib` dependency.
- `Linters.black()`; `Linters.run()` accepts `linter: Literal["ruff"]` only.
- `LoggingSettings.user_id`, `user_email`, `user_primary_usage` (read from `hub_session`) and the `%(userId)s` field of `FormatterWithExceptions.LOGPREFIXFORMAT`; nothing in openbb_core references `hub_session` any more.
- Standard-model fields `BondIndicesData.symbol/value`, `CommercialPaperData.symbol/maturity/rate/title`, `MortgageIndicesData.symbol/name/rate`, `SpotRateData.rate`: every requested series is now its own column.
- `integration/test_obbject.py` (required real providers) and `poetry.lock`.
- Nearly every `# pylint: disable` directive (three `import-outside-toplevel` lines survive in `openbb_core/app/config/loader.py`).
**Breaking**
- Packaging: `[tool.poetry]` -> `[project]`, build backend `poetry.core.masonry.api` -> `hatchling.build`, wheel packages `["openbb_core", "openbb"]`, `uv.lock` replaces `poetry.lock`; the sdist ships only `openbb_core`, `openbb`, `README.md`, `pyproject.toml`.
- `pandas` is the `openbb-core[pandas]` extra; `require_optional("pandas")` guards `OBBject.to_dataframe/to_polars/to_numpy`, `basemodel_to_df`, `Metadata`, `Fetcher.test`, `OptionsChainsProperties.dataframe` and the pandas-backed standard-model validators.
- Dependency floors: uvicorn `>=0.48.0`, fastapi `>=0.137.2` (raised from `>=0.136.3` by `f0258c93366`), requests `>=2.34.2`, pyjwt `>=2.13.0`, pydantic `>=2.12.3,<3.0.0`, aiohttp `>=3.14.2` (raised from `>=3.13.3` by the same commit), python-multipart `>=0.0.29`, ruff `>=0.15`, `tomli>=2.0.0; python_version<'3.11'`; `requires-python` stays `>=3.10,<4`.
- License Apache-2.0; `APISettings.license_name` default `"Apache-2.0"`; README license section rewritten.
- `OBBject.to_llm() -> str` (returns `"[]"` when empty); `OBBject.to_polars()` raises `OpenBBError` with `pip install polars pyarrow` when polars is missing.
- `api/router/commands.py` uses `Charting = ChartingManager.get_charting_class()` and `CHARTING_INSTALLED = Charting is not None`; `StaticCommandRunner._chart` resolves the accessor via `ChartingManager.accessor_name()` with a new error message; `PackageBuilder` computes
`CHARTING_INSTALLED = ChartingManager.is_installed()`.
- `SingletonMeta` is thread-safe and no longer `Generic[T]`.
- `Credentials.show()` iterates `type(self).model_fields`, unmasks raw `SecretStr` values and no longer prints undeclared extra credentials.
- The committed `openbb/assets/reference.json` is a 10,207-line local-build snapshot listing `equity@1.6.1`, `technical@2.0.0` and `yfinance@1.6.2` — reverted back to a clean 14-line stub by `d377ba941e3` ([#7681](https://github.com/OpenBB-finance/OpenBB/pull/7681)); `openbb/package/__init__.py` now matches the builder's unchanged `""" Autogenerated OpenBB module."""` output.
**New**
- Layered configuration (`openbb_core.app.config`: `load_config`, `load_layered_config`, `apply_config_to_services`, `apply_settings_to_env`, `load_env_files`, `render_config_template`). Resolution order: model defaults -> `system_settings.json`/`user_settings.json` -> `[tool.openbb]` in the nearest
`pyproject.toml` -> `~/.openbb_platform/openbb.toml` (or `.openbb.toml`) -> `./openbb.toml` walking up from CWD -> `$OPENBB_CONFIG` -> `.env` files (`~/.openbb_platform/.env`, `$OPENBB_ENV_FILE`) -> `OPENBB_*` env vars.
`[system]`/`[user]` tables deep-merge and the top-level keys `debug-mode`, `test-mode`, `headless`, `logging-suppress`, `allow-mutable-extensions`, `allow-on-command-output` promote onto `[system]`.
- `openbb_core.app.model.aggrid`: `AgGridRowsRequest`, `AgGridRowsResponse[Row]`, `AgSortColumn`, `AgFilterModel`, `AgGroupingModel`; routes using them are auto-promoted to `ssrm_table` widgets by the platform-api generator.
- Streaming: `OBBStream` (`openbb_core/app/model/stream.py`) with `id` (uuid7), `provider`, `warnings`, `extra`, `media_type`, `async for`, `start(output=None, handler=None)` on a background thread (stdout, path, file or socket sink), `stop()`, `wait()`, `aiter()`, `aiter_bytes()`,
`OBBStream.from_query()` and a module-level `stop_all()` wired to atexit/SIGINT/SIGTERM.
- Fetcher streaming contract: `Fetcher.stream_data(query, data, **kwargs)` (async generator), `Fetcher.is_streaming`, `_get_data_type` unwraps async/sync iterator containers, `Fetcher.fetch_data` returns `stream_data(...)` for streaming fetchers, `Fetcher.test` delegates to `_test_stream`,
`RegistryMap._get_results_type` normalizes async-iterator return types to `list`.
- Router/API streaming plumbing: `Router.command` sets `response_model=None` and registers a `200: text/event-stream` response for `-> OBBStream` endpoints; the API wrapper returns a `StreamingResponse` from `output.aiter_bytes()` with `X-OpenBB-Stream-Id`, `X-OpenBB-Provider`, `X-OpenBB-Warning`
headers and passes raw Starlette `Response`s through; `Container._run` wraps a `body_iterator` into `OBBStream`; the docstring generator emits `get_OBBStream_description` and `ImportDefinition` maps `text/event-stream` to `OBBStream`.
- Charting layer `openbb_core.app.charting`: `ChartingManager` (`get_extension`, `accessor_name`, `get_charting_class`, `is_installed`, `functions`, `has_chart`), `ChartingExtension`/`AbstractChartingBackend` protocols, `get_charting_backend_class` (entry-point group `openbb_charting_backend`), and
lifecycle hooks (`ChartLifecycle` resolve_data/pre_figure/post_figure/pre_render/post_render, `HookContext`, `ChartingHook`, `ChartingHooksManager`, `get_hooks_manager`, group `openbb_charting_hooks`).
- System settings `charting_extension` and `charting_backend` (env `OPENBB_CHARTING_EXTENSION`, `OPENBB_CHARTING_BACKEND`), added to `SystemService`'s allowed keys.
- Enterprise Flask Migration Toolkit: an `openbb_core_extension` entry point may reference a Flask app; `ExtensionLoader.flask_objects` detects them, `rest_api` calls `mount_flask_extensions(app, prefix)` to mount each under `{prefix}/{name}` via a2wsgi's `WSGIMiddleware`,
`FlaskIntrospector`/`OpenAPISpecGenerator` introspect routes into a `FlaskMountRegistry`, and `merge_flask_openapi` folds the fragments into the schema; new extra `openbb-core[flask]` (`flask>=3.1.2`, `a2wsgi>=1.10.10`); `openbb_core/app/utils.py` became the package `openbb_core/app/utils/`.
- `openbb_core.app.utils_optional`: `is_installed(module_name)` and `require_optional(*module_names)` with install hints for pandas, numpy, polars, pyarrow, openbb_charting, pycountry, bs4, flask, a2wsgi.
- `openbb_core/app/route_iter.py` (`iter_api_routes`, `iter_included_routers`) expanding FastAPI's `_IncludedRouter`; `AppLoader.deduplicate_router_event_handlers`.
- POST bodies as `params: Model`: a command may declare a single `params: XxxQueryParams` argument; `MethodDefinition.query_params_model` flattens it into kwargs in the generated SDK method, docstring and reference, the generated body repacks them, and `filter_inputs` converts a nested `"data"` key
via `convert_to_basemodel`.
- The 4340-line `openbb_core/app/static/package_builder.py` is now the package `package_builder/` (`builder.py`, `class_definition.py`, `docstring_generator.py`, `file_lock.py`, `import_definition.py`, `method_definition.py`, `module_builder.py`, `path_handler.py`, `reference_generator.py`,
`_indent.py`) with every previously importable name re-exported from `__init__.py`.
- `PackageBuilder._write` post-processes generated modules through `_normalize_code_annotations` (rewrites `typing.X` and `List` to builtins only outside strings and comments); `PackageBuilder._distribution_version` tolerates entry-point distributions whose metadata raises.
- OpenAPI tag grouping: `AppLoader.add_openapi_tags` overrides `app.openapi` to collapse per-level route tags into a composite `a/b/c` tag, emits `tags` with router descriptions and `x-tagGroups` (data extensions first); Swagger UI is served with `docExpansion: "none"`.
- `pytest.ini` markers `requires_pandas` and `requires_extensions`.
- `openbb_platform/core/README.md` rewritten to document the three entry-point groups, the `on_command_output`/`immutable`/`results_only` flags with their `OPENBB_ALLOW_ON_COMMAND_OUTPUT`/`OPENBB_ALLOW_MUTABLE_EXTENSIONS` gates, the `openbb-build` console script and
`uvicorn openbb_core.api.rest_api:app`.
**Patterns**
- `[dependency-groups] dev = ["openbb-devtools>=2.0.1", "flask>=3.1.2", "a2wsgi>=1.10.10"]` with `[tool.uv.sources] openbb-devtools = { path = "../extensions/devtools", editable = true }`; ruff and `[tool.ty]` config in the package pyproject (`[tool.ty.environment] python-version = "3.10"`).
- `# ty: ignore[code]` replaces pylint directives, for example `class OpenBBField(FieldInfo): # ty: ignore[subclass-of-final-class]`.
- `.github/workflows/test-openbb-core.yml`: Python 3.10-3.14 (Linux full sweep, macOS/Windows min+max) with `pip install -e ".[pandas,flask]"`, `--cov-config=.coveragerc`, `OPENBB_ALLOW_ON_COMMAND_OUTPUT=True`/`OPENBB_ALLOW_MUTABLE_EXTENSIONS=True`, and an `integration` job instrumenting
subprocesses via a sitecustomize shim; `publish-openbb-core.yml` builds with `uv build --no-sources`, tests the installed wheel after `rm -rf openbb_core openbb`, aborts if the version exists on PyPI and publishes via trusted publishing from a `release/openbb-core-v<version>` branch.
- A new `.coveragerc` (branch=False, parallel=True, omits `build.py`, the two `update_*_data.py` scripts, `tests/*`, `integration/*`) and 47 new `test_*.py` modules plus 3 conftests (`tests/app/model/test_stream.py`, `tests/provider/abstract/test_fetcher_streaming.py`,
`tests/app/config/test_loader.py`, `tests/app/charting/*`, `tests/app/test_flask_*.py`, `tests/app/static/package_builder/*`).
- `integration/conftest.py` writes a synthetic `openbb-fake-integration` distribution (router, provider and OBBject accessor entry points), installs it with `pip install --no-deps -e`, triggers the real build with `OPENBB_AUTO_BUILD=true`, and `integration/test_built_package.py` asserts
`obb.fake_integration.list_indicators` dispatches through the real `CommandRunner`.
- Standard models and core modules use ruff-isort ordering (`pydantic` before `openbb_core`); roughly 150 standard-model files changed only by that reorder.
**Fixes**
- `CommandMap.get_provider_coverage`/`get_command_coverage` skip routes whose `openapi_extra["model"]` is not in `ProviderInterface().map` (`if model and model in mapping`), avoiding a `KeyError` for models with no installed provider.
- `OBBject.to_dataframe()` checks `isinstance(self.results, DataFrame)` before the "Results not found" guard, avoiding pandas' ambiguous-truth-value `ValueError`.
- `basemodel_to_df` parses `date` with one vectorized `to_datetime` call and a vectorized midnight test, falling back to per-element parsing only for mixed-UTC-offset columns (8.92 ms -> 1.46 ms for 250 bars, 162 ms -> 12 ms for 5000 bars).
- `SystemSettings.create_openbb_directory` is an instance-mode `@model_validator(mode="after")`.
- `APIEx` validation uses `parameters.get("provider")` instead of popping it, excludes `provider` from the >3-parameter description requirement and single-quotes only `str` values.
- Seven standard-model annotations corrected to `X | None` where the default is `None`.
- `openbb/__init__.py` loads `openbb.package.__extensions__` via `import_module` and also catches `AttributeError` when falling back to a bare app.
- `combine_certificates` registers `Path(combined_cert).unlink` with `missing_ok=True`; `amake_requests` asserts re-raised results are `BaseException`.
- Instance-level `model_fields` access (deprecated in pydantic 2.11) removed: `_model_fields` helpers in `RegistryMap._extract_info` and `create_combined_model`, class-level access in `ParametersBuilder.validate_kwargs`, `Credentials.model_post_init`, `OptionsChainsData.model_serialize`.
- `OptionsChainsProperties._require_pandas()` and `Metadata` (`require_optional("numpy", "pandas")`) raise a uniform `OpenBBError` install hint when pandas is absent.
- FastAPI 0.137+: `CommandMap`, coverage maps and `add_command_map` iterate `iter_api_routes` (wrapping the `original_route` leaf with the effective prefixed path); exception handlers registered with `app.add_exception_handler`; `FastAPI(strict_content_type=False)`.
</details>
<details>
<summary><h2>openbb-cli</h2></summary>
openbb-cli 1.4.2 -> 2.0.0 was rewritten in [#7433](https://github.com/OpenBB-finance/OpenBB/pull/7433) around a non-TTY default, a pluggable `Dispatcher`, precomputed `.spec` files and `--generate-extension` codegen.
OpenAPI ingestion was hardened by [#7586](https://github.com/OpenBB-finance/OpenBB/pull/7586) and [#7589](https://github.com/OpenBB-finance/OpenBB/pull/7589) (modular `$ref` bundling) and [#7606](https://github.com/OpenBB-finance/OpenBB/pull/7606) (path-item parameter inheritance, `allOf` merging,
safe identifiers);
codegen by [#7597](https://github.com/OpenBB-finance/OpenBB/pull/7597), [#7598](https://github.com/OpenBB-finance/OpenBB/pull/7598) and [#7599](https://github.com/OpenBB-finance/OpenBB/pull/7599). [#7530](https://github.com/OpenBB-finance/OpenBB/pull/7530) added SSE streaming,
[#7545](https://github.com/OpenBB-finance/OpenBB/pull/7545) decoupled it from `openbb_charting`,
[#7537](https://github.com/OpenBB-finance/OpenBB/pull/7537) refreshed the lock, and [#7677](https://github.com/OpenBB-finance/OpenBB/pull/7677) relicensed it. Direct commits `932a895a069` and `5f4dda273b8` added Plotly figure rendering and `strip_theme_colors`.
**Removed**
- `Settings.HUB_URL` and `Settings.BASE_URL`; `--dev` no longer repoints them.
- `exe --url` and the OpenBB Hub routine download path (`ROUTINE_DEFAULT_FILES`, `ROUTINE_PERSONAL_FILES`, `default/`/`personal/` prefixes, the `requests` import).
- `record --public/-p` and `SESSION_RECORDED_PUBLIC`.
- The module-level `PLATFORM_ROUTERS` dict and the import-time `from openbb import obb` in `cli_controller.py`; the `system` REPL command; `user` as a model-dump command (now the `/user/` menu).
- `pytz` (stdlib `zoneinfo` instead).
- Every direct `openbb_charting` import (`session.py`, `base_platform_controller.py`, `controllers/utils.py`).
- `print_rich_table` truncation to `ALLOWED_NUMBER_OF_ROWS`/`ALLOWED_NUMBER_OF_COLUMNS` (settings remain but are unused) and `MenuText._format_cmd_name` truncation.
- `poetry.lock` and the `fastapi = "0.136.3"` pin.
**Breaking**
- Packaging: PEP 621 + hatchling; `openbb[all]` -> `openbb-core[pandas]>=2.0.0`; `httpx>=0.28.0,<1.0.0`, `pyyaml>=6.0`, `tomli>=2.0` (py<3.11) added; `pywry` moved to the `interactive` extra; new `charting = ["openbb-charting>=3.0.0"]` and `all` extras; license Apache-2.0.
- `openbb <command.path> [--key value]` dispatches once and prints a JSON line; the REPL requires `-i/--interactive`; `main(argv=None) -> int`, `__main__` handles `BrokenPipeError`; `-t`, `-m`, `-f`, `--HistoryManager.hist_file` are unreachable from the entry point.
- `Settings.USE_INTERACTIVE_DF` default False; new `Settings.OUTPUT_MODE` (`rich|json|tsv|html`, default `tsv`) and `OutputMode` enum; `_apply_interactive_defaults` flips them under `-i`.
- `Session` is lazy (`_obb`, `prompt_session`, `backend`, `output_adapter`, `is_interactive` properties; `_build_prompt_session`; `Style(directory=None)`).
- `CLIController.__init__(jobs_cmds=None, *, backend=None)`; `CHOICES_COMMANDS_BUILTIN = ["record", "stop", "exe", "results"]`, `CHOICES_MENUS_BUILTIN = ["settings", "user", "feature"]`; `run_cli`, `main`, `launch` accept `backend=`.
- `PlatformControllerFactory.__init__(platform_router=None, *, backend=None, router_name=None, reference=None)`; `create()` injects `_factory_backend`, `_factory_translators`, `_factory_paths`; `PlatformController.__init__` gained `paths` and a new `ValueError` message.
- `ArgparseClassProcessor._build_paths(target)` no longer recurses (`"subpath"` only); `Registry.all` returns `obbject.model_dump(exclude={"results"})`; `Registry.register` accepts `results is not None`.
- `BaseController.check_path` regex `^[a-z0-9_\-/]*$`; `parse_input` prepends `home` for `/`-prefixed input and protects `-f/--file` paths (`.db/.sqlite/.sqlite3`); `parse_and_split_input` drops empty commands.
- `results` gained `-i`/`-k`, `db`/`sqlite`/`sqlite3` export choices and renders through `session.output_adapter.display`; `PlatformController` routes OBBject results through `output_adapter.display` and `extract_dataframe`; `SettingsController` uses `session.settings.__class__.model_fields`.
- `LocalBackend.routers` skips `user`, `system`, `account` and `_`-prefixed names only, so routers containing `_` now surface.
- The test workflow runs `uv pip install --system -e ".[charting]" --group dev` with coverage on ubuntu 3.10-3.14 plus macOS/Windows 3.10 and 3.14; README retitled "ODP Command-Line Interface" with docs at `docs.openbb.co/odp/cli`.
**New**
- Mode flags (mutually exclusive): `-i/--interactive`, `--batch`, `--generate-spec`, `--generate-extension`, `--list-commands`, `--describe COMMAND[:PROVIDER]`, `--print-config-template`, `--show-config`.
- Option flags: `--config PATH`, `--env-file PATH`, `--batch-concurrency N`, `--server URL`, `--spec [NAME=]PATH` (repeatable), `-o/--output PATH`, `--openapi-path PATH`, `--socrata-story URL_OR_PATH`, `-H/--header KEY=VALUE`, `--header-file PATH`, `-Q/--query-param KEY=VALUE`,
`--query-param-file PATH`, `--provider-name`, `--project-name`, `--package-name`, `--router-name`, `--include PATTERN`, `--exclude PATTERN`, plus `--dev`/`--debug` and a `command` REMAINDER positional.
- Environment: `OPENBB_CLI_CONFIG`, `OPENBB_CLI_ENV_FILE`, `OPENBB_CLI_BATCH_CONCURRENCY`, `OPENBB_SERVER_URL`, `OPENBB_SPEC_PATH`, `OPENBB_HEADER_FILE`, `OPENBB_QUERY_PARAM_FILE`, any `OPENBB_HTTP_QUERY_<NAME>` becomes a `?name=` query param; TOML `[settings]` keys and
`output-mode`/`flair`/`timezone`/`rich-style` promote to `OPENBB_<FIELD>`.
- Layered TOML config (`openbb_cli/config/loader.py`): `[tool.openbb-cli]` in the nearest `pyproject.toml` -> `~/.openbb_platform/openbb.toml` -> `./openbb.toml` walking up -> `--config`/`$OPENBB_CLI_CONFIG`; keys `server`, `spec`, `openapi-path`, `header-file`, `query-param-file`, `output`,
`batch-concurrency`, `auth-hook`, `[headers]`, `[query]`, `[specs.<ns>]`, `[settings]`; `.env` files (`~/.openbb_platform/.env`, `--env-file`) loaded before argparse with `os.environ.setdefault`.
- `openbb_cli.dispatchers`: `Dispatcher` protocol, `LocalDispatcher` (in-process `obb`), `HttpDispatcher` (httpx against openbb-platform-api or any OpenAPI server), `MultiSpecDispatcher` (`<ns>.<cmd>` routing), NDJSON wire models `Request`/`Response`/`ResponseError` with `extra="forbid"`.
- Batch mode: NDJSON requests on stdin, concurrent responses (`asyncio.Semaphore`, default 8); reserved `__commands__` and `__schema__` introspection commands implemented by the HTTP and multi-spec dispatchers only; `--list-commands`/`--describe` exit 2 without `--spec` or `--server`.
- `.spec` files (`SPEC_VERSION = 5`): `--generate-spec` writes a compact JSON spec stamped with `content_sha256`; `load_spec` rejects version mismatches, schema violations (`SpecDocument`) and hash mismatches; specs carry `base_url`, `api_prefix`, `commands`, `routers`, `reference`, `generator`,
`source_url`, `api_version`; `--generate-spec` accepts the output path as its first positional.
- Spec-driven argument parsing (`parse_command_argv`): per-provider narrowing, `BooleanOptionalAction` booleans, JSON-typed body args, ISO datetime coercion, URL overload merging (`url_templates`, longest fully-satisfied template wins).
- OpenAPI ingestion (`dispatchers/openapi_schema.py`): JSON or YAML, `--openapi-path`, specs embedded in HTML landing pages, 3.1 `type` arrays rewritten to `anyOf` (`expand_type_arrays`), `apiKey` security schemes materialized as parameters, menu tree and `obb.reference`-shaped metadata
(`build_router_map`, `build_reference`, `detect_api_prefix`, `url_to_command`); same-origin external `$ref`s bundled with document-count (512), byte (8 MiB), depth (128) and no-redirect limits; `.` in URL segments maps to `_`.
- Socrata support: `--socrata-story` (or `/resource/{uid}` / `/api/views/{uid}` URLs) builds a spec from `datasetUid`s, resolves categorical choices via SoQL `$group`, emits `start_date`/`end_date` and `limit`/`offset` -> `$limit`/`$offset`; the HTTP dispatcher rewrites `$where`/`$order`, fetches
all pages for `limit=0` and truncates to N most recent dates.
- Auth hooks: an importable `module:attribute` callable (`AuthContext` -> `AuthDecision(headers, query_params, allow, deny_reason)`, sync or async) configured globally or per `[specs.<ns>]`; a deny short-circuits with `AccessDenied` and hides commands from introspection.
- `--generate-extension` (`openbb_cli.codegen`): a hatchling `pyproject.toml` with `openbb_provider_extension`/`openbb_core_extension` entry points and a `[tool.openbb-codegen]` provenance block, one `Router` per namespace, one `QueryParams`/`Data`/`Fetcher` module per GET command, POST commands
under a `tools` provider, a `Provider(...)` module, README, `utils.py`, `record_http` test modules with VCR redactions; output post-processed with `ruff check --fix` and `ruff format`; credential-looking params and required path-item headers/cookies are promoted into `credentials=[...]`.
- Backend-pluggable REPL: `openbb_cli.backend` (`Backend` protocol, `LocalBackend`, `SpecBackend`, `SpecTranslator`) so `openbb -i --spec X.spec` or `openbb -i --server URL` runs the full REPL without `openbb` installed; `openbb -i <command ...>` seeds the queue.
- Output adapters `openbb_cli.outputs`: `RichTableOutput`, `JsonOutput`, `TsvOutput`, `HtmlOutput`, `StdioOutput`; `Session.output_adapter` follows `settings.OUTPUT_MODE`.
- Plotly figure rendering: `is_plotly_figure`, `render_figure_html` from `assets/figure.html` (inlined plotly.js with CDN fallback), `show_figure`, `strip_theme_colors`; TSV mode prints the figure JSON; the HTTP dispatcher wraps figure payloads into an `OBBject` with `Chart(format="plotly")`.
- `load -f/--file PATH [--sheet-name NAME] [--register_key KEY]` in every menu (CSV/JSON/XLSX/XLS/DB/SQLite) with a lazy `SQLiteTable` wrapper and tab completion.
- `/feature/` menu (`FeatureController`): `list`, `select`, `info`, `view`, `query`, `colname`, `coltype`, `addcol`, `dropcol`, `renamecol`, `modifycol`, `join`, `copy`, `save`, `delete`, `results`.
- `/user/` menu (`UserController`) with one toggle or `-v/--value` command per `obb.user.preferences` field and a `/user/credentials/` submenu (`CredentialsController`) with masked status; session-only.
- SQLite export (`--export db|sqlite|sqlite3`) via `DataFrame.to_sql` with an overwrite/append/new-table prompt.
- SSE streaming end to end: `_HttpSSESource` returns an `OBBStream` for `text/event-stream` commands, one-shot mode follows to stdout until end or Ctrl+C, `PlatformController._follow_stream` does the same, codegen emits streaming fetchers (`aextract_data -> AsyncIterator[str]`, `stream_data`) and
`OBBStream.from_query` commands.
- The HTTP dispatcher coerces rows to the spec's column types, attaches `extra["results_metadata"]` and `extra["metadata"]` (`Metadata` with duration and route) and returns a real `OBBject`.
- Completion: `results --index/--key` from the live registry, `load --file` from the data directory, spec-mode flags and choices, `complete_while_typing=True`.
**Patterns**
- `[dependency-groups] dev = ["openbb-devtools>=2.0.1"]`, `[tool.uv.sources]` for `openbb-core` and `openbb-charting`, committed `uv.lock`; ruff with numpy pydocstyle and `[tool.ty]` (`src.include = ["openbb_cli"]`); targeted `# ty: ignore[code]` and `# noqa` directives.
- `.coveragerc` (`source = openbb_cli`, `parallel = True`, omits `openbb_cli/cli.py` and assets) with `coverage combine` of subprocess partials in `conftest.py`; 29 `# pragma: no cover` markers across 11 files.
- `cli/conftest.py` builds and installs a real hatchling extension `openbb-cli-fake` exposing `obb.cli_test.{echo,quote,bomb,rows}`, triggers `openbb-build` in a fresh subprocess, snapshots/restores `openbb/package` and `openbb/assets`, and provides a session-wide `run_in_obb` worker.
- Static HTML lives in `openbb_cli/assets/figure.html` with `__TITLE__`/`__PLOTLYJS__`/`__FIGURE__` tokens.
- `lint-openbb-cli.yml` (ruff format/check + ty on changed `cli/**/*.py`) replaces the shared `general-linting.yml`; the `openbb-cli` test workflow runs a 9-way matrix; no `publish-openbb-cli.yml` exists.
- Lazy imports of `openbb`, `openbb_core` models and `prompt_toolkit` (inside functions or `lru_cache` accessors) so the CLI starts in about 50 ms against a `.spec`.
- Docstrings normalized to numpy style; `# pylint: disable` banners, inline comments and TODOs stripped.
**Fixes**
- Path-item-level `parameters` (`in: path`/`in: query`) are inherited by every operation with operation-level overrides on `(name, in)`; required path-item `header`/`cookie` params route through credential handling.
- `allOf` compositions in response and request-body schemas collapse into one object schema (`merge_allof`); `deref_schema`/`merge_allof` skip `default`, `example(s)`, `enum`, `const`, `x-*`.
- Generated POST signatures use Python-safe identifiers (`from`, `REB-APIKEY`), dedupe on the emitted identifier and key payloads by wire name.
- Generated provider tests use `safe_field_name` Python parameter names.
- `unpack_response` only unwraps when every list item is a dict or the list is the payload's only key; `_envelope_inner_schema` skips scalar item schemas.
- Generated pydantic classes coerce `[]` to `None` on optional object-typed fields (PHP-style serializers).
- `fetch_openapi` surfaces the parse error from a 2xx non-OpenAPI response (`_raise_fetch_failure`) instead of silently re-fetching.
- `strip_theme_colors` removes `template` and every `*color` layout key before `send_figure`.
- `ArgparseClassProcessor._custom_groups_from_reference` matches routes by the flattened `class_name_function_name` form; `_get_action_type` recognizes `types.UnionType`; custom-type flattening skips `*args`/`**kwargs`.
- `__patch_controller_functions` wraps its `yield` in `try/finally`; `system_clear` uses `subprocess.run("cls"|"clear", shell=True, check=False)`; rich/html adapters fall back to the terminal table when `session.backend` is `None` or `send_table` raises.
- Sub-menu partitioning uses exact prefix matching (`f"{router}_{path}_" in f"{name}_"`, `translator_name.startswith(sub_prefix)`).
- `BaseController.load_class` refreshes a cached controller's completer (`update_completer(choices_default)`) before re-entering its menu.
</details>
<details>
<summary><h2>openbb-platform-api</h2></summary>
openbb-platform-api 1.3.6 -> 2.0.0 is almost entirely [#7494](https://github.com/OpenBB-finance/OpenBB/pull/7494): hatchling packaging, the `app/`, `models/`, `service/` split behind tested import shims, the layered `openbb.toml` bootstrap, `--spec` proxy mode and a 489-test suite.
[#7677](https://github.com/OpenBB-finance/OpenBB/pull/7677) flipped the license, [#7518](https://github.com/OpenBB-finance/OpenBB/pull/7518) trimmed `default_apps.json`, and direct commits `768e52c6358` (merge widgets), `1cbb24d8b7a`, `5b1bc33e579` and `bf0cb48465f` followed. The metapackage still
pins `openbb-platform-api = "^1.3.6"`.
**Removed**
- The "Example BLS App" dashboard (`economy_survey_bls_search_bls_obb`, `economy_survey_bls_series_bls_obb`) from `assets/default_apps.json`.
- README sections Markdown Widget, Table Widget, Metric Widget, Query Parameters, Easy Date Picker, Annotated Query Params, Annotated Table Fields, Export apps.json, Installation, Usage, Launch Custom App (collapsed into `## Install`, a launch sample and one "Example Application" block).
- The pandas import in `OmniWidgetResponseModel.validate_model` (MRO-based `_is_pandas_dataframe` and `zip(..., strict=True)` instead).
**Breaking**
- Packaging: `[project] version = "2.0.0"`, hatchling, `[dependency-groups] dev = ["openbb-devtools>=2.0.1", "httpx>=0.28.0,<1.0.0"]`, `uv.lock` added (`poetry.lock` still committed); `openbb-core>=2.0.0`, `deepdiff>=8.6.2`, `tomli>=2.0` on py<3.11; license Apache-2.0 with a new README license
section.
- `main.py` is a bootstrap: `_short_circuit_on_help()`, `_bootstrap_config()`, then `globals().update(...)` of `app.app`; `uvicorn.run` still targets `openbb_platform_api.main:app` and the `openbb-api` script `openbb_platform_api.main:main`.
- `utils/api.py` is a lazy `__getattr__` shim (`parse_args`/`LAUNCH_SCRIPT_DESCRIPTION` -> `app/args.py`, `import_app` -> `app/bootstrap.py`, `check_port`/`get_user_settings` -> `utils/network.py`, `get_widgets_json`/`FIRST_RUN`/`PATH_WIDGETS`/`logger` -> `service/widgets_service.py`);
`query_models.py`, `response_models.py`, `utils/merge_agents.py`, `utils/merge_apps.py` re-export from `models/` and `service/`.
- Route discovery uses `iter_api_routes(app)` and `getattr(route, "original_route", route).endpoint`, which is what makes `include_router` routes discoverable under FastAPI 0.137+.
- `import_app(...) -> FastAPI` installs the six `ExceptionHandlers` inline and adds CORS through the idempotent `apply_cors_from_system_service(app)`; the default `rest_api.app` is imported only when no `--app`/`--spec` app was supplied; TOML `[middleware] hooks` are registered at import.
- widgets.json: `format: "date"` -> `cellDataType: "dateString"`; a `date` field with a date cell type gets `"sort": "desc"`; `fiscal_year`/`year`/`year_born`/`calendar_year` -> `cellDataType: "text"`, `formatterFn: "none"`; routes with a 2xx `event-stream` content type are skipped.
- `--spec` (or `[spec]`) and `--app` are mutually exclusive.
**New**
- `--spec <path>` / `[spec] path`: an `openbb-cli` `.spec` (version 5, `content_sha256` verified, optional deploy pin) becomes an aiohttp-backed proxy FastAPI app, one route per command at its `url_path`, with hop-by-hop headers filtered, `{path}` placeholders substituted and `wire_name` query
rewriting.
- Multi-spec mode: each `[spec.NAME]` subtable (`path`, `mount`, `base_url`, `content_sha256`, `[spec.NAME.headers]`, `[spec.NAME.auth] hooks`, `[spec.NAME.middleware] hooks`) mounts its own sub-app on a parent FastAPI (`app.state.openbb_specs`); mount collisions raise at startup.
- `[spec.headers]` / `[spec.NAME.headers]` inject static upstream headers with `$VAR`/`${VAR}` expansion (unresolved entries skipped with a warning; config headers override incoming ones).
- Spec launches rewrite widget defaults (`source: [<spec filename>]`, `mcp_tool.mcp_server`, namespaced `mcp_tool.tool_id`) and trim uniform `T00:00:00` suffixes from date columns in proxied JSON (top-level lists and `results`/`data`/`rows`/`records` envelopes).
- `--config-file <path>` (or `OPENBB_API_CONFIG` / `OPENBB_CONFIG`) selects the explicit layer of the core cascade; a `[launcher]` table supplies defaults for any CLI flag (CLI wins); malformed explicit TOML raises at startup; `[env]` is pushed into `os.environ` without clobbering shell variables,
with chained `$VAR` substitution.
- `[middleware] hooks = ["module:async_callable", ...]` registers Starlette-style HTTP middleware (validated at startup; first entry outermost); per-spec `[spec.NAME.auth]`/`[spec.NAME.middleware]` hooks are registered on the sub-app as `BaseHTTPMiddleware`.
- `-h` as an alias of `--help`, handled before the openbb-core stack is imported.
- SSRM auto-promotion: a route whose request body is (or `allOf`-extends) `AgGridRowsRequest`, or whose 200 response is `AgGridRowsResponse[...]` / has `{rowData, rowCount}`, is emitted as `type: "ssrm_table"` with `runButton: true` and an empty `dataKey`; `get_data_schema_for_widget` falls back to
the POST operation and descends into `rowData.items`.
- Inline-schema fast paths in `get_data_schema_for_widget` (`results.items`, `rowData.items`, bare object schema) and a defensive `components.schemas` lookup for apps without a `components` block.
- `apply_cors_from_system_service(app) -> bool` (idempotent) applied to every app path including the spec proxy.
- Package layout `app/` (`args`, `bootstrap`, `config`, `middleware`, `spec`, `app`), `models/` (`query`, `response`), `service/` (`widgets_service`, `apps_service`, `agents_service`), `utils/network.py`; `synthesize_openapi_from_spec(spec)` helper (exercised only by tests); spec provenance on
`app.state.openbb_spec_*`.
- README sections "Spec-driven proxy mode", `[spec]` credential injection, "Custom HTTP middleware", "Single-file launch".
**Patterns**
- Ruff (numpy pydocstyle, per-file ignores for tests) and `[tool.ty]` (`unresolved-import = "warn"`) in-package; `# ty: ignore[...]` in place of pylint disables (one `# pylint: disable=import-outside-toplevel` remains in a README sample).
- Tests mirror the package (`tests/app`, `tests/models`, `tests/service`, `tests/utils`, `tests/test_compat_shims.py`): 6 files / 61 tests on develop -> 16 files / 489 on v5, `httpx` in the dev group for `TestClient`, `.coveragerc` with `show_missing`.
- `.github/workflows/test-unit-platform-api.yml`: PRs to develop/v5/feature/cli-2 touching platform_api, core or devtools, 9-cell matrix, `uv pip install --system -e . --group dev`, `pytest tests --cov=openbb_platform_api --cov-config=.coveragerc`; no publish workflow.
- Config is loaded once into `_BOOTSTRAPPED_CONFIG` via core's `load_layered_config` (the bootstrap call applies `[system]`/`[user]` and env promotion; `parse_args` re-reads with `apply_to_services=False, apply_to_env=False`).
- `tests/test_compat_shims.py` asserts every legacy import path resolves to the same V5 objects and that the `utils.api` proxy reflects live `widgets_service` state.
- `check_for_platform_extensions` lives in `app/bootstrap.py` (lazy `SystemService` import); `service/__init__.py` re-exports `FIRST_RUN`/`PATH_WIDGETS` by value while `app/app.py` mutates `widgets_service.FIRST_RUN`.
**Fixes**
- `get_additional_agents` no longer crashes on `endpoints.startwith(path)` / `agents[k][v]["endpoints"][name]`; the rewrite uses `endpoint_path.startswith(path)` and guards non-dict values.
- `PdfResponseModel.validate_model` no longer raises `UnboundLocalError` on the url-only path.
- `OmniWidgetInput._validate_prompt` repairs trailing commas on the input `v` (develop ran the regex on an empty placeholder) and passes non-string scalars through.
- `/widgets.json` in `--editable` mode reloads from disk on every request including the first.
- `fix_router_widgets` prefixes bare relative endpoints (`endpoint`, `wsEndpoint`, `imgUrl`, param `endpoint`, `optionsEndpoint`) and keys merged widgets by `widgetId` (`768e52c6358`).
- `parse_args` joins `--agents-json`/`--widgets-json`/`--apps-json` directories with `os.path.join` and detects `module:attr` notation so `C:\path\file.py` is not mis-split.
- Form-widget POST schemas are looked up on the form endpoint path; `OmniWidgetResponseModel` guards `content is not None and parse_as`.
</details>
<details>
<summary><h2>openbb-mcp-server</h2></summary>
openbb-mcp-server 1.4.1 -> 2.0.0 ([#7495](https://github.com/OpenBB-finance/OpenBB/pull/7495), plus the relicense in [#7677](https://github.com/OpenBB-finance/OpenBB/pull/7677)) is a ground-up rewrite on fastmcp>=4.0.9 and fastapi>=0.138.2:
stateless BM25 tool discovery, a layered `openbb.toml` launcher, `--spec` proxy mode, `run_pipeline` chaining, `ChartArtifactMiddleware`, optional openbb-cli dispatcher tools and a 100% branch-coverage gate. Direct commits `aba09afb1c5` and `bf0cb48465f` added the `serve_app` conftest fixtures and
README lint.
**Removed**
- Admin tools `activate_tools`, `deactivate_tools`, `activate_category`; `ToolInfo.active`; `CategoryIndex.has_tool()`.
- Settings `cache_expiration_seconds`, `on_duplicate_tools`, `on_duplicate_resources`, `on_duplicate_prompts`, `resource_prefix_format`, `dependencies`, `deprecation_warnings` and their `OPENBB_MCP_*` aliases.
- `TokenAuthProvider.authorize()` and its `resource_server_url`/`authorization_url`/`token_url` attributes.
- `econometrics`, `quantitative`, `technical` from the default `module_exclusion_map` (only `{"coverage": "openbb_core"}` remains).
- `ProcessedRouteData.removed_routes` (now `excluded_routes`); `key:value,key:value` dict parsing in `parse_args` (env vars keep it); the `Env()` instantiation in `parse_args`.
- `poetry.lock`, `tests/app/test_tool_execution.py`, `tests/utils/test_compress_schema.py`.
**Breaking**
- Packaging: hatchling/PEP 621, `[dependency-groups] dev = ["openbb-devtools>=2.0.1", "httpx>=0.28.0,<1.0.0", "openbb-cli>=2.0.0", "openbb-mcp-fixture"]`, `uv.lock`; `openbb-core>=2.0.0`, `fastapi>=0.138.2`, `fastmcp>=4.0.9`, `tomli>=2.0` (py<3.11); license Apache-2.0.
- `openbb-mcp` -> `openbb_mcp_server.main:main` (`app.app.main` is a shim; the launcher body is `launch_mcp()`); `parse_args()` in `app/args.py` returns `{app, transport, mcp_overrides, uvicorn_overrides}`; `import_app` in `app/bootstrap.py`; `cl_doc` -> `LAUNCH_SCRIPT_DESCRIPTION` (lazy aliases in
`utils/app_import.py`).
- `create_mcp_server(auth=...)` accepts `AuthProvider | tuple[str, str] | list[str] | None` (`TypeError` otherwise); `TokenAuthProvider(TokenVerifier)` takes a `(username, password)` tuple; `get_auth_provider(auth)`.
- Discovery is stateless: with `enable_tool_discovery` route tools stay enabled but hidden by `OpenBBToolCatalog`; `default_tool_categories` is ignored; `mcp_config.enable: false` no longer disables a tool in that mode; without discovery all route tools are disabled and only `_enabled_tools`
re-enabled.
- `available_tools` is synchronous and reports name plus description only; non-GET tools on multi-method paths get a `_<method>` suffix (`demo_items_post`); `allowed_tool_categories` is enforced ("Unknown tool" for anything outside it); `module_exclusion_map={}` hides nothing.
- `output_schema` is `None` for routes without a JSON 2xx response; JSON routes get a compressed, description-trimmed schema with the OBBject `chart` field replaced by the `ClientArtifact` schema.
- `StaticPrompt.render` returns `list[Message | str]`; `execute_prompt(prompt_name=...)` -> `get_prompt(name=...)`; route-prompt arguments are emitted in first-appearance order, tagged with the served path and only for routes exposing a method.
- `on_duplicate_*` collapsed into `on_duplicate` (`OPENBB_MCP_ON_DUPLICATE`); `--version` sets `MCPSettings.version`; `write_to_file` omits a default `default_skills_dir`.
- `process_fastapi_routes_for_mcp` expresses exclusions as `MCPType.EXCLUDE` RouteMaps and walks routes with `fastapi.routing.iter_route_contexts`; `ProcessedRouteData.exposed_methods` added.
**New**
- `--spec <path>` and `[mcp.spec]` / `[mcp.spec.NAME]` tables: a `.spec` (version 5, `content_sha256` integrity plus optional operator pin) becomes a FastAPI proxy exposed as MCP tools, with per-mount headers (`[mcp.spec.headers]` with `$VAR` substitution), `wire_name` query rewriting, zero-time
date trimming and hooks; `--spec` and `--app` are mutually exclusive.
- `--config-file <path>` (`$OPENBB_MCP_CONFIG` / `$OPENBB_API_CONFIG` / `$OPENBB_CONFIG`) with `[mcp]` defaults for any CLI flag (CLI wins, TOML beats env) and `[env]` injection.
- `[mcp.auth]` and `[mcp.middleware]` `hooks` lists of `module:attr` async callables wrapped as `BaseHTTPMiddleware` on the HTTP/SSE transports, between CORS and `SSEShutdownWrapper`.
- `run_pipeline` (always registered): `PipelineStep` with `tool`, `arguments`, `id`, `inputs` mapping an argument to an earlier step's `results`; ids, references and `outputs` validated before any step runs.
- `search_tools` (BM25, max 5 results) and `call_tool` from `OpenBBToolCatalog`, which hides route tools from `list_tools`.
- openbb-cli dispatcher tools `openbb_dispatch`, `openbb_batch_dispatch`, `openbb_list_commands`, `openbb_describe_command` (registered when `openbb-cli` is importable and `enable_cli_tools` is true, default True; `cli` extra `openbb-cli>=2.0.0`).
- `expose_choices`: provider `choices` and `x-widget_config` options become an `enum` or a "Valid values" note; `optionsEndpoint` becomes a note naming the listing tool.
- `ChartArtifactMiddleware`: line/bar/scatter/pie/donut Plotly figures become Workspace `ClientArtifact` `chart` artifacts with `content` rows and `chart_params`, everything else a `table` artifact; typed-array `bdata` is decoded; `artifact_output_schema` rewrites the OBBject `chart` output field.
- `MCPConfigModel` declares `name`, `tags`, `enable`, `describe_responses`, `mime_type`; `exclude_args` is applied; `_trim_model_descriptions` keeps only the first paragraph of object descriptions.
- Bundled skill `use_openbb_cli` (`skill://use_openbb_cli/SKILL.md`); existing skills rewritten for stateless discovery, `run_pipeline`, chart artifacts and `uv pip install -e . --group dev`.
- `openbb-mcp --help` / `-h` prints `LAUNCH_SCRIPT_DESCRIPTION` before any bootstrap; unknown `--key value` routing (settings fields, `--httpx-<option>`, uvicorn) is documented.
- Public helpers `strip_api_prefix`, `route_naming`, `tool_name_for_route`; the installable test extension `openbb-mcp-fixture` (`mcp_fixture` router with `echo`, `fail`, POST `scale`) auto-installed by conftest.
- Workflows `publish-openbb-mcp-server.yml` (release branch, PyPI check, `uv build --no-sources`, trusted publishing) and `test-unit-mcp-server.yml` (ruff, `ty check`, `--cov-branch --cov-fail-under=100` on 3.10-3.14 across ubuntu/macos/windows).
**Patterns**
- ruff (numpy pydocstyle) and `ty` in pyproject and CI; `# pylint: disable` stripped; numpy docstrings with Parameters/Returns/Raises.
- `[tool.coverage.run] branch = true`; pytest `filterwarnings = ["error", ...]`.
- Layered `openbb.toml` via core `load_layered_config`; the `isolated_config` fixture patches `loader.USER_OPENBB_DIR`.
- Tests dispatch against the real installed fixture extension; `test_auth.py`, `test_cli_tools.py`, `test_spec.py` serve the app with uvicorn on a free loopback port via `serve_app`.
- Subpackage `__init__.py` files eagerly import a subset of modules; legacy paths stay alive through the `utils/app_import.py` `__getattr__` alias.
- The spec proxy imports `aiohttp` at call time without declaring it; it is satisfied transitively through `openbb-core>=2.0.0`.
**Fixes**
- Passing a FastMCP `AuthProvider` to `create_mcp_server(auth=...)` works (develop silently dropped it); a `(username, password)` pair builds the verifier from the pair itself (develop read `settings.server_auth` and rejected every token when it was `None`).
- `install_skill` rejects names outside `[a-z0-9][a-z0-9_-]*` and files whose path escapes the skill directory.
- Server-prompt arguments without a `description` are no longer dropped (`validated_arg.get("description")`).
- `_load_settings_from_env` recognizes PEP 604 unions, so `OPENBB_MCP_UVICORN_CONFIG` and `OPENBB_MCP_MODULE_EXCLUSION_MAP` parse from env.
- `TokenAuthProvider.verify_token` uses strict base64, byte-wise `secrets.compare_digest` and `partition(b":")`.
- `get_httpx_kwargs` copies `httpx_client_kwargs` instead of mutating it; `SSEShutdownWrapper.safe_send` no longer re-sends a response start.
- README: `--port` default 8001, client URLs `/mcp`, prompt typos fixed; skills import `make_request` from `openbb_core.provider.utils.helpers`.
</details>
<details>
<summary><h2>openbb-technical</h2></summary>
openbb-technical 1.6.2 -> 2.0.0 ([#7502](https://github.com/OpenBB-finance/OpenBB/pull/7502)) deleted the 1916-line `technical_router.py` and rebuilt the extension as `indicators/`, `signals/` and `multi/` sub-packages aggregated by `openbb_technical/router.py`, keeping all 27 V4 commands by name
and adding 32 endpoints for 59 routes.
[#7537](https://github.com/OpenBB-finance/OpenBB/pull/7537) adapted the catalog to FastAPI 0.137+ and [#7677](https://github.com/OpenBB-finance/OpenBB/pull/7677) relicensed it; ten direct commits touched locks, ty ignores and workflows.
**Removed**
- `openbb_technical/technical_router.py` (importing `openbb_technical.technical_router` fails; a dead ImportError-guarded fallback remains in `multi/compose.py`).
- `kc.mamode` values `wma`, `hma`, `zlma`; the `DMP_<n>`/`DMN_<n>` columns of `adx`; `fib` fields `min_date`, `max_date`, `min_pr`, `max_pr`, `lvl_text`; the `span_*` forward cloud rows of `ichimoku`; `clenow`'s string-formatted columns.
- `poetry.lock`; `tests/test_technical_helpers.py` (replaced by `tests/test_helpers.py` and per-family test packages); every `# pylint: disable` directive.
**Breaking**
- Packaging: hatchling/PEP 621, `openbb-core[pandas]>=2.0.0`, `pandas-ta-openbb>=0.4.23`, `scikit-learn>=1.6.0`, new `scipy>=1.11` and `statsmodels>=0.14`; `[dependency-groups] dev = ["openbb-devtools>=2.0.1", "openbb-charting>=3.0.0"]`; entry point `openbb_technical.router:router`; license
Apache-2.0; `iter_api_routes` required.
- Every command takes `params: XxxQueryParams` (HTTP params move to the JSON body) and returns typed `XxxData` rows with `date` plus renamed indicator columns; pandas-ta backed indicators drop warm-up rows.
- Defaults and types: `bbands.length` 50 -> 20, `bbands.std` `PositiveFloat`, `adx.length` 50 -> 14, `kc.scalar` 20 -> 2.0, `atr.drift`/`stoch` periods/`adx.drift`/`rsi.drift` and the `rsi`, `macd`, `aroon`, `sma`, `ema`, `wma`, `hma`, `zlma` lengths `PositiveInt`; `rsi/adx/aroon.scalar`
`PositiveFloat`; `cones.trading_periods` `PositiveInt | None`.
- Column renames: `bbands` (`lower, middle, upper, bandwidth, percent`), `kc`/`donchian` (`lower, middle, upper`), `macd` (`macd, signal, histogram`), `aroon` (`aroon_up, aroon_down, aroon_oscillator`), `ichimoku` (`tenkan_sen, kijun_sen, senkou_a, senkou_b, chikou_span`), `fisher`
(`fisher, signal`), `stoch` (`k, d`), `cones` (`lower`, `upper`, integer `window`), `fib` (`level`, `price`), `demark` (`date, up, down`); `clenow` returns per-bar `predicted`, `r2`, `coefficient`, `annualized_coefficient` floats.
- Signals are mounted under `/technical/signals/*`; `relative_rotation(params: RelativeRotationQueryParams)` is categorised `multi` and its crypto example was dropped.
**New**
- Overlays `tema`, `dema`, `kama`, `frama` (even `window`, native numpy), `vwma`, `supertrend` (`supertrend`, `direction`, `long_band`, `short_band`).
- Oscillators `williams_r`, `mfi`, `trix`, `ultimate_oscillator`, `awesome_oscillator`; trend `di` (`plus_di`, `minus_di`, `dx`) and `choppiness`.
- Volatility `realized_volatility` (`std`, `parkinson`, `garman_klass`, `hodges_tompkins`, `rogers_satchell`, `yang_zhang`; default `yang_zhang`, `window=30`) and `realized_volatility_compare`; structure `pivot_points` (classic/fibonacci/woodie/camarilla/demark, day/week/month).
- Statistics `drawdown`, `returns_stats` (mean/std/skew/kurtosis/Sharpe/Sortino/Calmar/max_drawdown/VaR95/CVaR95, summary or rolling), `stationarity` (ADF/KPSS), `hurst` (`rs`/`dfa`), `autocorrelation` (ACF/PACF with 95% bands).
- Signals `signals.crossovers`, `signals.oscillator_signals`, `signals.divergences`, `signals.breakouts`, `signals.candlestick_patterns` (doji, hammer, engulfing, marubozu, spinning_top), `signals.regime`.
- Multi-symbol and utility endpoints `multi`, `correlation`, `correlation_matrix`, `screen` (`gt/gte/lt/lte/eq/between/crossed_above/crossed_below/made_high/made_low`), and the introspected `indicators` catalog filterable by `category`.
- Every endpoint QueryParams declares `__category__` and `__output_columns__`; a `docs/` tree (getting-started, four user guides, generated `api-reference.md`) and a README endpoint table; integration tests run against committed SPY CSV fixtures and an in-process uvicorn server.
- Unit-test tree: `tests/conftest.py`, `tests/test_router.py`, `tests/test_helpers.py`, `tests/test_technical_views.py`, `tests/test_relative_rotation.py`, `tests/indicators/`, `tests/signals/`, `tests/multi/`.
**Patterns**
- Hatchling with `[tool.uv.sources]` for openbb-core and openbb-charting, committed `uv.lock`; ruff (numpy pydocstyle) and `ty` with `# ty: ignore[code]`; explicit sdist include list.
- `test-unit-openbb-technical.yml` and `publish-openbb-technical.yml` with `--cov-fail-under=100` (reasons on every `# pragma: no cover`); router composed via `Router.include_router` with per-module `__all__`; `class TestX` files with a shared OHLCV fixture; integration marked `integration` and
excluded from `pytest tests`.
- `technical_views.py` imports `openbb_charting` lazily inside functions; openbb-charting is a dev-group dependency only.
**Fixes**
- `RelativeRotationFetcher.transform_query` calls `model_validate(params)` instead of the invalid `model_validate(**params)`.
- Catalog introspection uses `iter_api_routes(family_router.api_router)`.
- `technical_relative_rotation` validates `tail_interval` against `day|week|month` (fallback `week`).
- `demark` handles both `EXHC_UPa`/`EXHC_DNa` and `EXHC_UP`/`EXHC_DN` column spellings.
- `stoch` honours the user-supplied periods (V4 passed `fast_k_period=`/`slow_d_period=`/`slow_k_period=` which pandas-ta swallowed, always computing 14/3/3); V5 passes `k`, `d`, `smooth_k`.
</details>
<details>
<summary><h2>openbb-quantitative</h2></summary>
openbb-quantitative 1.6.2 -> 2.0.0 ([#7506](https://github.com/OpenBB-finance/OpenBB/pull/7506)) keeps all 19 V4 commands under the same paths but rewrites each toRelated Repositories
public-apis/public-apis★ 491,175
A collective list of free APIs
NousResearch/hermes-agent★ 256,017
The agent that grows with you
yt-dlp/yt-dlp★ 200,192
A feature-rich command-line audio/video downloader
microsoft/markitdown★ 191,524
Python tool for converting files and office documents to Markdown.
Significant-Gravitas/AutoGPT★ 187,703
AutoGPT is the vision of accessible AI for everyone, to use and to build on. Our mission is to provide the tools, so that you can focus on what matters.