SDK logs improved (#2893)

* added console prints

* little refactor for degiro company news

* fixed message always showing even on login fail

* initial test with the api logs

* changes log_settings location in order to use it on the sdk; also, modified the actual settings logging to a json.dumps - in order to get a well formed json str

* added logger to the api

* adding decorator to the function as it's copied

* added arguments to the logging

* remove the double log_start_end decorator

* added func_name_override

* Revert "added console prints"

This reverts commit 61d8224e97.

* Revert "little refactor for degiro company news"

This reverts commit ca5239fa9e.

* Revert "fixed message always showing even on login fail"

This reverts commit 05793bff8b.

* added typing ignore

* fixed litting

* added logging of theme and keys

* added virtual path to the logging

* fix flake8

* fixing mypy

* removed predict from the settings

* changed the way we get the keys - after the keys controller pr was merged

* dict escaped to json str

* moved the settings logging for a different file

* added different logging for keys, configs and feature flags

* fixing typo

* removed locals - using directly the args and kwargs gives us the same

* fixed black

* adding sensitive words to exclude from logs

* adding chart arg to logging

* adding all args to logs - default or not

* fix linting

* suppressing logs for reports

* solving conflicts

* fix linting

* little change on the way suppression occurs

* changing decorator to get keys state during notebook execution

* removing unused import

* black

* added dashboards to supress logging on sdk
This commit is contained in:
hjoaquim
2022-10-18 19:05:28 +01:00
committed by GitHub
parent 7136806103
commit ace5ac607f
3 changed files with 135 additions and 12 deletions

View File

@@ -15,6 +15,18 @@ from openbb_terminal.core.log.generation.path_tracking_file_handler import (
)
SENSITIVE_WORDS = [
"API",
"DG_",
"KEY",
"PASSWORD",
"SECRET",
"TOKEN",
"USER",
"USERNAME",
"ACCOUNT",
]
logger = logging.getLogger(__name__)
@@ -63,8 +75,7 @@ def log_config_terminal() -> None:
not item.startswith("__")
and not isinstance(prop, FunctionType)
and not isinstance(prop, ModuleType)
and "API" not in item
and "DG_" not in item
and not any(substring in item for substring in SENSITIVE_WORDS)
):
config_terminal_dict[item] = str(prop)

View File

@@ -4,10 +4,13 @@ import functools
import logging
import os
import json
import inspect
from typing import Callable
import pandas as pd
from openbb_terminal import feature_flags as obbff
from openbb_terminal.rich_config import console # pragma: allowlist secret
from openbb_terminal.core.log.generation.settings_logger import log_keys
logger = logging.getLogger(__name__)
@@ -120,7 +123,7 @@ def disable_check_api():
obbff.ENABLE_CHECK_API = False
def sdk_arg_logger(func=None, log=None, virtual_path: str = ""):
def sdk_arg_logger(func=None, log=None, virtual_path: str = "", chart: bool = False):
"""
Wrap function to add the function args to the log entry when using the SDK.
"""
@@ -130,10 +133,13 @@ def sdk_arg_logger(func=None, log=None, virtual_path: str = ""):
try:
value = func(*args, **kwargs)
logging_info = {"INPUT": {"args": args, "kwargs": kwargs}}
merged_args = merge_function_args(func, args, kwargs)
merged_args = sdk_remove_key_and_log_state(func.__module__, merged_args)
if virtual_path:
logging_info["VIRTUAL_PATH"] = virtual_path
logging_info = {}
logging_info["INPUT"] = merged_args
logging_info["VIRTUAL_PATH"] = virtual_path
logging_info["CHART"] = chart
log.info(
f"{json.dumps(logging_info)}",
@@ -146,3 +152,60 @@ def sdk_arg_logger(func=None, log=None, virtual_path: str = ""):
raise
return wrapper_decorator
def merge_function_args(func: Callable, args: tuple, kwargs: dict) -> dict:
"""
Merge user input args and kwargs with signature defaults into a dictionary.
Parameters
----------
func : Callable
Function to get the args from
args : tuple
Positional args
kwargs : dict
Keyword args
Returns
-------
dict
Merged user args and signature defaults
"""
sig = inspect.signature(func)
sig_args = {
param.name: param.default
for param in sig.parameters.values()
if param.default is not inspect.Parameter.empty
}
# merge args with sig_args
sig_args.update(dict(zip(sig.parameters, args)))
# add kwargs elements to sig_args
sig_args.update(kwargs)
return sig_args
def sdk_remove_key_and_log_state(func_module: str, function_args: dict) -> dict:
"""
Remove API key from the function args and log state of keys.
Parameters
----------
func_module : str
Module of the function
function_args : dict
Function args
Returns
-------
dict
Function args with API key removed
"""
if func_module == "openbb_terminal.keys_model":
# remove key if defined
function_args.pop("key", None)
log_keys()
return function_args

View File

@@ -9,8 +9,11 @@ import functools
import importlib
from typing import Optional, Callable, List
import logging
from traceback import format_stack
from openbb_terminal.rich_config import console
from openbb_terminal.reports.reports_controller import ReportController
from openbb_terminal.dashboards.dashboards_controller import DashboardsController
try:
import darts # pyright: reportMissingImports=false
@@ -37,6 +40,13 @@ from .cryptocurrency.due_diligence.pycoingecko_model import Coin
logger = logging.getLogger(__name__)
SUPPRESS_LOGGING_CLASSES = {
ReportController: "ReportController",
DashboardsController: "DashboardsController",
}
functions = {
"alt.covid.slopes": {
"model": "openbb_terminal.alternative.covid.covid_model.get_case_slopes",
@@ -2039,7 +2049,10 @@ if forecasting:
def copy_func(
f: Callable, logging_decorator: bool = False, virtual_path: str = ""
f: Callable,
logging_decorator: bool = False,
virtual_path: str = "",
chart: bool = False,
) -> Callable:
"""Copy the contents and attributes of the entered function.
@@ -2051,6 +2064,10 @@ def copy_func(
Function to be copied
logging_decorator: bool
If True, the copied function will be decorated with the logging decorator
virtual_path: str
If not empty, virtual path will be added to the logging
chart: bool
If True, the copied function will log info on whether it is a view (chart)
Returns
-------
@@ -2073,7 +2090,7 @@ def copy_func(
if logging_decorator:
log_name = logging.getLogger(g.__module__)
g = sdk_arg_logger(func=g, log=log_name, virtual_path=virtual_path)
g = sdk_arg_logger(func=g, log=log_name, virtual_path=virtual_path, chart=chart)
g = log_start_end(func=g, log=log_name)
return g
@@ -2131,6 +2148,29 @@ def change_docstring(api_callable, model: Callable, view=None):
return api_callable
def check_suppress_logging(suppress_dict: dict) -> bool:
"""
Check if logging should be suppressed.
If the dict contains a value that is found in the stack trace,
the logging should be suppressed.
Parameters
----------
supress_dict: dict
Dictionary with values that trigger log suppression
Returns
-------
bool
True if logging shall be suppressed, False otherwise
"""
for _, value in suppress_dict.items():
for ele in format_stack():
if value in ele:
return True
return False
class FunctionFactory:
"""The SDK Function Factory, which creates the callable instance."""
@@ -2155,7 +2195,7 @@ class FunctionFactory:
self.view = None
if view is not None:
self.view = copy_func(
f=view, logging_decorator=True, virtual_path=virtual_path
f=view, logging_decorator=True, virtual_path=virtual_path, chart=True
)
def api_callable(self, *args, **kwargs):
@@ -2215,13 +2255,15 @@ class MainMenu:
class Loader:
"""The Loader class."""
def __init__(self, funcs: dict):
def __init__(self, funcs: dict, suppress_logging: bool = False):
print(
"WARNING! Breaking changes incoming! Especially avoid using kwargs, since some of them will change.\n"
"For more information see the official documentation at: https://openbb-finance.github.io/OpenBBTerminal/sdk/"
)
self.__suppress_logging = suppress_logging
self.__function_map = self.build_function_map(funcs=funcs)
self.__initialize_logging()
self.__check_initialize_logging()
self.load_menus()
def __call__(self):
@@ -2298,6 +2340,10 @@ class Loader:
self.openbb = main_menu
def __check_initialize_logging(self):
if not self.__suppress_logging:
self.__initialize_logging()
@staticmethod
def __load_module(module_path: str) -> Optional[types.ModuleType]:
"""Load a module from a path.
@@ -2409,4 +2455,7 @@ class Loader:
# TO USE THE SDK DIRECTLY JUST IMPORT IT:
# from openbb_terminal.sdk import openbb (or: from openbb_terminal.sdk import openbb as sdk)
openbb = Loader(funcs=functions).openbb
openbb = Loader(
funcs=functions,
suppress_logging=check_suppress_logging(suppress_dict=SUPPRESS_LOGGING_CLASSES),
).openbb