"""Integration-test fixtures for openbb-econometrics.""" import threading import time import numpy as np import pandas as pd import pytest from openbb_core.app.utils import df_to_basemodel from openbb_econometrics.utils import mock_multi_index_data _SEED = 20240517 _N_ROWS = 120 @pytest.fixture(scope="session", autouse=True) def api_server(pytestconfig): """Run the OpenBB REST API on 0.0.0.0:8000 for the integration session.""" if pytestconfig.getoption("markexpr") == "not integration": yield None return import uvicorn from openbb_core.api.rest_api import app config = uvicorn.Config(app, host="0.0.0.0", port=8000, log_level="warning") # noqa: S104 server = uvicorn.Server(config) thread = threading.Thread(target=server.run, daemon=True) thread.start() deadline = time.time() + 60 while time.time() < deadline: if server.started: break time.sleep(0.25) else: # pragma: no cover raise RuntimeError("The OpenBB REST API did not start within 60s.") yield server server.should_exit = True thread.join(timeout=15) def _timeseries_records() -> list[dict]: """Build a deterministic OHLCV time series as JSON-ready records.""" rng = np.random.default_rng(_SEED) t = np.arange(_N_ROWS) base = 100 + 0.5 * t + rng.normal(0, 2, _N_ROWS).cumsum() * 0.3 close = base + rng.normal(0, 1, _N_ROWS) open_ = close + rng.normal(0, 0.5, _N_ROWS) high = np.maximum(open_, close) + np.abs(rng.normal(1, 0.5, _N_ROWS)) low = np.minimum(open_, close) - np.abs(rng.normal(1, 0.5, _N_ROWS)) volume = 1_000_000 + rng.normal(0, 100_000, _N_ROWS) + 5_000 * t dates = pd.date_range("2021-01-04", periods=_N_ROWS, freq="B") return [ { "date": day.strftime("%Y-%m-%d"), "open": round(float(o), 4), "high": round(float(h), 4), "low": round(float(lo), 4), "close": round(float(c), 4), "volume": round(float(v), 2), } for day, o, h, lo, c, v in zip(dates, open_, high, low, close, volume) ] @pytest.fixture(scope="session") def timeseries_data() -> list[dict]: """Deterministic OHLCV records for the time-series command tests.""" return _timeseries_records() @pytest.fixture(scope="session") def panel_data() -> list[dict]: """Deterministic entity/time panel records as JSON-safe dicts.""" np.random.seed(_SEED) return [ row.model_dump(mode="json") for row in df_to_basemodel(mock_multi_index_data()) ]