|
|
"""Settings Controller Module.""" |
|
|
|
|
|
import argparse |
|
|
from functools import partial, update_wrapper |
|
|
from types import MethodType |
|
|
from typing import List, Literal, Optional, get_origin |
|
|
|
|
|
from openbb_cli.config.menu_text import MenuText |
|
|
from openbb_cli.controllers.base_controller import BaseController |
|
|
from openbb_cli.models.settings import SettingGroups |
|
|
from openbb_cli.session import Session |
|
|
|
|
|
session = Session() |
|
|
|
|
|
|
|
|
class SettingsController(BaseController): |
|
|
"""Settings Controller class.""" |
|
|
|
|
|
_COMMANDS = { |
|
|
v.json_schema_extra.get("command"): { |
|
|
"command": (v.json_schema_extra or {}).get("command"), |
|
|
"group": (v.json_schema_extra or {}).get("group"), |
|
|
"description": v.description, |
|
|
"annotation": v.annotation, |
|
|
"field_name": k, |
|
|
} |
|
|
for k, v in sorted( |
|
|
session.settings.model_fields.items(), |
|
|
key=lambda item: (item[1].json_schema_extra or {}).get("command", ""), |
|
|
) |
|
|
if v.json_schema_extra |
|
|
} |
|
|
CHOICES_COMMANDS: List[str] = list(_COMMANDS.keys()) |
|
|
PATH = "/settings/" |
|
|
CHOICES_GENERATION = True |
|
|
|
|
|
def __init__(self, queue: Optional[List[str]] = None): |
|
|
"""Initialize the Constructor.""" |
|
|
super().__init__(queue) |
|
|
for cmd, field in self._COMMANDS.items(): |
|
|
group = field.get("group") |
|
|
if group == SettingGroups.feature_flags: |
|
|
self._generate_command(cmd, field, "toggle") |
|
|
elif group == SettingGroups.preferences: |
|
|
self._generate_command(cmd, field, "set") |
|
|
self.update_completer(self.choices_default) |
|
|
|
|
|
def print_help(self): |
|
|
"""Print help.""" |
|
|
mt = MenuText("settings/") |
|
|
mt.add_info("Feature Flags") |
|
|
for k, f in self._COMMANDS.items(): |
|
|
if f.get("group") == SettingGroups.feature_flags: |
|
|
mt.add_setting( |
|
|
name=k, |
|
|
status=getattr(session.settings, f["field_name"]), |
|
|
description=f["description"], |
|
|
) |
|
|
mt.add_raw("\n") |
|
|
mt.add_info("Preferences") |
|
|
for k, f in self._COMMANDS.items(): |
|
|
if f.get("group") == SettingGroups.preferences: |
|
|
mt.add_cmd( |
|
|
name=k, |
|
|
description=f["description"], |
|
|
) |
|
|
session.console.print(text=mt.menu_text, menu="Settings") |
|
|
|
|
|
def _generate_command( |
|
|
self, cmd_name: str, field: dict, action_type: Literal["toggle", "set"] |
|
|
): |
|
|
"""Generate command call.""" |
|
|
|
|
|
def _toggle(self, other_args: List[str], field=field) -> None: |
|
|
"""Toggle setting value.""" |
|
|
field_name = field["field_name"] |
|
|
parser = argparse.ArgumentParser( |
|
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter, |
|
|
prog=field["command"], |
|
|
description=field["description"], |
|
|
add_help=False, |
|
|
) |
|
|
ns_parser, _ = self.parse_simple_args(parser, other_args) |
|
|
if ns_parser: |
|
|
session.settings.set_item( |
|
|
field_name, not getattr(session.settings, field_name) |
|
|
) |
|
|
|
|
|
def _set(self, other_args: List[str], field=field) -> None: |
|
|
"""Set preference value.""" |
|
|
field_name = field["field_name"] |
|
|
annotation = field["annotation"] |
|
|
command = field["command"] |
|
|
type_ = str if get_origin(annotation) is Literal else annotation |
|
|
choices = None |
|
|
if get_origin(annotation) is Literal: |
|
|
choices = annotation.__args__ |
|
|
elif command == "console_style": |
|
|
|
|
|
choices = session.style.available_styles |
|
|
parser = argparse.ArgumentParser( |
|
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter, |
|
|
prog=command, |
|
|
description=field["description"], |
|
|
add_help=False, |
|
|
) |
|
|
parser.add_argument( |
|
|
"-v", |
|
|
"--value", |
|
|
dest="value", |
|
|
action="store", |
|
|
required=False, |
|
|
type=type_, |
|
|
choices=choices, |
|
|
) |
|
|
ns_parser, _ = self.parse_simple_args(parser, other_args) |
|
|
if ns_parser: |
|
|
if ns_parser.value: |
|
|
|
|
|
if command == "console_style": |
|
|
session.style.apply(ns_parser.value) |
|
|
session.settings.set_item(field_name, ns_parser.value) |
|
|
session.console.print( |
|
|
f"[info]Current value:[/info] {getattr(session.settings, field_name)}" |
|
|
) |
|
|
elif not other_args: |
|
|
session.console.print( |
|
|
f"[info]Current value:[/info] {getattr(session.settings, field_name)}" |
|
|
) |
|
|
|
|
|
action = None |
|
|
if action_type == "toggle": |
|
|
action = _toggle |
|
|
elif action_type == "set": |
|
|
action = _set |
|
|
else: |
|
|
raise ValueError(f"Action type '{action_type}' not allowed.") |
|
|
|
|
|
bound_method = update_wrapper( |
|
|
wrapper=partial(MethodType(action, self), field=field), wrapped=action |
|
|
) |
|
|
setattr(self, f"call_{cmd_name}", bound_method) |
|
|
|