Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDK : use _chart for views #3429

Merged
merged 10 commits into from
Nov 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 36 additions & 10 deletions openbb_terminal/core/library/breadcrumb.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
from openbb_terminal.core.library.trail_map import TrailMap
from openbb_terminal.core.library.operation import Operation

# pylint: disable=import-outside-toplevel


class MetadataBuilder:
@staticmethod
def build_dir_list(trail: str, trail_map: TrailMap) -> List[str]:
def get_option_list(trail: str, trail_map: TrailMap) -> List[str]:
option_list = []
for key in trail_map.map_dict:
if trail == "":
Expand All @@ -23,30 +25,44 @@ def build_dir_list(trail: str, trail_map: TrailMap) -> List[str]:

return list(set(option_list))

@classmethod
def build_dir_list(cls, trail: str, trail_map: TrailMap) -> List[str]:
option_list = cls.get_option_list(trail=trail, trail_map=trail_map)

option_list_full = []
for option in option_list:
option_list_full.append(option)

option_view_trail = f"{trail}.{option}_chart"
if trail_map.get_view_function(trail=option_view_trail):
option_list_full.append(f"{option}_chart")

return option_list_full

@staticmethod
def build_doc_string(trail: str, dir_list: List[str]) -> str:
def build_docstring(trail: str, dir_list: List[str]) -> str:
if trail == "":
doc_string = """This is the OpenBB Terminal SDK.
docstring = """This is the OpenBB Terminal SDK.
Use the SDK to get data directly into your jupyter notebook or directly use it in your application.
For more information see the official documentation at: https://openbb-finance.github.io/OpenBBTerminal/SDK/
"""
else:
doc_string = (
docstring = (
trail.rsplit(".")[-1].upper()
+ " Menu\n\nThe SDK commands of the the menu:"
)
for command in dir_list:
doc_string += f"\n\t<openbb>.{trail}.{command}"
docstring += f"\n\t<openbb>.{trail}.{command}"

return doc_string
return docstring

@classmethod
def build(cls, trail: str, trail_map: TrailMap) -> Metadata:
dir_list = cls.build_dir_list(trail=trail, trail_map=trail_map)
doc_string = cls.build_doc_string(trail=trail, dir_list=dir_list)
docstring = cls.build_docstring(trail=trail, dir_list=dir_list)
metadata = Metadata(
dir_list=dir_list,
doc_string=doc_string,
docstring=docstring,
)
return metadata

Expand Down Expand Up @@ -83,7 +99,7 @@ def __init__(
self._trail_map = trail_map
self._trail = trail

self.__doc__ = metadata.doc_string
self.__doc__ = metadata.docstring

if trail == "":
BreadcrumbLogger()
Expand All @@ -100,7 +116,9 @@ def __getattr__(self, name: str) -> Any:
else:
trail_next = f"{trail}.{name}"

if Operation.is_valid(trail=trail_next, trail_map=trail_map):
if trail_map.get_model_function(
trail=trail_next
) or trail_map.get_view_function(trail=trail_next):
next_crumb: Any = Operation(
trail=trail_next,
trail_map=trail_map,
Expand All @@ -118,6 +136,14 @@ def __getattr__(self, name: str) -> Any:

return next_crumb

def about(self):
import webbrowser

trail = self._trail
url = "https://openbb-finance.github.io/OpenBBTerminal/SDK/"
url += "/".join(trail.split("."))
webbrowser.open(url)


# pylint: disable=R0903
class BreadcrumbLogger:
Expand Down
8 changes: 4 additions & 4 deletions openbb_terminal/core/library/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ def dir_list(self) -> List[str]:
return self.__dir_list

@property
def doc_string(self) -> str:
return self.__doc_string
def docstring(self) -> str:
return self.__docstring

def __init__(
self,
dir_list: List[str],
doc_string: str = "",
docstring: str = "",
) -> None:
self.__dir_list = dir_list
self.__doc_string = doc_string
self.__docstring = docstring
160 changes: 58 additions & 102 deletions openbb_terminal/core/library/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,49 @@
from openbb_terminal.core.library.metadata import Metadata
from openbb_terminal.core.library.trail_map import TrailMap

# pylint: disable=import-outside-toplevel


class MetadataBuilder:
def __init__(self, model: Optional[Callable], view: Optional[Callable]) -> None:
self.__model = model
self.__view = view
def __init__(
self,
method: Callable,
trail: str,
trail_map: TrailMap,
) -> None:
self.__method = method
self.__trail = trail
self.__trail_map = trail_map

@staticmethod
def build_doc_string(
model: Optional[Callable],
view: Optional[Callable],
def build_docstring(
method: Callable,
trail: str,
trail_map: TrailMap,
) -> str:
if view is not None:
view_doc = view.__doc__ or ""
model_doc = model.__doc__ or ""
index = view_doc.find("Parameters")

all_parameters = (
"\nSDK function, use the chart kwarg for getting the view model and it's plot. "
"See every parameter below:\n\n "
+ view_doc[index:]
+ """chart: bool
If the view and its chart shall be used"""
)
doc_string = (
all_parameters
+ "\n\nModel doc:\n"
+ model_doc
+ "\n\nView doc:\n"
+ view_doc
)
else:
doc_string = model.__doc__ or ""
doc = ""

view_trail = f"{trail}_chart"
if trail_map.get_view_function(view_trail):
doc += f"Use '{view_trail}' to access the view.\n"

return doc_string
if method.__doc__:
doc += method.__doc__

return doc

def build(self) -> Metadata:
model = self.__model
view = self.__view
method = self.__method
trail = self.__trail
trail_map = self.__trail_map

dir_list: List[str] = []
docstring = self.build_doc_string(model=model, view=view)
metadata = Metadata(dir_list=dir_list, doc_string=docstring)
docstring = self.build_docstring(
method=method,
trail=trail,
trail_map=trail_map,
)
metadata = Metadata(dir_list=dir_list, docstring=docstring)

return metadata

Expand All @@ -61,53 +62,9 @@ class Operation:
def __get_method(method_path: str) -> Callable:
module_path, function_name = method_path.rsplit(".", 1)
module = import_module(module_path)
method = getattr(module, function_name)

return method

@classmethod
def __get_model(cls, trail: str, trail_map: TrailMap) -> Optional[Callable]:
map_dict = trail_map.map_dict
model = None

if trail in map_dict:
if "model" in map_dict[trail] and map_dict[trail]["model"]:
model_path = map_dict[trail]["model"]
model = cls.__get_method(method_path=model_path)
func = getattr(module, function_name)

return model

@classmethod
def __get_view(cls, trail: str, trail_map: TrailMap) -> Optional[Callable]:
map_dict = trail_map.map_dict
view = None

if trail in map_dict:
if "view" in map_dict[trail] and map_dict[trail]["view"]:
view_path = map_dict[trail]["view"]
view = cls.__get_method(method_path=view_path)

return view

@staticmethod
def is_valid(trail: str, trail_map: TrailMap) -> bool:
return trail in trail_map.map_dict

@property
def trail(self) -> str:
return self.__trail

@property
def trail_map(self) -> TrailMap:
return self.__trail_map

@property
def model(self) -> Optional[Callable]:
return self.__model

@property
def view(self) -> Optional[Callable]:
return self.__view
return func

def __init__(
self,
Expand All @@ -116,48 +73,47 @@ def __init__(
metadata: Optional[Metadata] = None,
) -> None:
trail_map = trail_map or TrailMap()
model = self.__get_model(trail=trail, trail_map=trail_map)
view = self.__get_view(trail=trail, trail_map=trail_map)
metadata = metadata or MetadataBuilder(model=model, view=view).build()

self.__trail = trail
self.__trail_map = trail_map
self.__model = model
self.__view = view
method_path = trail_map.get_model_or_view(trail=trail)
method = self.__get_method(method_path=method_path)
metadata = (
metadata
or MetadataBuilder(method=method, trail=trail, trail_map=trail_map).build()
)

self.__doc__ = metadata.doc_string
self._trail = trail
self._trail_map = trail_map
self._method = method

if model:
self.__signature__ = signature(model)
self.__doc__ = metadata.docstring
self.__signature__ = signature(method)

def __call__(self, *args: Any, **kwargs: Any) -> Any:
model = self.__model
view = self.__view

if view and "chart" in kwargs and kwargs["chart"] is True:
method_chosen = view
elif model:
method_chosen = model
else:
raise Exception("Unknown method")
method = self._method

operation_logger = OperationLogger(
trail=self.__trail,
method_chosen=method_chosen,
trail=self._trail,
method_chosen=method,
args=args,
kwargs=kwargs,
)

operation_logger.log_before_call()

if "chart" in kwargs:
kwargs.pop("chart")
method_result = method_chosen(*args, **kwargs)
method_result = method(*args, **kwargs)

operation_logger.log_after_call(method_result=method_result)

return method_result

def about(self):
import webbrowser

trail = self._trail
url = "https://openbb-finance.github.io/OpenBBTerminal/SDK/"
url += "/".join(trail.split("."))
webbrowser.open(url)


class OperationLogger:
def __init__(
Expand Down
47 changes: 44 additions & 3 deletions openbb_terminal/core/library/trail_map.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pathlib import Path
from typing import Dict
from typing import Dict, Optional

import pandas as pd

Expand All @@ -8,8 +8,6 @@
try:
import darts # pylint: disable=W0611 # noqa: F401

# If you just import darts this will pass during pip install, this creates
# Failures later on, also importing utils ensures that darts is installed correctly
from darts import utils # pylint: disable=W0611 # noqa: F401

FORECASTING = True
Expand Down Expand Up @@ -41,6 +39,49 @@ def save_csv(cls, map_dict: Dict[str, Dict[str, str]], path: Path = None) -> Non
def map_dict(self) -> Dict[str, Dict[str, str]]:
return self.__map_dict

def get_view_function(self, trail: str) -> Optional[str]:
"""Retrieves the view function from the mapping.

Views ends with "_chart".

Args:
trail (str): Trail like "futures.curves_chart"

Returns:
Optional[str]: View function import path.
"""

map_dict = self.__map_dict
trail = trail[: -len("_chart")]

view = None
if trail in map_dict and "view" in map_dict[trail] and map_dict[trail]["view"]:
view = map_dict[trail]["view"]

return view

def get_model_function(self, trail: str) -> Optional[str]:
map_dict = self.map_dict

model = None
if trail in map_dict and "view" in map_dict[trail] and map_dict[trail]["model"]:
model = map_dict[trail]["model"]

return model

def get_model_or_view(self, trail: str) -> str:
model_path = self.get_model_function(trail=trail)
view_path = self.get_view_function(trail=trail)

if model_path:
method_path = model_path
elif view_path:
method_path = view_path
else:
raise AttributeError(f"Unknown method : {trail}")

return method_path

def load(self):
map_dict = self.load_csv(path=self.MAP_PATH)
if FORECASTING:
Expand Down
Loading