openbb-cli 1.0.4__tar.gz → 1.1.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 (45) hide show
  1. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/PKG-INFO +9 -7
  2. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/README.md +2 -2
  3. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/argparse_translator.py +7 -5
  4. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/config/menu_text.py +2 -2
  5. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/base_controller.py +52 -41
  6. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/base_platform_controller.py +3 -3
  7. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/choices.py +4 -3
  8. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/cli_controller.py +2 -1
  9. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/settings_controller.py +2 -2
  10. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/utils.py +79 -23
  11. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/session.py +19 -0
  12. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/pyproject.toml +7 -6
  13. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/__init__.py +0 -0
  14. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/__init__.py +0 -0
  15. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/argparse_argument.py +0 -0
  16. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/argparse_class_processor.py +0 -0
  17. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/obbject_registry.py +0 -0
  18. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/reference_processor.py +0 -0
  19. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/utils.py +0 -0
  20. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/routines/routine_example.openbb +0 -0
  21. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/Consolas.ttf +0 -0
  22. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/dark.mpfstyle.json +0 -0
  23. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/dark.mplrc.json +0 -0
  24. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/dark.mplstyle +0 -0
  25. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/dark.pltstyle.json +0 -0
  26. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/dark.richstyle.json +0 -0
  27. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/light.mpfstyle.json +0 -0
  28. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/light.mplrc.json +0 -0
  29. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/light.mplstyle +0 -0
  30. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/light.pltstyle.json +0 -0
  31. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/light.richstyle.json +0 -0
  32. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/tables.pltstyle.json +0 -0
  33. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/user/openbb.richstyle.json +0 -0
  34. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/cli.py +0 -0
  35. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/config/__init__.py +0 -0
  36. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/config/completer.py +0 -0
  37. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/config/console.py +0 -0
  38. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/config/constants.py +0 -0
  39. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/config/setup.py +0 -0
  40. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/config/style.py +0 -0
  41. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/hub_service.py +0 -0
  42. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/platform_controller_factory.py +0 -0
  43. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/script_parser.py +0 -0
  44. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/models/settings.py +0 -0
  45. {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/utils/utils.py +0 -0
@@ -1,30 +1,32 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openbb-cli
3
- Version: 1.0.4
3
+ Version: 1.1.1
4
4
  Summary: Investment Research for Everyone, Anywhere.
5
5
  Home-page: https://openbb.co
6
6
  License: AGPL-3.0-only
7
7
  Author: OpenBB
8
8
  Author-email: hello@openbb.co
9
- Requires-Python: >=3.8.1,<3.12
9
+ Requires-Python: >=3.9,<3.13
10
10
  Classifier: License :: OSI Approved :: GNU Affero General Public License v3
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.9
13
13
  Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
- Requires-Dist: openbb[all] (>=4.2.3,<5.0.0)
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Requires-Dist: openbb[all] (>=4.3.1,<5.0.0)
16
17
  Requires-Dist: openpyxl (>=3.1.2,<4.0.0)
17
18
  Requires-Dist: prompt-toolkit (>=3.0.16,<4.0.0)
18
19
  Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
20
+ Requires-Dist: pywry (>=0.6.2,<0.7.0)
19
21
  Requires-Dist: rich (>=13,<14)
20
- Project-URL: Documentation, https://docs.openbb.co/terminal
21
- Project-URL: Repository, https://github.com/OpenBB-finance/OpenBBTerminal
22
+ Project-URL: Documentation, https://docs.openbb.co/cli
23
+ Project-URL: Repository, https://github.com/OpenBB-finance/OpenBB
22
24
  Description-Content-Type: text/markdown
23
25
 
24
26
  # OpenBB Platform CLI
25
27
 
26
28
  [![Downloads](https://static.pepy.tech/badge/openbb)](https://pepy.tech/project/openbb)
27
- [![LatestRelease](https://badge.fury.io/py/openbb.svg)](https://github.com/OpenBB-finance/OpenBBTerminal)
29
+ [![LatestRelease](https://badge.fury.io/py/openbb.svg)](https://github.com/OpenBB-finance/OpenBB)
28
30
 
29
31
  | OpenBB is committed to build the future of investment research by focusing on an open source infrastructure accessible to everyone, everywhere. |
30
32
  | :---------------------------------------------------------------------------------------------------------------------------------------------: |
@@ -57,7 +59,7 @@ openbb
57
59
 
58
60
  Which should result in the following output:
59
61
 
60
- ![image](https://github.com/OpenBB-finance/OpenBBTerminal/assets/48914296/f606bb6e-fa00-4fc8-bad2-8269bb4fc38e)
62
+ ![image](https://github.com/OpenBB-finance/OpenBB/assets/48914296/f606bb6e-fa00-4fc8-bad2-8269bb4fc38e)
61
63
 
62
64
  ## API keys
63
65
 
@@ -1,7 +1,7 @@
1
1
  # OpenBB Platform CLI
2
2
 
3
3
  [![Downloads](https://static.pepy.tech/badge/openbb)](https://pepy.tech/project/openbb)
4
- [![LatestRelease](https://badge.fury.io/py/openbb.svg)](https://github.com/OpenBB-finance/OpenBBTerminal)
4
+ [![LatestRelease](https://badge.fury.io/py/openbb.svg)](https://github.com/OpenBB-finance/OpenBB)
5
5
 
6
6
  | OpenBB is committed to build the future of investment research by focusing on an open source infrastructure accessible to everyone, everywhere. |
7
7
  | :---------------------------------------------------------------------------------------------------------------------------------------------: |
@@ -34,7 +34,7 @@ openbb
34
34
 
35
35
  Which should result in the following output:
36
36
 
37
- ![image](https://github.com/OpenBB-finance/OpenBBTerminal/assets/48914296/f606bb6e-fa00-4fc8-bad2-8269bb4fc38e)
37
+ ![image](https://github.com/OpenBB-finance/OpenBB/assets/48914296/f606bb6e-fa00-4fc8-bad2-8269bb4fc38e)
38
38
 
39
39
  ## API keys
40
40
 
@@ -400,22 +400,23 @@ class ArgparseTranslator:
400
400
  """
401
401
  kwargs = self._unflatten_args(vars(parsed_args))
402
402
  kwargs = self._update_with_custom_types(kwargs)
403
-
404
403
  provider = kwargs.get("provider")
405
- provider_args = []
404
+ provider_args: List = []
406
405
  if provider and provider in self.provider_parameters:
407
406
  provider_args = self.provider_parameters[provider]
408
407
  else:
409
408
  for args in self.provider_parameters.values():
410
409
  provider_args.extend(args)
411
410
 
412
- # remove kwargs that doesn't match the signature or provider parameters
411
+ # remove kwargs not matching the signature, provider parameters, or are empty.
413
412
  kwargs = {
414
413
  key: value
415
414
  for key, value in kwargs.items()
416
- if key in self.signature.parameters or key in provider_args
415
+ if (
416
+ (key in self.signature.parameters or key in provider_args)
417
+ and (value or value is False)
418
+ )
417
419
  }
418
-
419
420
  return self.func(**kwargs)
420
421
 
421
422
  def parse_args_and_execute(self) -> Any:
@@ -426,6 +427,7 @@ class ArgparseTranslator:
426
427
  Any: The return value of the original function.
427
428
  """
428
429
  parsed_args = self._parser.parse_args()
430
+
429
431
  return self.execute_func(parsed_args)
430
432
 
431
433
  def translate(self) -> Callable:
@@ -79,8 +79,8 @@ class MenuText:
79
79
  self.warnings.append(
80
80
  {
81
81
  "warning": "Command name too long",
82
- "command": name,
83
- "trimmed_command": new_name,
82
+ "actual command": f"`{name}`",
83
+ "displayed command": f"`{new_name}`",
84
84
  }
85
85
  )
86
86
  name = new_name
@@ -8,7 +8,7 @@ import shlex
8
8
  from abc import ABCMeta, abstractmethod
9
9
  from datetime import datetime
10
10
  from pathlib import Path
11
- from typing import Any, Dict, List, Literal, Optional, Union
11
+ from typing import Any, Dict, List, Literal, Optional, Tuple, Union
12
12
 
13
13
  import pandas as pd
14
14
  from openbb_cli.config.completer import NestedCompleter
@@ -19,7 +19,9 @@ from openbb_cli.controllers.utils import (
19
19
  check_file_type_saved,
20
20
  check_positive,
21
21
  get_flair_and_username,
22
+ handle_obbject_display,
22
23
  parse_and_split_input,
24
+ parse_unknown_args_to_dict,
23
25
  print_guest_block_msg,
24
26
  print_rich_table,
25
27
  remove_file,
@@ -373,7 +375,7 @@ class BaseController(metaclass=ABCMeta):
373
375
  if other_args and "-" not in other_args[0][0]:
374
376
  other_args.insert(0, "-n")
375
377
 
376
- ns_parser = self.parse_simple_args(parser, other_args)
378
+ ns_parser, _ = self.parse_simple_args(parser, other_args)
377
379
 
378
380
  if ns_parser:
379
381
  if not ns_parser.name:
@@ -472,7 +474,7 @@ class BaseController(metaclass=ABCMeta):
472
474
  description="Stop recording session into .openbb routine file",
473
475
  )
474
476
  # This is only for auto-completion purposes
475
- _ = self.parse_simple_args(parser, other_args)
477
+ _, _ = self.parse_simple_args(parser, other_args)
476
478
 
477
479
  if "-h" not in other_args and "--help" not in other_args:
478
480
  global RECORD_SESSION # noqa: PLW0603
@@ -603,7 +605,7 @@ class BaseController(metaclass=ABCMeta):
603
605
  prog="whoami",
604
606
  description="Show current user",
605
607
  )
606
- ns_parser = self.parse_simple_args(parser, other_args)
608
+ ns_parser, _ = self.parse_simple_args(parser, other_args)
607
609
 
608
610
  if ns_parser:
609
611
  current_user = session.user
@@ -635,11 +637,27 @@ class BaseController(metaclass=ABCMeta):
635
637
  "--chart", action="store_true", dest="chart", help="Display chart."
636
638
  )
637
639
  parser.add_argument(
638
- "--export", dest="export", help="Export data.", nargs="+", default=None
640
+ "--export",
641
+ default="",
642
+ type=check_file_type_saved(["csv", "json", "xlsx", "png", "jpg"]),
643
+ dest="export",
644
+ help="Export raw data into csv, json, xlsx and figure into png or jpg.",
645
+ nargs="+",
646
+ )
647
+ parser.add_argument(
648
+ "--sheet-name",
649
+ dest="sheet_name",
650
+ default=None,
651
+ nargs="+",
652
+ help="Name of excel sheet to save data to. Only valid for .xlsx files.",
653
+ )
654
+
655
+ ns_parser, unknown_args = self.parse_simple_args(
656
+ parser, other_args, unknown_args=True
639
657
  )
640
658
 
641
- ns_parser = self.parse_simple_args(parser, other_args)
642
659
  if ns_parser:
660
+ kwargs = parse_unknown_args_to_dict(unknown_args)
643
661
  if not ns_parser.index and not ns_parser.key:
644
662
  results = session.obbject_registry.all
645
663
  if results:
@@ -657,21 +675,13 @@ class BaseController(metaclass=ABCMeta):
657
675
  index = int(ns_parser.index)
658
676
  obbject = session.obbject_registry.get(index)
659
677
  if obbject:
660
- if ns_parser.chart and obbject.chart:
661
- obbject.show()
662
- else:
663
- title = obbject.extra.get("command", "")
664
- df = obbject.to_dataframe()
665
- print_rich_table(
666
- df=df,
667
- show_index=True,
668
- title=title,
669
- export=ns_parser.export,
670
- )
671
- if ns_parser.chart and not obbject.chart:
672
- session.console.print(
673
- "[info]No chart available.[/info]"
674
- )
678
+ handle_obbject_display(
679
+ obbject=obbject,
680
+ chart=ns_parser.chart,
681
+ export=ns_parser.export,
682
+ sheet_name=ns_parser.sheet_name,
683
+ **kwargs,
684
+ )
675
685
  else:
676
686
  session.console.print(
677
687
  f"[info]No result found at index {index}.[/info]"
@@ -683,26 +693,24 @@ class BaseController(metaclass=ABCMeta):
683
693
  elif ns_parser.key:
684
694
  obbject = session.obbject_registry.get(ns_parser.key)
685
695
  if obbject:
686
- if ns_parser.chart and obbject.chart:
687
- obbject.show()
688
- else:
689
- title = obbject.extra.get("command", "")
690
- df = obbject.to_dataframe()
691
- print_rich_table(
692
- df=df,
693
- show_index=True,
694
- title=title,
695
- export=ns_parser.export,
696
- )
697
- if ns_parser.chart and not obbject.chart:
698
- session.console.print("[info]No chart available.[/info]")
696
+ handle_obbject_display(
697
+ obbject=obbject,
698
+ chart=ns_parser.chart,
699
+ export=ns_parser.export,
700
+ sheet_name=ns_parser.sheet_name,
701
+ **kwargs,
702
+ )
699
703
  else:
700
704
  session.console.print(
701
705
  f"[info]No result found with key '{ns_parser.key}'.[/info]"
702
706
  )
703
707
 
704
708
  @staticmethod
705
- def parse_simple_args(parser: argparse.ArgumentParser, other_args: List[str]):
709
+ def parse_simple_args(
710
+ parser: argparse.ArgumentParser,
711
+ other_args: List[str],
712
+ unknown_args: bool = False,
713
+ ) -> Tuple[Optional[argparse.Namespace], Optional[List[str]]]:
706
714
  """Parse list of arguments into the supplied parser.
707
715
 
708
716
  Parameters
@@ -711,11 +719,15 @@ class BaseController(metaclass=ABCMeta):
711
719
  Parser with predefined arguments
712
720
  other_args: List[str]
713
721
  List of arguments to parse
722
+ unknown_args: bool
723
+ Flag to indicate if unknown arguments should be returned
714
724
 
715
725
  Returns
716
726
  -------
717
- ns_parser:
727
+ ns_parser: argparse.Namespace
718
728
  Namespace with parsed arguments
729
+ l_unknown_args: List[str]
730
+ List of unknown arguments
719
731
  """
720
732
  parser.add_argument(
721
733
  "-h", "--help", action="store_true", help="show this help message"
@@ -729,19 +741,18 @@ class BaseController(metaclass=ABCMeta):
729
741
  except SystemExit:
730
742
  # In case the command has required argument that isn't specified
731
743
  session.console.print("\n")
732
- return None
744
+ return None, None
733
745
 
734
746
  if ns_parser.help:
735
747
  txt_help = parser.format_help()
736
748
  session.console.print(f"[help]{txt_help}[/help]")
737
- return None
749
+ return None, None
738
750
 
739
- if l_unknown_args:
751
+ if l_unknown_args and not unknown_args:
740
752
  session.console.print(
741
753
  f"The following args couldn't be interpreted: {l_unknown_args}\n"
742
754
  )
743
-
744
- return ns_parser
755
+ return ns_parser, l_unknown_args
745
756
 
746
757
  @classmethod
747
758
  def parse_known_args_and_warn(
@@ -232,6 +232,8 @@ class PlatformController(BaseController):
232
232
  fig = obbject.chart.fig if obbject.chart else None
233
233
  if not export:
234
234
  obbject.show()
235
+ elif session.settings.USE_INTERACTIVE_DF and not export:
236
+ obbject.charting.table()
235
237
  else:
236
238
  if isinstance(df.columns, pd.RangeIndex):
237
239
  df.columns = [str(i) for i in df.columns]
@@ -379,9 +381,7 @@ class PlatformController(BaseController):
379
381
 
380
382
  session.console.print(text=mt.menu_text, menu=self.PATH)
381
383
 
382
- settings = session.settings
383
- dev_mode = settings.DEBUG_MODE or settings.TEST_MODE
384
- if mt.warnings and dev_mode:
384
+ if mt.warnings:
385
385
  session.console.print("")
386
386
  for w in mt.warnings:
387
387
  w_str = str(w).replace("{", "").replace("}", "").replace("'", "")
@@ -4,7 +4,7 @@ from argparse import SUPPRESS, ArgumentParser
4
4
  from contextlib import contextmanager
5
5
  from inspect import isfunction, unwrap
6
6
  from types import MethodType
7
- from typing import Callable, List, Literal
7
+ from typing import Callable, List, Literal, Tuple
8
8
  from unittest.mock import patch
9
9
 
10
10
  from openbb_cli.controllers.utils import (
@@ -110,7 +110,7 @@ def __mock_parse_known_args_and_warn(
110
110
  )
111
111
 
112
112
 
113
- def __mock_parse_simple_args(parser: ArgumentParser, other_args: List[str]) -> None:
113
+ def __mock_parse_simple_args(parser: ArgumentParser, other_args: List[str]) -> Tuple:
114
114
  """Add arguments.
115
115
 
116
116
  Add the arguments that would have normally added by:
@@ -127,6 +127,7 @@ def __mock_parse_simple_args(parser: ArgumentParser, other_args: List[str]) -> N
127
127
  "-h", "--help", action="store_true", help="show this help message"
128
128
  )
129
129
  _ = other_args
130
+ return None, None
130
131
 
131
132
 
132
133
  def __get_command_func(controller, command: str):
@@ -216,7 +217,7 @@ def __patch_controller_functions(controller):
216
217
  target=controller,
217
218
  attribute="parse_simple_args",
218
219
  side_effect=__mock_parse_simple_args,
219
- return_value=None,
220
+ return_value=(None, None),
220
221
  ),
221
222
  patch.object(
222
223
  target=controller,
@@ -205,10 +205,11 @@ class CLIController(BaseController):
205
205
  choices["results"] = {
206
206
  "--help": None,
207
207
  "-h": "--help",
208
- "--export": None,
208
+ "--export": {c: None for c in ["csv", "json", "xlsx", "png", "jpg"]},
209
209
  "--index": None,
210
210
  "--key": None,
211
211
  "--chart": None,
212
+ "--sheet_name": None,
212
213
  }
213
214
 
214
215
  self.update_completer(choices)
@@ -80,7 +80,7 @@ class SettingsController(BaseController):
80
80
  description=field["description"],
81
81
  add_help=False,
82
82
  )
83
- ns_parser = self.parse_simple_args(parser, other_args)
83
+ ns_parser, _ = self.parse_simple_args(parser, other_args)
84
84
  if ns_parser:
85
85
  session.settings.set_item(
86
86
  field_name, not getattr(session.settings, field_name)
@@ -113,7 +113,7 @@ class SettingsController(BaseController):
113
113
  type=type_, # type: ignore[arg-type]
114
114
  choices=choices,
115
115
  )
116
- ns_parser = self.parse_simple_args(parser, other_args)
116
+ ns_parser, _ = self.parse_simple_args(parser, other_args)
117
117
  if ns_parser:
118
118
  if ns_parser.value:
119
119
  # Console style is applied immediately
@@ -16,11 +16,9 @@ from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union
16
16
  import numpy as np
17
17
  import pandas as pd
18
18
  import requests
19
- from openbb import obb
20
- from openbb_charting.core.backend import create_backend, get_backend
21
19
  from openbb_cli.config.constants import AVAILABLE_FLAIRS, ENV_FILE_SETTINGS
22
20
  from openbb_cli.session import Session
23
- from openbb_core.app.model.charts.charting_settings import ChartingSettings
21
+ from openbb_core.app.model.obbject import OBBject
24
22
  from pytz import all_timezones, timezone
25
23
  from rich.table import Table
26
24
 
@@ -302,20 +300,6 @@ def return_colored_value(value: str):
302
300
  return f"{value}"
303
301
 
304
302
 
305
- def _get_backend():
306
- """Get the Platform charting backend."""
307
- try:
308
- return get_backend()
309
- except ValueError:
310
- # backend might not be created yet
311
- charting_settings = ChartingSettings(
312
- system_settings=obb.system, user_settings=obb.user # type: ignore
313
- )
314
- create_backend(charting_settings)
315
- get_backend().start(debug=charting_settings.debug_mode)
316
- return get_backend()
317
-
318
-
319
303
  # pylint: disable=too-many-arguments
320
304
  def print_rich_table( # noqa: PLR0912
321
305
  df: pd.DataFrame,
@@ -384,7 +368,7 @@ def print_rich_table( # noqa: PLR0912
384
368
  isinstance(df[col].iloc[x], pd.Timestamp)
385
369
  for x in range(min(10, len(df)))
386
370
  ):
387
- df[col] = pd.to_numeric(df[col], errors="ignore")
371
+ df[col] = df[col].apply(pd.to_numeric)
388
372
  except (ValueError, TypeError):
389
373
  df[col] = df[col].astype(str)
390
374
 
@@ -395,7 +379,7 @@ def print_rich_table( # noqa: PLR0912
395
379
  output = list(_headers)
396
380
  if len(output) != len(df.columns):
397
381
  raise ValueError("Length of headers does not match length of DataFrame.")
398
- return output
382
+ return output # type: ignore
399
383
 
400
384
  if session.settings.USE_INTERACTIVE_DF:
401
385
  df_outgoing = df.copy()
@@ -413,10 +397,7 @@ def print_rich_table( # noqa: PLR0912
413
397
  if col == "":
414
398
  df_outgoing = df_outgoing.rename(columns={col: " "})
415
399
 
416
- # ensure everything on the dataframe is a string
417
- df_outgoing = df_outgoing.applymap(str)
418
-
419
- _get_backend().send_table(
400
+ session._backend.send_table( # type: ignore # pylint: disable=protected-access
420
401
  df_table=df_outgoing,
421
402
  title=title,
422
403
  theme=session.user.preferences.table_style,
@@ -974,3 +955,78 @@ def request(
974
955
  timeout=timeout,
975
956
  **kwargs,
976
957
  )
958
+
959
+
960
+ def parse_unknown_args_to_dict(unknown_args: Optional[List[str]]) -> Dict[str, str]:
961
+ """Parse unknown arguments to a dictionary."""
962
+ unknown_args_dict = {}
963
+ if unknown_args:
964
+ for idx, arg in enumerate(unknown_args):
965
+ if arg.startswith("--"):
966
+ if idx + 1 < len(unknown_args):
967
+ try:
968
+ unknown_args_dict[arg.replace("--", "")] = (
969
+ eval( # noqa: S307, E501 pylint: disable=eval-used
970
+ unknown_args[idx + 1]
971
+ )
972
+ )
973
+ except Exception:
974
+ unknown_args_dict[arg] = unknown_args[idx + 1]
975
+ else:
976
+ session.console.print(
977
+ f"Missing value for argument {arg}. Skipping this argument."
978
+ )
979
+ return unknown_args_dict
980
+
981
+
982
+ def handle_obbject_display(
983
+ obbject: OBBject,
984
+ chart: bool = False,
985
+ export: str = "",
986
+ sheet_name: str = "",
987
+ **kwargs,
988
+ ):
989
+ """Handle the display of an OBBject."""
990
+ df: pd.DataFrame = pd.DataFrame()
991
+ fig: Optional[OpenBBFigure] = None
992
+ if chart:
993
+ try:
994
+ if obbject.chart:
995
+ obbject.show(**kwargs)
996
+ else:
997
+ obbject.charting.to_chart(**kwargs) # type: ignore
998
+ if export:
999
+ fig = obbject.chart.fig # type: ignore
1000
+ df = obbject.to_dataframe()
1001
+ except Exception as e:
1002
+ session.console.print(f"Failed to display chart: {e}")
1003
+ elif session.settings.USE_INTERACTIVE_DF:
1004
+ obbject.charting.table() # type: ignore
1005
+ else:
1006
+ df = obbject.to_dataframe()
1007
+ print_rich_table(
1008
+ df=df,
1009
+ show_index=True,
1010
+ title=obbject.extra.get("command", ""),
1011
+ export=bool(export),
1012
+ )
1013
+ if export and not df.empty:
1014
+ if sheet_name and isinstance(sheet_name, list):
1015
+ sheet_name = sheet_name[0]
1016
+
1017
+ func_name = (
1018
+ obbject.extra.get("command", "")
1019
+ .replace("/", "_")
1020
+ .replace(" ", "_")
1021
+ .replace("--", "_")
1022
+ )
1023
+ export_data(
1024
+ export_type=",".join(export),
1025
+ dir_path=os.path.dirname(os.path.abspath(__file__)),
1026
+ func_name=func_name,
1027
+ df=df,
1028
+ sheet_name=sheet_name,
1029
+ figure=fig,
1030
+ )
1031
+ elif export and df.empty:
1032
+ session.console.print("[yellow]No data to export.[/yellow]")
@@ -5,7 +5,9 @@ from pathlib import Path
5
5
  from typing import Optional
6
6
 
7
7
  from openbb import obb
8
+ from openbb_charting.core.backend import create_backend, get_backend
8
9
  from openbb_core.app.model.abstract.singleton import SingletonMeta
10
+ from openbb_core.app.model.charts.charting_settings import ChartingSettings
9
11
  from openbb_core.app.model.user_settings import UserSettings as User
10
12
  from prompt_toolkit import PromptSession
11
13
 
@@ -17,11 +19,26 @@ from openbb_cli.config.style import Style
17
19
  from openbb_cli.models.settings import Settings
18
20
 
19
21
 
22
+ def _get_backend():
23
+ """Get the Platform charting backend."""
24
+ try:
25
+ return get_backend()
26
+ except ValueError:
27
+ # backend might not be created yet
28
+ charting_settings = ChartingSettings(
29
+ system_settings=obb.system, user_settings=obb.user # type: ignore
30
+ )
31
+ create_backend(charting_settings)
32
+ get_backend().start(debug=charting_settings.debug_mode) # type: ignore
33
+ return get_backend()
34
+
35
+
20
36
  class Session(metaclass=SingletonMeta):
21
37
  """Session class."""
22
38
 
23
39
  def __init__(self):
24
40
  """Initialize session."""
41
+
25
42
  self._obb = obb
26
43
  self._settings = Settings()
27
44
  self._style = Style(
@@ -34,6 +51,8 @@ class Session(metaclass=SingletonMeta):
34
51
  self._prompt_session = self._get_prompt_session()
35
52
  self._obbject_registry = Registry()
36
53
 
54
+ self._backend = _get_backend()
55
+
37
56
  @property
38
57
  def user(self) -> User:
39
58
  """Get platform user."""
@@ -1,30 +1,31 @@
1
1
  [tool.poetry]
2
2
  name = "openbb-cli"
3
- version = "1.0.4"
3
+ version = "1.1.1"
4
4
  description = "Investment Research for Everyone, Anywhere."
5
5
  authors = ["OpenBB <hello@openbb.co>"]
6
6
  packages = [{ include = "openbb_cli" }]
7
7
  license = "AGPL-3.0-only"
8
8
  readme = "README.md"
9
9
  homepage = "https://openbb.co"
10
- repository = "https://github.com/OpenBB-finance/OpenBBTerminal"
11
- documentation = "https://docs.openbb.co/terminal"
10
+ repository = "https://github.com/OpenBB-finance/OpenBB"
11
+ documentation = "https://docs.openbb.co/cli"
12
12
 
13
13
  [tool.poetry.scripts]
14
14
  openbb = 'openbb_cli.cli:main'
15
15
 
16
16
  [tool.poetry.dependencies]
17
- python = "^3.8.1,<3.12"
17
+ python = "^3.9,<3.13"
18
18
 
19
19
  # OpenBB dependencies
20
- openbb = { version = "^4.2.3", extras = ["all"] }
20
+ openbb = { version = "^4.3.1", extras = ["all"] }
21
21
 
22
22
  # CLI dependencies
23
23
  prompt-toolkit = "^3.0.16"
24
24
  rich = "^13"
25
25
  python-dotenv = "^1.0.0"
26
26
  openpyxl = "^3.1.2"
27
+ pywry = "^0.6.2"
27
28
 
28
29
  [build-system]
29
- requires = ["setuptools<65.5.0", "poetry-core>=1.0.0"]
30
+ requires = ["poetry-core>=1.0.0"]
30
31
  build-backend = "poetry.core.masonry.api"
File without changes