mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 13:01:38 +00:00
* merge branch develop with main * bump desktop version * fix the merge * sync Cargo.lock to desktop 2.0.0 * fix cli conftest.py --------- Co-authored-by: deeleeramone <>
208 lines
6.3 KiB
Python
208 lines
6.3 KiB
Python
"""Shared fixtures for the openbb-core test suite.
|
|
|
|
These fixtures intentionally avoid importing or relying on any non-core
|
|
OpenBB packages so the suite can be exercised against just the
|
|
``openbb-core`` distribution (optionally with the ``[pandas]`` extra).
|
|
"""
|
|
|
|
from typing import Any
|
|
|
|
import pytest
|
|
|
|
from openbb_core.provider.abstract.data import Data
|
|
from openbb_core.provider.abstract.fetcher import Fetcher
|
|
from openbb_core.provider.abstract.provider import Provider
|
|
from openbb_core.provider.abstract.query_params import QueryParams
|
|
from openbb_core.provider.registry import Registry
|
|
from openbb_core.provider.standard_models.available_indicators import (
|
|
AvailableIndicatorsData,
|
|
AvailableIndicesQueryParams,
|
|
)
|
|
|
|
|
|
class _FakeQueryParams(AvailableIndicesQueryParams):
|
|
"""Concrete query params for the primary fake provider."""
|
|
|
|
|
|
class _FakeData(AvailableIndicatorsData):
|
|
"""Provider-specific data model that adds a single extension field."""
|
|
|
|
extra_field: str | None = None
|
|
|
|
|
|
class _FakeFetcher(Fetcher[_FakeQueryParams, list[_FakeData]]):
|
|
"""Minimal list-returning fetcher used by the primary fake provider."""
|
|
|
|
require_credentials = True
|
|
|
|
@staticmethod
|
|
def transform_query(params: dict[str, Any]) -> _FakeQueryParams:
|
|
return _FakeQueryParams(**params)
|
|
|
|
@staticmethod
|
|
def extract_data(
|
|
query: _FakeQueryParams, credentials: dict[str, str] | None
|
|
) -> list[dict[str, Any]]:
|
|
return [{"symbol": "FAKE"}]
|
|
|
|
@staticmethod
|
|
def transform_data(
|
|
query: _FakeQueryParams, data: list[dict[str, Any]], **kwargs
|
|
) -> list[_FakeData]:
|
|
return [_FakeData(**row) for row in data]
|
|
|
|
|
|
class _SecondFakeQueryParams(AvailableIndicesQueryParams):
|
|
"""Query params for the secondary fake provider — adds a provider-specific filter."""
|
|
|
|
region: str | None = None
|
|
|
|
|
|
class _SecondFakeData(AvailableIndicatorsData):
|
|
"""Data model for the secondary fake provider — adds a different extension field."""
|
|
|
|
second_extra: int | None = None
|
|
|
|
|
|
class _SecondFakeFetcher(Fetcher[_SecondFakeQueryParams, list[_SecondFakeData]]):
|
|
"""Fetcher used to test multi-provider model registration."""
|
|
|
|
require_credentials = False
|
|
|
|
@staticmethod
|
|
def transform_query(params: dict[str, Any]) -> _SecondFakeQueryParams:
|
|
return _SecondFakeQueryParams(**params)
|
|
|
|
@staticmethod
|
|
def extract_data(
|
|
query: _SecondFakeQueryParams, credentials: dict[str, str] | None
|
|
) -> list[dict[str, Any]]:
|
|
return [{"symbol": "FAKE2"}]
|
|
|
|
@staticmethod
|
|
def transform_data(
|
|
query: _SecondFakeQueryParams,
|
|
data: list[dict[str, Any]],
|
|
**kwargs,
|
|
) -> list[_SecondFakeData]:
|
|
return [_SecondFakeData(**row) for row in data]
|
|
|
|
|
|
class _SingleResultFetcher(Fetcher[_FakeQueryParams, _FakeData]):
|
|
"""Fetcher whose return type is a single ``Data`` instance, not a list.
|
|
|
|
Used to verify ``RegistryMap`` distinguishes list vs. scalar return types.
|
|
"""
|
|
|
|
require_credentials = False
|
|
|
|
@staticmethod
|
|
def transform_query(params: dict[str, Any]) -> _FakeQueryParams:
|
|
return _FakeQueryParams(**params)
|
|
|
|
@staticmethod
|
|
def extract_data(
|
|
query: _FakeQueryParams, credentials: dict[str, str] | None
|
|
) -> dict[str, Any]:
|
|
return {"symbol": "ONE"}
|
|
|
|
@staticmethod
|
|
def transform_data(
|
|
query: _FakeQueryParams, data: dict[str, Any], **kwargs
|
|
) -> _FakeData:
|
|
return _FakeData(**data)
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def fake_provider_name() -> str:
|
|
"""Return the canonical primary fake provider name."""
|
|
return "fake"
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def second_fake_provider_name() -> str:
|
|
"""Return the secondary fake provider name."""
|
|
return "fake_two"
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def fake_model_name() -> str:
|
|
"""Return the standard model name registered by the fake providers."""
|
|
return "AvailableIndicators"
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def single_result_model_name() -> str:
|
|
"""Return the model name registered by the single-result fetcher."""
|
|
return "SingleResult"
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def fake_credential_names(fake_provider_name: str) -> list[str]:
|
|
"""Return the namespaced credential keys expected on the primary provider."""
|
|
return [f"{fake_provider_name}_api_key", f"{fake_provider_name}_api_secret"]
|
|
|
|
|
|
@pytest.fixture
|
|
def fake_provider(
|
|
fake_provider_name: str,
|
|
fake_model_name: str,
|
|
single_result_model_name: str,
|
|
) -> Provider:
|
|
"""Primary fake provider — multi-credential, list and single-result fetchers."""
|
|
return Provider(
|
|
name=fake_provider_name,
|
|
description="Fake provider used to exercise core wiring without external deps.",
|
|
website="https://example.invalid",
|
|
credentials=["api_key", "api_secret"],
|
|
fetcher_dict={
|
|
fake_model_name: _FakeFetcher,
|
|
single_result_model_name: _SingleResultFetcher,
|
|
},
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def second_fake_provider(
|
|
second_fake_provider_name: str, fake_model_name: str
|
|
) -> Provider:
|
|
"""Second fake provider sharing the same standard model — no credentials."""
|
|
return Provider(
|
|
name=second_fake_provider_name,
|
|
description="Second fake provider — exercises multi-provider model merging.",
|
|
website="https://example.invalid",
|
|
credentials=None,
|
|
fetcher_dict={fake_model_name: _SecondFakeFetcher},
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def fake_registry(fake_provider: Provider) -> Registry:
|
|
"""Registry containing only the primary fake provider."""
|
|
registry = Registry()
|
|
registry.include_provider(fake_provider)
|
|
return registry
|
|
|
|
|
|
@pytest.fixture
|
|
def multi_provider_registry(
|
|
fake_provider: Provider, second_fake_provider: Provider
|
|
) -> Registry:
|
|
"""Registry containing both fake providers — for multi-provider scenarios."""
|
|
registry = Registry()
|
|
registry.include_provider(fake_provider)
|
|
registry.include_provider(second_fake_provider)
|
|
return registry
|
|
|
|
|
|
@pytest.fixture
|
|
def standard_data_cls() -> type[Data]:
|
|
"""Re-export the standard ``Data`` subclass used as the model parent."""
|
|
return AvailableIndicatorsData
|
|
|
|
|
|
@pytest.fixture
|
|
def standard_query_cls() -> type[QueryParams]:
|
|
"""Re-export the standard ``QueryParams`` subclass used as the model parent."""
|
|
return AvailableIndicesQueryParams
|