github OpenBB-finance/OpenBB openbb-v5.0.0
OpenBB V5

4 hours ago

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, 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.

Pull requests

Core and packaging

PR Merged Author Title
#7482 2026-04-28 Danglewood [Feature] OpenBB V5: Initial openbb-core Refactor
#7484 2026-04-30 Danglewood [V5] openbb-core: 100% Test Coverage
#7492 2026-05-07 Danglewood [V5] openbb-core: Add Backwards-Compatible Layered Config System (openbb.toml)
#7537 2026-06-18 Danglewood [V5] [BugFix] Fix for Breaking Changes in FastAPI 0.137+
#7524 2026-06-22 Danglewood [V5] Refactor Shared Pass Through Router Extensions For Hatchling
#7264 2026-09-24 Boris Li Enterprise Flask Migration Toolkit
#7622 2026-09-25 Dex Hunter perf(core): vectorize the date conversion in basemodel_to_df
#7681 2026-09-26 Danglewood [Release] openbb-core-v2.0.0rc1: Testing Publish Pipeline

CLI

PR Merged Author Title
#7433 2026-06-01 Danglewood [V5] CLI 2.0 - Pluggable Backends, Non-TTY Default, HTTP Dispatcher, Spec Files + Codegen
#7586 2026-07-14 Dex fix(cli): resolve modular OpenAPI references
#7589 2026-07-14 Danglewood [V5] openbb-cli: Modular OpenAPI Refs
#7597 2026-07-20 Monte Hoover Update generated tests to get python parameter names instead of raw API-provider parameter names.
#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 2026-07-20 Monte Hoover Update class generation code to handle empty data that php-style serialization emits as [].
#7606 2026-09-25 Lucas Zimmermann fix(cli): inherit path-item-level OpenAPI parameters

API, MCP and streaming

PR Merged Author Title
#7494 2026-06-20 Danglewood [V5] openbb-platform-api: Refactor for V5 Spec, Config, Packaging, Test Coverage
#7530 2026-06-22 Danglewood add full support for AsyncIterator response type for streaming output
#7495 2026-09-24 Danglewood [V5] openbb-mcp-server: Refactor for v5 - Spec, Config, Packaging, Test Coverage

Charting and toolkit extensions

PR Merged Author Title
#7507 2026-05-29 Danglewood [V5] openbb-news: Refactor News for V5 and Add Configurable RSS Endpoint
#7506 2026-05-29 Danglewood [V5] openbb-quantitative: Refactor for V5
#7502 2026-05-29 Danglewood [V5] openbb-technical: Refactor for V5 & Add More Quick Win Endpoints
#7505 2026-06-01 Danglewood refactor econometrics for v5
#7545 2026-07-01 Danglewood [V5] openbb-charting: Refactor for V5 and Decouple
#7602 2026-07-23 Danglewood add drugs.com and brutalist as news rss feeds

Providers — refactors and additions

PR Merged Author Title
#7413 2026-05-15 Danglewood [V5] Refactor openbb-oecd for full SDMX 2 API Exposure and V5 Packaging
#7509 2026-05-25 Danglewood [V5] openbb-oecd: Rename oecd_utils as oecd
#7508 2026-05-29 Danglewood [V5] openbb-imf: Refactor for V5
#7518 2026-06-01 Danglewood [V5] openbb-bls: Refactor for V5 + Add Many Endpoints
#7503 2026-06-01 Danglewood [V5] openbb-famafrench: Refactor for V5
#7528 2026-06-08 Danglewood [V5] openbb-congress-gov: Refactor for V5 + Convert To Using Bulk Files Instead of api.congress.gov.
#7560 2026-09-23 Danglewood [V5] openbb-ecb: Refactor for V5 and Expand Coverage
#7561 2026-09-23 Danglewood [V5] openbb-federal-reserve: Refactor for V5 + FFIEC & Regional Fed Routers
#7584 2026-09-23 Danglewood [V5] openbb-eia: Refactor for V5 + Add Full API Implementation
#7604 2026-09-23 Danglewood [V5] openbb-government-us: Refactor for V5 + Move uscongress
#7593 2026-09-23 Danglewood [V5] Feature: Add JODI World Oil & Gas Database
#7615 2026-09-23 Danglewood [V5] openbb-cftc: Refactor for V5 + Add OIS, Forward Curve, and FX Trade Analysis
#7668 2026-09-23 Danglewood [V5] openbb-tmx: Refactor extension for V5
#7670 2026-09-23 Danglewood [V5] openbb-nasdaq: Refactor provider for V5.
#7669 2026-09-23 Danglewood [V5] openbb-fred: Refactor as V5 extension.
#7617 2026-09-23 Danglewood [V5] openbb-cboe: Refactor for V5 + Add Payoff Diagrams
#7674 2026-09-23 Danglewood [V5] openbb-deribit: Refactor provider for V5
#7525 2026-09-24 Danglewood [V5] openbb-sec: Refactor for V5
#7676 2026-09-24 Danglewood [V5] openbb-finra: Refactor for V5

Provider removals

PR Merged Author Title
#7486 2026-05-29 Danglewood remove stockgrid provider
#7485 2026-05-29 Danglewood [V5] remove wsj provider and related code
#7523 2026-06-01 Danglewood delete biztoc
#7522 2026-06-01 Danglewood [V5] Remove openbb-alpha-vantage
#7521 2026-06-01 Danglewood [V5] Remove openbb-benzinga
#7570 2026-07-08 Danglewood remove seeking alpha provider
#7573 2026-07-08 Danglewood remove tradier provider
#7574 2026-07-08 Danglewood remove tiingo provider
#7575 2026-07-08 Danglewood remove intrinio provider
#7576 2026-07-08 Danglewood remove yfinance provider from repo
#7577 2026-09-14 Danglewood remove finviz
#7578 2026-09-14 Danglewood remove trading economics provider
#7610 2026-09-14 Danglewood remove openbb-multpl from repository
#7665 2026-09-14 Danglewood remove fmp provider extension from repository
#7675 2026-09-23 Danglewood remove openbb-econdb provider

License and repository tooling

PR Merged Author Title
#7677 2026-09-24 Danglewood [V5] Update Repository License to Apache 2.0

Direct commits

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

Cross-cutting patterns

  • 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 (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); 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): 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.

Removals

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 none
openbb-benzinga 1.6.1 #7521 none
openbb-biztoc 1.6.1 #7523 none
openbb-congress-gov 1.2.3 #7604, after the in-place refactor in #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 none
openbb-finviz 1.5.1 #7577 none
openbb-fmp 1.6.1 #7665 none
openbb-intrinio 1.6.1 #7575 none
openbb-multpl 1.3.1 #7610 none
openbb-regulators 1.6.2 #7525 openbb-sec router: the eight obb.regulators.sec.* commands are now obb.sec.* / /api/v1/sec/*
openbb-seeking-alpha 1.6.1 #7570 none
openbb-stockgrid 1.6.1 #7486 none
openbb-tiingo 1.6.1 #7574 none
openbb-tradier 1.5.1 #7573 none
openbb-tradingeconomics 1.6.1 #7578 none
openbb-wsj 1.6.1 #7485 none; the etf.discovery sub-router it served was deleted with it
openbb-yfinance 1.6.3 #7576 none
extensions/famafrench (integration tests only, no pyproject) n/a direct commit fbcd512905e, after #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): 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); 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.

Breaking changes

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).

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.skips 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); 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'.

openbb-core

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 and #7484;
the layered openbb.toml config loader in #7492; streaming in #7530; the engine-agnostic charting layer in #7545;
FastAPI 0.137+ route iteration in #7537; the Flask migration toolkit in #7264; the vectorized basemodel_to_df in #7622;
the license flip in #7677. #7485 pinned the dev group, #7669 reshaped four FRED-backed standard models, and
#7494/#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); 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 Responses 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).

openbb-cli

openbb-cli 1.4.2 -> 2.0.0 was rewritten in #7433 around a non-TTY default, a pluggable Dispatcher, precomputed .spec files and --generate-extension codegen.
OpenAPI ingestion was hardened by #7586 and #7589 (modular $ref bundling) and #7606 (path-item parameter inheritance, allOf merging,
safe identifiers);
codegen by #7597, #7598 and #7599. #7530 added SSE streaming,
#7545 decoupled it from openbb_charting,
#7537 refreshed the lock, and #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 $refs 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 datasetUids, 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.

openbb-platform-api

openbb-platform-api 1.3.6 -> 2.0.0 is almost entirely #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 flipped the license, #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.

openbb-mcp-server

openbb-mcp-server 1.4.1 -> 2.0.0 (#7495, plus the relicense in #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.

openbb-technical

openbb-technical 1.6.2 -> 2.0.0 (#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 adapted the catalog to FastAPI 0.137+ and #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.

openbb-quantitative

openbb-quantitative 1.6.2 -> 2.0.0 (#7506) keeps all 19 V4 commands under the same paths but rewrites each to

Don't miss a new OpenBB release

NewReleases is sending notifications on new releases.