* fix(core): invoke linters via `python -m` so PATH state can't silently skip them
`Linters.run()` used `shutil.which(linter)` which resolves the binary against
the process `PATH`. When users run `.venv/bin/python` directly — as
`dev_install.py` itself does, and as common IDE configurations do — the venv's
`bin/` directory is not on `PATH`, so `which("ruff")` returned `None` and the
linter step silently no-op'd.
That mattered because `ImportDefinition.build` emits speculative type imports
(e.g. `OBBject_EquityInfo`) by design and relies on `ruff --fix` to strip the
unused ones. Without the cleanup, those imports remained in generated files
and produced `ImportError` on first import — the symptom many users have hit.
This change resolves the linter through `sys.executable -m <linter>` so it
always resolves against the running Python's environment, independent of
`PATH`. A pre-check via `importlib.util.find_spec` preserves the
"linter not found" path for environments where the package genuinely isn't
installed. A second guard skips invocation when the target directory has no
`*.py` files, which prevents the linter from falling back to its default
working-directory scan.
Adds two regression tests:
- `test_ruff_strips_unused_imports_via_module_invocation` simulates the
failing scenario by clearing `PATH` and asserts ruff still removes an
unused import.
- `test_run_logs_not_found_when_module_missing` exercises the missing-module
branch with a known-bogus linter name.
* style(linters): collapse subprocess.run call to satisfy black
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(linters): keep command list[str] to satisfy mypy
Glob produces Path objects; concatenating with the str command list
tripped mypy's "list[str] + list[Path]" check. Stringify the file
paths up-front so the assembled command is uniformly list[str].
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Open Data Platform by OpenBB
Open Data Platform by OpenBB (ODP) is the open-source toolset that helps data engineers integrate proprietary, licensed, and public data sources into downstream applications like AI copilots and research dashboards.
ODP operates as the "connect once, consume everywhere" infrastructure layer that consolidates and exposes data to multiple surfaces at once: Python environments for quants, OpenBB Workspace and Excel for analysts, MCP servers for AI agents, and REST APIs for other applications.
Overview
The Core extension is used as the basis for building and integrating Open Data Platform Python packages. It provides the necessary classes and structures for standardizing and handling data. It is also responsible for generating a REST API and Python package static assets, which operate independently and interface with various consumption vehicles.
Typically, this library will be used as a project dependency, and extended.
Go to the documentation for information on getting started.
Prerequisites
- Python >=3.10,<3.14
- Familiarity with FastAPI and Pydantic.
Installation
Installing through pip:
pip install openbb-core
Note that, the openbb-core is an infrastructural component of the OpenBB Platform. It is not intended to be used as a standalone package.
Build
Build the Python application, with installed extensions, by running:
openbb-build
Key Features
- Standardized Data Model (
DataClass): A flexible and dynamic Pydantic model capable of handling various data structures. - Standardized Query Params (
QueryParamsClass): A Pydantic model for handling querying to different providers. - Dynamic Field Support: Enables handling of undefined fields, providing versatility in data processing.
- Robust Data Validation: Utilizes Pydantic's validation features to ensure data integrity.
- API Routing Mechanism (
RouterClass): Simplifies the process of defining API routes and endpoints - out of the box Python and Web endpoints.
Bugs
Report bugs on Github by opening a new issue, or commenting on an already open one, with all the details.
License
This project is licensed under the AGPL-3.0 License - see the LICENSE.md file for details.