Files
OpenBB/cli/openbb_cli/models/settings.py
Danglewood 9a30186174 [V5] CLI 2.0 - Pluggable Backends, Non-TTY Default, HTTP Dispatcher, Spec Files + Codegen (#7433)
* 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>
2026-06-01 19:14:38 +03:00

213 lines
6.6 KiB
Python

"""Settings model."""
from enum import Enum
from typing import Any, Literal
from zoneinfo import available_timezones
from dotenv import dotenv_values, set_key
from openbb_core.app.version import get_package_version
from pydantic import BaseModel, ConfigDict, Field, model_validator
all_timezones = sorted(available_timezones())
from openbb_cli.config.constants import AVAILABLE_FLAIRS, ENV_FILE_SETTINGS
VERSION = get_package_version("openbb-cli")
class OutputMode(str, Enum):
"""Output mode for displaying results."""
rich = "rich"
json = "json"
tsv = "tsv"
html = "html"
class SettingGroups(Enum):
"""Setting types."""
feature_flags = "feature_flag"
preferences = "preference"
class Settings(BaseModel):
"""Settings model."""
VERSION: str = VERSION
TEST_MODE: bool = False
DEBUG_MODE: bool = False
DEV_BACKEND: bool = False
PREVIOUS_USE: bool = False
FILE_OVERWRITE: bool = Field(
default=False,
description="whether to overwrite Excel files if they already exists",
json_schema_extra={
"command": "overwrite",
"group": SettingGroups.feature_flags.value,
},
)
SHOW_VERSION: bool = Field(
default=True,
description="whether to show the version in the bottom right corner",
json_schema_extra={
"command": "version",
"group": SettingGroups.feature_flags.value,
},
)
USE_INTERACTIVE_DF: bool = Field(
default=False,
description="display tables in interactive window (when available)",
json_schema_extra={
"command": "interactive",
"group": SettingGroups.feature_flags.value,
},
)
OUTPUT_MODE: Literal["rich", "json", "tsv", "html"] = Field(
default="tsv",
description="output display mode (rich=terminal table, json=JSON, tsv=DataFrame string, html=browser)",
json_schema_extra={
"command": "output",
"group": SettingGroups.preferences.value,
},
)
USE_CLEAR_AFTER_CMD: bool = Field(
default=False,
description="clear console after each command",
json_schema_extra={
"command": "cls",
"group": SettingGroups.feature_flags.value,
},
)
USE_DATETIME: bool = Field(
default=True,
description="whether to show the date and time before the flair",
json_schema_extra={
"command": "datetime",
"group": SettingGroups.feature_flags.value,
},
)
USE_PROMPT_TOOLKIT: bool = Field(
default=True,
description="enable prompt toolkit (autocomplete and history)",
json_schema_extra={
"command": "promptkit",
"group": SettingGroups.feature_flags.value,
},
)
ENABLE_EXIT_AUTO_HELP: bool = Field(
default=True,
description="automatically print help when quitting menu",
json_schema_extra={
"command": "exithelp",
"group": SettingGroups.feature_flags.value,
},
)
ENABLE_RICH_PANEL: bool = Field(
default=True,
description="enable colorful rich CLI panel",
json_schema_extra={
"command": "richpanel",
"group": SettingGroups.feature_flags.value,
},
)
TOOLBAR_HINT: bool = Field(
default=True,
description="displays usage hints in the bottom toolbar",
json_schema_extra={
"command": "tbhint",
"group": SettingGroups.feature_flags.value,
},
)
SHOW_MSG_OBBJECT_REGISTRY: bool = Field(
default=False,
description="show obbject registry message after a new result is added",
json_schema_extra={
"command": "obbject_msg",
"group": SettingGroups.feature_flags.value,
},
)
TIMEZONE: Literal[tuple(all_timezones)] = Field( # ty: ignore[invalid-type-form]
default="America/New_York",
description="pick timezone",
json_schema_extra={
"command": "timezone",
"group": SettingGroups.preferences.value,
},
)
FLAIR: Literal[tuple(AVAILABLE_FLAIRS)] = Field( # ty: ignore[invalid-type-form]
default=":openbb",
description="choose flair icon",
json_schema_extra={
"command": "flair",
"group": SettingGroups.preferences.value,
},
)
N_TO_KEEP_OBBJECT_REGISTRY: int = Field(
default=10,
description="define the maximum number of obbjects allowed in the registry",
json_schema_extra={
"command": "obbject_res",
"group": SettingGroups.preferences.value,
},
)
N_TO_DISPLAY_OBBJECT_REGISTRY: int = Field(
default=5,
description="define the maximum number of cached results to display on the help menu",
json_schema_extra={
"command": "obbject_display",
"group": SettingGroups.preferences.value,
},
)
RICH_STYLE: str = Field(
default="dark",
description="apply a custom rich style to the CLI",
json_schema_extra={
"command": "console_style",
"group": SettingGroups.preferences.value,
},
)
ALLOWED_NUMBER_OF_ROWS: int = Field(
default=20,
description="number of rows to show in rich table mode (does not apply to json/stdio/html modes)",
json_schema_extra={
"command": "n_rows",
"group": SettingGroups.preferences.value,
},
)
ALLOWED_NUMBER_OF_COLUMNS: int = Field(
default=5,
description="number of columns to show in rich table mode (does not apply to json/stdio/html modes)",
json_schema_extra={
"command": "n_cols",
"group": SettingGroups.preferences.value,
},
)
model_config = ConfigDict(validate_assignment=True)
def __repr__(self) -> str:
"""Return a string representation of the model."""
return f"{self.__class__.__name__}\n\n" + "\n".join(
f"{k}: {v}" for k, v in self.model_dump().items()
)
@model_validator(mode="before")
@classmethod
def from_env(cls, values: dict) -> dict:
"""Load settings from .env."""
settings = {}
settings.update(dotenv_values(ENV_FILE_SETTINGS))
settings.update(values)
filtered = {k.replace("OPENBB_", ""): v for k, v in settings.items()}
return filtered
def set_item(self, key: str, value: Any) -> None:
"""Set an item in the model and save to .env."""
setattr(self, key, value)
set_key(str(ENV_FILE_SETTINGS), "OPENBB_" + key, str(value))