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.
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/PKG-INFO +9 -7
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/README.md +2 -2
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/argparse_translator.py +7 -5
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/config/menu_text.py +2 -2
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/base_controller.py +52 -41
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/base_platform_controller.py +3 -3
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/choices.py +4 -3
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/cli_controller.py +2 -1
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/settings_controller.py +2 -2
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/utils.py +79 -23
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/session.py +19 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/pyproject.toml +7 -6
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/__init__.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/__init__.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/argparse_argument.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/argparse_class_processor.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/obbject_registry.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/reference_processor.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/utils.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/routines/routine_example.openbb +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/Consolas.ttf +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/dark.mpfstyle.json +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/dark.mplrc.json +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/dark.mplstyle +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/dark.pltstyle.json +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/dark.richstyle.json +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/light.mpfstyle.json +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/light.mplrc.json +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/light.mplstyle +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/light.pltstyle.json +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/light.richstyle.json +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/default/tables.pltstyle.json +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/assets/styles/user/openbb.richstyle.json +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/cli.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/config/__init__.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/config/completer.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/config/console.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/config/constants.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/config/setup.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/config/style.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/hub_service.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/platform_controller_factory.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/controllers/script_parser.py +0 -0
- {openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/models/settings.py +0 -0
- {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.
|
|
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.
|
|
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
|
-
|
|
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/
|
|
21
|
-
Project-URL: Repository, https://github.com/OpenBB-finance/
|
|
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
|
[](https://pepy.tech/project/openbb)
|
|
27
|
-
[](https://github.com/OpenBB-finance/
|
|
29
|
+
[](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
|
-

|
|
61
63
|
|
|
62
64
|
## API keys
|
|
63
65
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# OpenBB Platform CLI
|
|
2
2
|
|
|
3
3
|
[](https://pepy.tech/project/openbb)
|
|
4
|
-
[](https://github.com/OpenBB-finance/
|
|
4
|
+
[](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
|
-

|
|
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
|
|
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
|
|
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:
|
|
@@ -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",
|
|
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
|
-
|
|
661
|
-
obbject
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
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
|
-
|
|
687
|
-
obbject
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
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(
|
|
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
|
-
|
|
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]) ->
|
|
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.
|
|
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] =
|
|
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
|
-
#
|
|
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.
|
|
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/
|
|
11
|
-
documentation = "https://docs.openbb.co/
|
|
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.
|
|
17
|
+
python = "^3.9,<3.13"
|
|
18
18
|
|
|
19
19
|
# OpenBB dependencies
|
|
20
|
-
openbb = { version = "^4.
|
|
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 = ["
|
|
30
|
+
requires = ["poetry-core>=1.0.0"]
|
|
30
31
|
build-backend = "poetry.core.masonry.api"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openbb_cli-1.0.4 → openbb_cli-1.1.1}/openbb_cli/argparse_translator/argparse_class_processor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|