openbb-cli 1.3.0__tar.gz → 1.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/PKG-INFO +4 -3
  2. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/argparse_translator/argparse_translator.py +48 -75
  3. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/controllers/base_platform_controller.py +1 -1
  4. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/controllers/settings_controller.py +16 -10
  5. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/controllers/utils.py +6 -7
  6. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/models/settings.py +68 -34
  7. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/pyproject.toml +3 -3
  8. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/README.md +0 -0
  9. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/__init__.py +0 -0
  10. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/argparse_translator/__init__.py +0 -0
  11. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/argparse_translator/argparse_argument.py +0 -0
  12. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/argparse_translator/argparse_class_processor.py +0 -0
  13. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/argparse_translator/obbject_registry.py +0 -0
  14. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/argparse_translator/reference_processor.py +0 -0
  15. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/argparse_translator/utils.py +0 -0
  16. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/assets/routines/routine_example.openbb +0 -0
  17. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/assets/styles/default/Consolas.ttf +0 -0
  18. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/assets/styles/default/dark.mpfstyle.json +0 -0
  19. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/assets/styles/default/dark.mplrc.json +0 -0
  20. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/assets/styles/default/dark.mplstyle +0 -0
  21. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/assets/styles/default/dark.pltstyle.json +0 -0
  22. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/assets/styles/default/dark.richstyle.json +0 -0
  23. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/assets/styles/default/light.mpfstyle.json +0 -0
  24. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/assets/styles/default/light.mplrc.json +0 -0
  25. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/assets/styles/default/light.mplstyle +0 -0
  26. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/assets/styles/default/light.pltstyle.json +0 -0
  27. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/assets/styles/default/light.richstyle.json +0 -0
  28. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/assets/styles/default/tables.pltstyle.json +0 -0
  29. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/assets/styles/user/openbb.richstyle.json +0 -0
  30. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/cli.py +0 -0
  31. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/config/__init__.py +0 -0
  32. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/config/completer.py +0 -0
  33. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/config/console.py +0 -0
  34. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/config/constants.py +0 -0
  35. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/config/menu_text.py +0 -0
  36. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/config/setup.py +0 -0
  37. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/config/style.py +0 -0
  38. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/controllers/base_controller.py +0 -0
  39. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/controllers/choices.py +0 -0
  40. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/controllers/cli_controller.py +0 -0
  41. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/controllers/platform_controller_factory.py +0 -0
  42. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/controllers/script_parser.py +0 -0
  43. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/session.py +0 -0
  44. {openbb_cli-1.3.0 → openbb_cli-1.4.1}/openbb_cli/utils/utils.py +0 -0
@@ -1,18 +1,19 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openbb-cli
3
- Version: 1.3.0
3
+ Version: 1.4.1
4
4
  Summary: Investment Research for Everyone, Anywhere.
5
5
  License: AGPL-3.0-only
6
6
  Author: OpenBB
7
7
  Author-email: hello@openbb.co
8
- Requires-Python: >=3.10,<3.14
8
+ Requires-Python: >=3.10,<4
9
9
  Classifier: License :: OSI Approved :: GNU Affero General Public License v3
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
14
  Classifier: Programming Language :: Python :: 3.13
15
- Requires-Dist: openbb[all] (>=4.6.0,<5.0.0)
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Requires-Dist: openbb[all] (>=4.7.1,<5.0.0)
16
17
  Requires-Dist: openpyxl (>=3.1.5,<4.0.0)
17
18
  Requires-Dist: prompt-toolkit (>=3.0.50,<4.0.0)
18
19
  Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
@@ -88,6 +88,8 @@ class ArgparseTranslator:
88
88
  # check if the argument is already in use, if not, add it
89
89
  if f"--{argument.name}" not in self._parser._option_string_actions:
90
90
  kwargs = argument.model_dump(exclude={"name"}, exclude_none=True)
91
+ if "help" in kwargs:
92
+ kwargs["help"] = ArgparseTranslator._escape_help(kwargs["help"])
91
93
  group.add_argument(f"--{argument.name}", **kwargs)
92
94
  if group.title in self.provider_parameters:
93
95
  self.provider_parameters[group.title].append(argument.name)
@@ -119,8 +121,8 @@ class ArgparseTranslator:
119
121
  set_optional_choices(action, optional_choices)
120
122
  if argument.name not in self.signature.parameters:
121
123
  # update help
122
- action.help = _update_providers(
123
- action.help or "", [group.title]
124
+ action.help = ArgparseTranslator._escape_help(
125
+ _update_providers(action.help or "", [group.title])
124
126
  )
125
127
  return
126
128
 
@@ -140,7 +142,9 @@ class ArgparseTranslator:
140
142
  if choices:
141
143
  kwargs["choices"] = choices # update choices
142
144
  # add provider info to the help
143
- kwargs["help"] = _update_providers(argument.help or "", groups_w_arg)
145
+ kwargs["help"] = ArgparseTranslator._escape_help(
146
+ _update_providers(argument.help or "", groups_w_arg)
147
+ )
144
148
  action = self._parser.add_argument(f"--{argument.name}", **kwargs)
145
149
  set_optional_choices(action, optional_choices)
146
150
 
@@ -149,96 +153,65 @@ class ArgparseTranslator:
149
153
  """Get the argparse parser."""
150
154
  return deepcopy(self._parser)
151
155
 
156
+ @staticmethod
157
+ def _escape_help(text: str | None) -> str | None:
158
+ """Escape percent signs in help strings for argparse.
159
+
160
+ Python 3.14+ validates help strings at add_argument time using
161
+ %-formatting. Bare '%' characters that aren't valid format
162
+ specifiers (like '%(default)s') cause a ValueError.
163
+ """
164
+ if text is None:
165
+ return None
166
+ return text.replace("%", "%%")
167
+
152
168
  @staticmethod
153
169
  def _build_description(func_doc: str) -> str:
154
170
  """Build the description of the argparse program from the function docstring."""
155
- # Remove only the Examples section and the openbb header if present
156
- patterns_to_remove = [
157
- (r"openbb\n\s+={3,}\n", ""), # Remove openbb header
158
- (r"\n\s*Examples\n\s*-{3,}\n.*", ""), # Remove Examples section to end
159
- ]
171
+ if not func_doc:
172
+ return ""
173
+
174
+ # Remove the openbb header if present
175
+ func_doc = re.sub(r"openbb\n\s+={3,}\n", "", func_doc, flags=re.DOTALL)
160
176
 
161
- for pattern, replacement in patterns_to_remove:
162
- func_doc = re.sub(pattern, replacement, func_doc, flags=re.DOTALL)
177
+ # Senior Approach: The main description should only be the summary.
178
+ # Sections like Parameters, Returns, and Examples are handled by argparse or are redundant.
179
+ for section in ["Parameters", "Returns", "Examples", "Raises"]:
180
+ pattern = rf"\n\s*{section}\n\s*-{{3,}}\n.*"
181
+ func_doc = re.sub(pattern, "", func_doc, flags=re.DOTALL | re.IGNORECASE)
163
182
 
164
- # Clean up type annotations in docstrings
183
+ # Clean up any remaining type-style annotations in the summary
165
184
  def clean_type_annotation(type_str: str) -> str:
166
- """Clean up a single type annotation."""
167
- # First, handle the pipe union syntax: type1 | type2 -> type1 or type2
168
- # Do this FIRST before other transformations
185
+ """Clean up type annotations for human readability."""
186
+ # Handle pipe unions: int | str -> int or str
169
187
  type_str = re.sub(r"\s*\|\s*", " or ", type_str)
170
-
171
188
  # Handle Annotated[type, ...] -> type
172
- type_str = re.sub(r"Annotated\[([^,\]]+)(?:,\s*[^\]]+)?\]", r"\1", type_str)
173
-
174
- # Handle Union[type1, type2, ...] -> type1 or type2 or ...
189
+ type_str = re.sub(r"Annotated\[\s*([^,\]]+).*?\]", r"\1", type_str)
190
+ # Handle Union[A, B] -> A or B
175
191
  type_str = re.sub(
176
- r"Union\[([^\]]+)\]",
177
- lambda m: " or ".join(m.group(1).split(", ")),
192
+ r"Union\[\s*(.*?)\s*\]",
193
+ lambda m: m.group(1).replace(", ", " or "),
178
194
  type_str,
179
195
  )
196
+ # Handle Optional[A] -> A or None
197
+ type_str = re.sub(r"Optional\[\s*(.*?)\s*\]", r"\1 or None", type_str)
180
198
 
181
- # Handle Optional[type] -> type or None
182
- type_str = re.sub(r"Optional\[([^\]]+)\]", r"\1 or None", type_str)
183
-
184
- # Deduplicate "or" separated types
185
- parts = [p.strip() for p in type_str.split(" or ")]
199
+ return type_str.strip()
186
200
 
187
- # Remove duplicates while preserving order (case-insensitive)
188
- seen = set()
189
- unique_parts = []
190
- for part in parts:
191
- part_lower = part.lower()
192
- if part_lower not in seen:
193
- seen.add(part_lower)
194
- unique_parts.append(part)
195
-
196
- # If None is present, move it to the end
197
- if "None" in unique_parts:
198
- unique_parts.remove("None")
199
- unique_parts.append("None")
200
-
201
- type_str = " or ".join(unique_parts)
202
-
203
- return type_str
204
-
205
- # Process each line that contains a type annotation (format: "name : type")
206
201
  lines = func_doc.split("\n")
207
202
  cleaned_lines = []
208
-
209
203
  for line in lines:
210
- # Match lines with type annotations (parameter_name : type_annotation)
204
+ # If a line still looks like a parameter definition (e.g. "param : type"), clean it
211
205
  if ":" in line and not line.strip().startswith("#"):
212
- # Split only on the first colon to preserve any colons in the description
213
206
  parts = line.split(":", 1)
214
- if len(parts) == 2:
215
- param_name = parts[0]
216
- rest = parts[1].strip()
217
-
218
- # Extract the type part (everything before the first real description line)
219
- # Type annotations typically don't contain spaces at the start of continuation lines
220
- type_match = re.match(r"^([^\n]+?)(?:\n\s{4,}|\s{2,}|$)", rest)
221
- if type_match:
222
- type_part = type_match.group(1).strip()
223
- description_part = rest[len(type_match.group(1)) :]
224
-
225
- # Clean the type annotation
226
- cleaned_type = clean_type_annotation(type_part)
227
-
228
- # Reconstruct the line
229
- if description_part:
230
- cleaned_lines.append(
231
- f"{param_name}: {cleaned_type}{description_part}"
232
- )
233
- else:
234
- cleaned_lines.append(f"{param_name}: {cleaned_type}")
235
- continue
236
-
237
- cleaned_lines.append(line)
238
-
239
- func_doc = "\n".join(cleaned_lines)
207
+ param_name = parts[0]
208
+ type_info = parts[1].strip()
209
+ cleaned_type = clean_type_annotation(type_info)
210
+ cleaned_lines.append(f"{param_name}: {cleaned_type}")
211
+ else:
212
+ cleaned_lines.append(line)
240
213
 
241
- return func_doc.strip()
214
+ return "\n".join(cleaned_lines).strip()
242
215
 
243
216
  @staticmethod
244
217
  def _param_is_default(param: inspect.Parameter) -> bool:
@@ -448,7 +421,7 @@ class ArgparseTranslator:
448
421
  default=param.default,
449
422
  required=required,
450
423
  action=action,
451
- help=self._get_argument_custom_help(param),
424
+ help=self._escape_help(self._get_argument_custom_help(param)),
452
425
  nargs=self._get_nargs(param),
453
426
  choices=choices,
454
427
  )
@@ -236,7 +236,7 @@ class PlatformController(BaseController):
236
236
  if not export:
237
237
  obbject.show()
238
238
  elif session.settings.USE_INTERACTIVE_DF and not export:
239
- obbject.charting.table()
239
+ obbject.charting.table() # type: ignore[attr-defined]
240
240
  else:
241
241
  if isinstance(df.columns, pd.RangeIndex):
242
242
  df.columns = [str(i) for i in df.columns]
@@ -3,7 +3,7 @@
3
3
  import argparse
4
4
  from functools import partial, update_wrapper
5
5
  from types import MethodType
6
- from typing import Literal, get_origin
6
+ from typing import Any, Literal, cast, get_origin
7
7
 
8
8
  from openbb_cli.config.menu_text import MenuText
9
9
  from openbb_cli.controllers.base_controller import BaseController
@@ -13,20 +13,26 @@ from openbb_cli.session import Session
13
13
  session = Session()
14
14
 
15
15
 
16
+ def _get_extra(field: Any) -> dict[str, Any]:
17
+ """Safely extract json_schema_extra as a dict."""
18
+ extra = field.json_schema_extra
19
+ return cast(dict[str, Any], extra) if isinstance(extra, dict) else {}
20
+
21
+
16
22
  class SettingsController(BaseController):
17
23
  """Settings Controller class."""
18
24
 
19
- _COMMANDS = {
20
- v.json_schema_extra.get("command"): {
21
- "command": (v.json_schema_extra or {}).get("command"),
22
- "group": (v.json_schema_extra or {}).get("group"),
25
+ _COMMANDS: dict[str, dict[str, Any]] = {
26
+ _get_extra(v).get("command", ""): {
27
+ "command": _get_extra(v).get("command"),
28
+ "group": _get_extra(v).get("group"),
23
29
  "description": v.description,
24
30
  "annotation": v.annotation,
25
31
  "field_name": k,
26
32
  }
27
33
  for k, v in sorted(
28
34
  session.settings.model_fields.items(),
29
- key=lambda item: (item[1].json_schema_extra or {}).get("command", ""),
35
+ key=lambda item: _get_extra(item[1]).get("command", ""),
30
36
  )
31
37
  if v.json_schema_extra
32
38
  }
@@ -39,9 +45,9 @@ class SettingsController(BaseController):
39
45
  super().__init__(queue)
40
46
  for cmd, field in self._COMMANDS.items():
41
47
  group = field.get("group")
42
- if group == SettingGroups.feature_flags:
48
+ if group == SettingGroups.feature_flags.value:
43
49
  self._generate_command(cmd, field, "toggle")
44
- elif group == SettingGroups.preferences:
50
+ elif group == SettingGroups.preferences.value:
45
51
  self._generate_command(cmd, field, "set")
46
52
  self.update_completer(self.choices_default)
47
53
 
@@ -50,7 +56,7 @@ class SettingsController(BaseController):
50
56
  mt = MenuText("settings/")
51
57
  mt.add_info("Feature Flags")
52
58
  for k, f in self._COMMANDS.items():
53
- if f.get("group") == SettingGroups.feature_flags:
59
+ if f.get("group") == SettingGroups.feature_flags.value:
54
60
  mt.add_setting(
55
61
  name=k,
56
62
  status=getattr(session.settings, f["field_name"]),
@@ -59,7 +65,7 @@ class SettingsController(BaseController):
59
65
  mt.add_raw("\n")
60
66
  mt.add_info("Preferences")
61
67
  for k, f in self._COMMANDS.items():
62
- if f.get("group") == SettingGroups.preferences:
68
+ if f.get("group") == SettingGroups.preferences.value:
63
69
  mt.add_cmd(
64
70
  name=k,
65
71
  description=f["description"],
@@ -1,6 +1,7 @@
1
1
  """Utils."""
2
2
 
3
3
  import argparse
4
+ import ast
4
5
  import os
5
6
  import random
6
7
  import re
@@ -379,7 +380,7 @@ def print_rich_table( # noqa: PLR0912
379
380
  )
380
381
 
381
382
  if columns_to_auto_color is None and rows_to_auto_color is None:
382
- df = df.applymap(lambda x: return_colored_value(str(x))) # type: ignore
383
+ df = df.map(lambda x: return_colored_value(str(x))) # type: ignore
383
384
 
384
385
  exceeds_allowed_columns = len(df.columns) > MAX_COLS
385
386
  exceeds_allowed_rows = len(df) > MAX_ROWS
@@ -920,13 +921,11 @@ def parse_unknown_args_to_dict(unknown_args: list[str] | None) -> dict[str, str]
920
921
  if arg.startswith("--"):
921
922
  if idx + 1 < len(unknown_args):
922
923
  try:
923
- unknown_args_dict[arg.replace("--", "")] = (
924
- eval( # noqa: S307, E501 pylint: disable=eval-used
925
- unknown_args[idx + 1]
926
- )
924
+ unknown_args_dict[arg.replace("--", "")] = ast.literal_eval(
925
+ unknown_args[idx + 1]
927
926
  )
928
- except Exception:
929
- unknown_args_dict[arg] = unknown_args[idx + 1]
927
+ except (ValueError, SyntaxError):
928
+ unknown_args_dict[arg.replace("--", "")] = unknown_args[idx + 1]
930
929
  else:
931
930
  session.console.print(
932
931
  f"Missing value for argument {arg}. Skipping this argument."
@@ -41,106 +41,140 @@ class Settings(BaseModel):
41
41
  FILE_OVERWRITE: bool = Field(
42
42
  default=False,
43
43
  description="whether to overwrite Excel files if they already exists",
44
- command="overwrite",
45
- group=SettingGroups.feature_flags,
44
+ json_schema_extra={
45
+ "command": "overwrite",
46
+ "group": SettingGroups.feature_flags.value,
47
+ },
46
48
  )
47
49
  SHOW_VERSION: bool = Field(
48
50
  default=True,
49
51
  description="whether to show the version in the bottom right corner",
50
- command="version",
51
- group=SettingGroups.feature_flags,
52
+ json_schema_extra={
53
+ "command": "version",
54
+ "group": SettingGroups.feature_flags.value,
55
+ },
52
56
  )
53
57
  USE_INTERACTIVE_DF: bool = Field(
54
58
  default=True,
55
59
  description="display tables in interactive window",
56
- command="interactive",
57
- group=SettingGroups.feature_flags,
60
+ json_schema_extra={
61
+ "command": "interactive",
62
+ "group": SettingGroups.feature_flags.value,
63
+ },
58
64
  )
59
65
  USE_CLEAR_AFTER_CMD: bool = Field(
60
66
  default=False,
61
67
  description="clear console after each command",
62
- command="cls",
63
- group=SettingGroups.feature_flags,
68
+ json_schema_extra={
69
+ "command": "cls",
70
+ "group": SettingGroups.feature_flags.value,
71
+ },
64
72
  )
65
73
  USE_DATETIME: bool = Field(
66
74
  default=True,
67
75
  description="whether to show the date and time before the flair",
68
- command="datetime",
69
- group=SettingGroups.feature_flags,
76
+ json_schema_extra={
77
+ "command": "datetime",
78
+ "group": SettingGroups.feature_flags.value,
79
+ },
70
80
  )
71
81
  USE_PROMPT_TOOLKIT: bool = Field(
72
82
  default=True,
73
83
  description="enable prompt toolkit (autocomplete and history)",
74
- command="promptkit",
75
- group=SettingGroups.feature_flags,
84
+ json_schema_extra={
85
+ "command": "promptkit",
86
+ "group": SettingGroups.feature_flags.value,
87
+ },
76
88
  )
77
89
  ENABLE_EXIT_AUTO_HELP: bool = Field(
78
90
  default=True,
79
91
  description="automatically print help when quitting menu",
80
- command="exithelp",
81
- group=SettingGroups.feature_flags,
92
+ json_schema_extra={
93
+ "command": "exithelp",
94
+ "group": SettingGroups.feature_flags.value,
95
+ },
82
96
  )
83
97
  ENABLE_RICH_PANEL: bool = Field(
84
98
  default=True,
85
99
  description="enable colorful rich CLI panel",
86
- command="richpanel",
87
- group=SettingGroups.feature_flags,
100
+ json_schema_extra={
101
+ "command": "richpanel",
102
+ "group": SettingGroups.feature_flags.value,
103
+ },
88
104
  )
89
105
  TOOLBAR_HINT: bool = Field(
90
106
  default=True,
91
107
  description="displays usage hints in the bottom toolbar",
92
- command="tbhint",
93
- group=SettingGroups.feature_flags,
108
+ json_schema_extra={
109
+ "command": "tbhint",
110
+ "group": SettingGroups.feature_flags.value,
111
+ },
94
112
  )
95
113
  SHOW_MSG_OBBJECT_REGISTRY: bool = Field(
96
114
  default=False,
97
115
  description="show obbject registry message after a new result is added",
98
- command="obbject_msg",
99
- group=SettingGroups.feature_flags,
116
+ json_schema_extra={
117
+ "command": "obbject_msg",
118
+ "group": SettingGroups.feature_flags.value,
119
+ },
100
120
  )
101
121
 
102
122
  # PREFERENCES
103
123
  TIMEZONE: Literal[tuple(all_timezones)] = Field( # type: ignore[valid-type]
104
124
  default="America/New_York",
105
125
  description="pick timezone",
106
- command="timezone",
107
- group=SettingGroups.preferences,
126
+ json_schema_extra={
127
+ "command": "timezone",
128
+ "group": SettingGroups.preferences.value,
129
+ },
108
130
  )
109
131
  FLAIR: Literal[tuple(AVAILABLE_FLAIRS)] = Field( # type: ignore[valid-type]
110
132
  default=":openbb",
111
133
  description="choose flair icon",
112
- command="flair",
113
- group=SettingGroups.preferences,
134
+ json_schema_extra={
135
+ "command": "flair",
136
+ "group": SettingGroups.preferences.value,
137
+ },
114
138
  )
115
139
  N_TO_KEEP_OBBJECT_REGISTRY: int = Field(
116
140
  default=10,
117
141
  description="define the maximum number of obbjects allowed in the registry",
118
- command="obbject_res",
119
- group=SettingGroups.preferences,
142
+ json_schema_extra={
143
+ "command": "obbject_res",
144
+ "group": SettingGroups.preferences.value,
145
+ },
120
146
  )
121
147
  N_TO_DISPLAY_OBBJECT_REGISTRY: int = Field(
122
148
  default=5,
123
149
  description="define the maximum number of cached results to display on the help menu",
124
- command="obbject_display",
125
- group=SettingGroups.preferences,
150
+ json_schema_extra={
151
+ "command": "obbject_display",
152
+ "group": SettingGroups.preferences.value,
153
+ },
126
154
  )
127
155
  RICH_STYLE: str = Field(
128
156
  default="dark",
129
157
  description="apply a custom rich style to the CLI",
130
- command="console_style",
131
- group=SettingGroups.preferences,
158
+ json_schema_extra={
159
+ "command": "console_style",
160
+ "group": SettingGroups.preferences.value,
161
+ },
132
162
  )
133
163
  ALLOWED_NUMBER_OF_ROWS: int = Field(
134
164
  default=20,
135
165
  description="number of rows to show (when not using interactive tables).",
136
- command="n_rows",
137
- group=SettingGroups.preferences,
166
+ json_schema_extra={
167
+ "command": "n_rows",
168
+ "group": SettingGroups.preferences.value,
169
+ },
138
170
  )
139
171
  ALLOWED_NUMBER_OF_COLUMNS: int = Field(
140
172
  default=5,
141
173
  description="number of columns to show (when not using interactive tables).",
142
- command="n_cols",
143
- group=SettingGroups.preferences,
174
+ json_schema_extra={
175
+ "command": "n_cols",
176
+ "group": SettingGroups.preferences.value,
177
+ },
144
178
  )
145
179
 
146
180
  model_config = ConfigDict(validate_assignment=True)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "openbb-cli"
3
- version = "1.3.0"
3
+ version = "1.4.1"
4
4
  description = "Investment Research for Everyone, Anywhere."
5
5
  authors = ["OpenBB <hello@openbb.co>"]
6
6
  packages = [{ include = "openbb_cli" }]
@@ -14,10 +14,10 @@ documentation = "https://docs.openbb.co/cli"
14
14
  openbb = 'openbb_cli.cli:main'
15
15
 
16
16
  [tool.poetry.dependencies]
17
- python = "^3.10,<3.14"
17
+ python = ">=3.10,<4"
18
18
 
19
19
  # OpenBB dependencies
20
- openbb = { version = "^4.6.0", extras = ["all"] }
20
+ openbb = { version = "^4.7.1", extras = ["all"] }
21
21
 
22
22
  # CLI dependencies
23
23
  prompt-toolkit = "^3.0.50"
File without changes
File without changes