mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-06-14 04:56:57 +08:00
* stash some changes * add more robust testing * mypy * point PR at V5 * introduce spec file * codespell * test fix * fix workflow environment setup * fix workflow environment setup * fix workflow environment setup * add pyyaml to dependencies * split lint jobs * fix workflow environment setup * fix workflow environment setup * workflow env setup * workflow env setup * clean up code comments * add auth hook entrypoints * codespell * add codegen feature * codespell * move _unpack into dispatchers for consistency with codegen packages * surface nested models in the response * fix missing coverage in CI * socrata updates * test fix * detect plotly output * add --include and --exclude flags from generate-extension command * cap test matrix at python 3.14 * no useless comments * platform controller command description split * merge URL overloads from path params * exclude none and unset from model dump --------- Co-authored-by: deeleeramone <> Co-authored-by: Copilot <copilot@github.com>
83 lines
2.7 KiB
Python
83 lines
2.7 KiB
Python
"""Platform controller factory."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from openbb_cli.backend import Backend, LocalBackend
|
|
from openbb_cli.controllers.base_platform_controller import PlatformController
|
|
|
|
|
|
class PlatformControllerFactory:
|
|
"""Factory to create a platform controller from a ``Backend``."""
|
|
|
|
def __init__(
|
|
self,
|
|
platform_router: type | None = None,
|
|
*,
|
|
backend: Backend | None = None,
|
|
router_name: str | None = None,
|
|
reference: dict[str, Any] | None = None,
|
|
) -> None:
|
|
if backend is None and platform_router is None:
|
|
raise ValueError("Either ``backend`` or ``platform_router`` is required.")
|
|
|
|
if backend is not None:
|
|
if router_name is None:
|
|
raise ValueError("``router_name`` is required when ``backend`` is set.")
|
|
self._backend: Backend = backend
|
|
self._router_name: str = router_name
|
|
else:
|
|
del reference
|
|
assert platform_router is not None # noqa: S101
|
|
self._backend = LocalBackend()
|
|
self._router_name = _derive_router_name(platform_router)
|
|
|
|
self._translators, self._paths = self._backend.get_translators_for_path(
|
|
self._router_name
|
|
)
|
|
|
|
@property
|
|
def router_name(self) -> str:
|
|
return self._router_name
|
|
|
|
@property
|
|
def controller_name(self) -> str:
|
|
return f"{self._router_name.capitalize()}Controller"
|
|
|
|
def create(self) -> type:
|
|
"""Create the platform controller class for this router."""
|
|
choices_menus: list[str] = []
|
|
choices_commands: list[str] = []
|
|
for key, value in self._paths.items():
|
|
if value == "path":
|
|
continue
|
|
choices_menus.append(key)
|
|
for name in self._translators:
|
|
if any(
|
|
f"{self._router_name}_{path}_" in f"{name}_" for path in self._paths
|
|
):
|
|
continue
|
|
choices_commands.append(name.replace(f"{self._router_name}_", ""))
|
|
|
|
attributes: dict[str, Any] = {
|
|
"CHOICES_GENERATION": True,
|
|
"CHOICES_MENUS": choices_menus,
|
|
"CHOICES_COMMANDS": choices_commands,
|
|
"_factory_backend": self._backend,
|
|
"_factory_translators": self._translators,
|
|
"_factory_paths": self._paths,
|
|
}
|
|
return type(self.controller_name, (PlatformController,), attributes)
|
|
|
|
|
|
def _derive_router_name(platform_router: type) -> str:
|
|
"""Replicate the legacy class-name → router-name derivation."""
|
|
return (
|
|
str(type(platform_router))
|
|
.rsplit(".", maxsplit=1)[-1]
|
|
.replace("'>", "")
|
|
.replace("ROUTER_", "")
|
|
.lower()
|
|
)
|