Files
OpenBB/cli/openbb_cli/controllers/platform_controller_factory.py
Danglewood 869cfed125 [Release] openbb-v5.0.0 (#7741)
* 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 <>
2026-09-29 10:58:44 -07:00

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