summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormontezdesousa <79287829+montezdesousa@users.noreply.github.com>2024-05-03 11:36:29 +0100
committerGitHub <noreply@github.com>2024-05-03 11:36:29 +0100
commitbf62333041a7f5e030ac996a11cedaf2f4e03a75 (patch)
tree88da700afd75eaecfdd06b60d90fe34291beed4a
parent152955546a995f4ae548d708f922f4c9c3edef8f (diff)
parentcd4e36e7fe90c72337d13c2db3af7c140e2531dd (diff)
Merge branch 'develop' into bugfix/sec-remote-disconnectbugfix/sec-remote-disconnect
-rw-r--r--cli/openbb_cli/config/completer.py24
-rw-r--r--cli/openbb_cli/config/constants.py2
-rw-r--r--cli/openbb_cli/config/menu_text.py194
-rw-r--r--cli/openbb_cli/controllers/cli_controller.py2
-rw-r--r--cli/openbb_cli/models/settings.py18
-rw-r--r--cli/openbb_cli/session.py4
-rw-r--r--cli/pyproject.toml1
7 files changed, 79 insertions, 166 deletions
diff --git a/cli/openbb_cli/config/completer.py b/cli/openbb_cli/config/completer.py
index f084c821478..9cc50a9b7eb 100644
--- a/cli/openbb_cli/config/completer.py
+++ b/cli/openbb_cli/config/completer.py
@@ -16,6 +16,7 @@ from typing import (
from prompt_toolkit.completion import CompleteEvent, Completer, Completion
from prompt_toolkit.document import Document
from prompt_toolkit.formatted_text import AnyFormattedText
+from prompt_toolkit.history import FileHistory
NestedDict = Mapping[str, Union[Any, Set[str], None, Completer]]
@@ -401,3 +402,26 @@ class NestedCompleter(Completer):
# This is a WordCompleter
yield from completer.get_completions(document, complete_event)
+
+
+class CustomFileHistory(FileHistory):
+ """Filtered file history."""
+
+ def sanitize_input(self, string: str) -> str:
+ """Sanitize sensitive information from the input string by parsing arguments."""
+ keywords = ["--password", "--email", "--pat"]
+ string_list = string.split(" ")
+
+ for kw in keywords:
+ if kw in string_list:
+ index = string_list.index(kw)
+ if len(string_list) > index + 1:
+ string_list[index + 1] = "********"
+
+ result = " ".join(string_list)
+ return result
+
+ def store_string(self, string: str) -> None:
+ """Store string in history."""
+ string = self.sanitize_input(string)
+ super().store_string(string)
diff --git a/cli/openbb_cli/config/constants.py b/cli/openbb_cli/config/constants.py
index c44150324f3..b5b8867a243 100644
--- a/cli/openbb_cli/config/constants.py
+++ b/cli/openbb_cli/config/constants.py
@@ -9,8 +9,6 @@ SRC_DIRECTORY = Path(__file__).parent.parent
SETTINGS_DIRECTORY = HOME_DIRECTORY / ".openbb_platform"
ASSETS_DIRECTORY = SRC_DIRECTORY / "assets"
STYLES_DIRECTORY = ASSETS_DIRECTORY / "styles"
-ENV_FILE_REPOSITORY = REPOSITORY_DIRECTORY / ".env"
-ENV_FILE_PROJECT = REPOSITORY_DIRECTORY / "openbb_cli" / ".env"
ENV_FILE_SETTINGS = SETTINGS_DIRECTORY / ".cli.env"
HIST_FILE_PROMPT = SETTINGS_DIRECTORY / ".cli.his"
I18N_FILE = ASSETS_DIRECTORY / "i18n"
diff --git a/cli/openbb_cli/config/menu_text.py b/cli/openbb_cli/config/menu_text.py
index d9bdc59656c..56e2034998c 100644
--- a/cli/openbb_cli/config/menu_text.py
+++ b/cli/openbb_cli/config/menu_text.py
@@ -26,28 +26,6 @@ RICH_TAGS = [
"[/help]",
]
-USE_COLOR = True
-
-
-def get_ordered_providers(command_path: str) -> List:
- """Return the preferred provider for the given command.
-
- Parameters
- ----------
- command_path: str
- The command to find the provider for. E.g. "/equity/price/historical
-
- Returns
- -------
- List
- The list of providers for the given command.
- """
- command_reference = obb.reference.get("paths", {}).get(command_path, {}) # type: ignore
- if command_reference:
- providers = list(command_reference["parameters"].keys())
- return [provider for provider in providers if provider != "standard"]
- return []
-
class MenuText:
"""Create menu text with rich colors to be displayed by CLI."""
@@ -58,82 +36,33 @@ class MenuText:
SECTION_SPACING = 4
def __init__(self, path: str = ""):
- """Initialize menu help.
-
- Parameters
- ----------
- path : str
- path to the menu that is being created
- column_sources : int
- column width from which to start displaying sources
- """
+ """Initialize menu help."""
self.menu_text = ""
self.menu_path = path
self.warnings: List[Dict[str, str]] = []
- def add_raw(self, raw_text: str):
- """Append raw text (no translation) to a menu.
-
- Parameters
- ----------
- raw_text : str
- raw text to be appended to the menu
- """
- self.menu_text += raw_text
-
- def add_custom(self, key: str):
- """Append custom text (after translation from key) to a menu.
-
- Parameters
- ----------
- key : str
- key to get translated text and add to the menu
- """
- self.menu_text += f"{i18n.t(self.menu_path + key)}"
-
- def add_info(self, key_info: str):
- """Append info text (after translation from key) to a menu.
-
- Parameters
- ----------
- key_info : str
- key to get translated text and add to the menu as info
- """
- self.menu_text += f"[info]{i18n.t(self.menu_path + key_info)}:[/info]\n"
-
- def add_param(self, key_param: str, value: str, col_align: int = 0):
- """Append info text (after translation from key) to a menu.
-
- Parameters
- ----------
- key_param : str
- key to get translated text and add to the menu as parameter
- value : str
- value to display in front of the parameter
- col_align : int
- column alignment for the value. This allows for a better UX experience.
- """
- parameter_translated = i18n.t(self.menu_path + key_param)
- space = (
- (col_align - len(parameter_translated)) * " "
- if col_align > len(parameter_translated)
- else ""
- )
- self.menu_text += f"[param]{parameter_translated}{space}:[/param] {value}\n"
-
- def _format_cmd_name(self, name: str) -> str:
- """Adjust the length of the command if it is too long.
+ @staticmethod
+ def _get_providers(command_path: str) -> List:
+ """Return the preferred provider for the given command.
Parameters
----------
- name : str
- command to be formatted
+ command_path: str
+ The command to find the provider for. E.g. "/equity/price/historical
Returns
-------
- str
- formatted command
+ List
+ The list of providers for the given command.
"""
+ command_reference = obb.reference.get("paths", {}).get(command_path, {}) # type: ignore
+ if command_reference:
+ providers = list(command_reference["parameters"].keys())
+ return [provider for provider in providers if provider != "standard"]
+ return []
+
+ def _format_cmd_name(self, name: str) -> str:
+ """Truncate command name length if it is too long."""
if len(name) > self.CMD_NAME_LENGTH:
new_name = name[
: self.CMD_NAME_LENGTH
@@ -164,22 +93,7 @@ class MenuText:
def _format_cmd_description(
self, name: str, description: str, trim: bool = True
) -> str:
- """Handle the command description.
-
- Parameters
- ----------
- name : str
- command to be adjusted
- description : str
- description of the command
- trim : bool
- If true, the description will be trimmed to the maximum length
-
- Returns
- -------
- str
- adjusted command description
- """
+ """Truncate command description length if it is too long."""
if not description:
description = i18n.t(self.menu_path + name)
if description == self.menu_path + name:
@@ -190,21 +104,33 @@ class MenuText:
else description
)
- def add_cmd(self, name: str, description: str = "", disable: bool = False):
- """Append command text (after translation from key) to a menu.
+ def add_raw(self, text: str):
+ """Append raw text (without translation)."""
+ self.menu_text += text
- Parameters
- ----------
- name : str
- key command to be executed by user. It is also used as a key to get description of command.
- description : str
- description of the command
- disable : bool
- If disable is true, the command line is greyed out.
- """
+ def add_custom(self, name: str):
+ """Append custom text (after translation)."""
+ self.menu_text += f"{i18n.t(self.menu_path + name)}"
+
+ def add_info(self, text: str):
+ """Append information text (after translation)."""
+ self.menu_text += f"[info]{i18n.t(self.menu_path + text)}:[/info]\n"
+
+ def add_param(self, name: str, value: str, col_align: int = 0):
+ """Append parameter (after translation)."""
+ parameter_translated = i18n.t(self.menu_path + name)
+ space = (
+ (col_align - len(parameter_translated)) * " "
+ if col_align > len(parameter_translated)
+ else ""
+ )
+ self.menu_text += f"[param]{parameter_translated}{space}:[/param] {value}\n"
+
+ def add_cmd(self, name: str, description: str = "", disable: bool = False):
+ """Append command text (after translation)."""
formatted_name = self._format_cmd_name(name)
name_padding = (self.CMD_NAME_LENGTH - len(formatted_name)) * " "
- providers = get_ordered_providers(f"{self.menu_path}{formatted_name}")
+ providers = self._get_providers(f"{self.menu_path}{name}")
formatted_description = self._format_cmd_description(
formatted_name,
description,
@@ -231,43 +157,21 @@ class MenuText:
description: str = "",
disable: bool = False,
):
- """Append menu text (after translation from key) to a menu.
-
- Parameters
- ----------
- name : str
- key menu to be executed by user. It is also used as a key to get description of menu.
- disable : bool
- If disable is true, the menu line is greyed out.
- """
+ """Append menu text (after translation)."""
spacing = (self.CMD_NAME_LENGTH - len(name) + self.SECTION_SPACING) * " "
- if description:
- menu = f"{name}{spacing}{description}"
- else:
+ if not description:
description = i18n.t(self.menu_path + name)
if description == self.menu_path + name:
description = ""
- menu = f"{name}{spacing}{description}"
- if disable:
- self.menu_text += f"[unvl]> {menu}[/unvl]\n"
- else:
- self.menu_text += f"[menu]> {menu}[/menu]\n"
+ menu = f"{name}{spacing}{description}"
+ tag = "unvl" if disable else "menu"
+ self.menu_text += f"[{tag}]> {menu}[/{tag}]\n"
def add_setting(self, name: str, status: bool = True):
- """Append menu text (after translation from key) to a menu.
-
- Parameters
- ----------
- name : str
- key setting to be set by user. It is also used as a key to get description of the setting.
- status : bool
- status of the current setting. If true the line will be green, otherwise red.
- """
+ """Append menu text (after translation)."""
spacing = (self.CMD_NAME_LENGTH - len(name) + self.SECTION_SPACING) * " "
indentation = self.SECTION_SPACING * " "
- if status:
- self.menu_text += f"[green]{indentation}{name}{spacing}{i18n.t(self.menu_path + name)}[/green]\n"
- else:
- self.menu_text += f"[red]{indentation}{name}{spacing}{i18n.t(self.menu_path + name)}[/red]\n"
+ color = "green" if status else "red"
+ self.menu_text += f"[{color}]{indentation}{name}{spacing}{i18n.t(self.menu_path + name)}[/{color}]\n"
diff --git a/cli/openbb_cli/controllers/cli_controller.py b/cli/openbb_cli/controllers/cli_controller.py
index 8c79ae6f842..e82a5dbdfc0 100644
--- a/cli/openbb_cli/controllers/cli_controller.py
+++ b/cli/openbb_cli/controllers/cli_controller.py
@@ -128,6 +128,8 @@ class CLIController(BaseController):
"""Call command."""
mdl = getattr(obb, router)
df = pd.DataFrame.from_dict(mdl.model_dump(), orient="index")
+ if isinstance(df.columns, pd.RangeIndex):
+ df.columns = [str(i) for i in df.columns]
return print_rich_table(df, show_index=True)
for router, value in PLATFORM_ROUTERS.items():
diff --git a/cli/openbb_cli/models/settings.py b/cli/openbb_cli/models/settings.py
index f83bca01ab3..754b122034c 100644
--- a/cli/openbb_cli/models/settings.py
+++ b/cli/openbb_cli/models/settings.py
@@ -3,11 +3,7 @@
from typing import Any
from dotenv import dotenv_values, set_key
-from openbb_cli.config.constants import (
- ENV_FILE_PROJECT,
- ENV_FILE_REPOSITORY,
- ENV_FILE_SETTINGS,
-)
+from openbb_cli.config.constants import ENV_FILE_SETTINGS
from pydantic import BaseModel, ConfigDict, model_validator
@@ -62,16 +58,8 @@ class Settings(BaseModel):
@model_validator(mode="before")
@classmethod
def from_env(cls, values: dict) -> dict:
- """Load .env files.
-
- Loads the dotenv files in the following order:
- 1. Repository .env file
- 2. Package .env file
- 3. User .env file
- """
+ """Load settings from .env."""
settings = {}
- settings.update(dotenv_values(ENV_FILE_REPOSITORY))
- settings.update(dotenv_values(ENV_FILE_PROJECT))
settings.update(dotenv_values(ENV_FILE_SETTINGS))
settings.update(values)
filtered = {k.replace("OPENBB_", ""): v for k, v in settings.items()}
@@ -79,7 +67,5 @@ class Settings(BaseModel):
def set_item(self, key: str, value: Any) -> None:
"""Set an item in the model and save to .env."""
- # TODO: Check if this is ok, we are just saving into the settings .env
- # Same behavior as before...
setattr(self, key, value)
set_key(str(ENV_FILE_SETTINGS), "OPENBB_" + key, str(value))
diff --git a/cli/openbb_cli/session.py b/cli/openbb_cli/session.py
index 96b63f10da9..ef63fd6e7f0 100644
--- a/cli/openbb_cli/session.py
+++ b/cli/openbb_cli/session.py
@@ -8,8 +8,8 @@ from openbb import obb
from openbb_core.app.model.abstract.singleton import SingletonMeta
from openbb_core.app.model.user_settings import UserSettings as User
from prompt_toolkit import PromptSession
-from prompt_toolkit.history import FileHistory
+from openbb_cli.config.completer import CustomFileHistory
from openbb_cli.config.console import Console
from openbb_cli.config.constants import HIST_FILE_PROMPT
from openbb_cli.config.style import Style
@@ -62,7 +62,7 @@ class Session(metaclass=SingletonMeta):
try:
if sys.stdin.isatty():
prompt_session: Optional[PromptSession] = PromptSession(
- history=FileHistory(str(HIST_FILE_PROMPT))
+ history=CustomFileHistory(str(HIST_FILE_PROMPT))
)
else:
prompt_session = None
diff --git a/cli/pyproject.toml b/cli/pyproject.toml
index 3ef0d94a897..93d8ab34a93 100644
--- a/cli/pyproject.toml
+++ b/cli/pyproject.toml
@@ -5,7 +5,6 @@ description = "Investment Research for Everyone, Anywhere."
license = "MIT"
authors = ["OpenBB <hello@openbb.co>"]
packages = [{ include = "openbb_cli" }]
-include = ["cli/.env"]
readme = "README.md"
homepage = "https://openbb.co"
repository = "https://github.com/OpenBB-finance/OpenBBTerminal"