From cb5e610bcb71e2a5e7c8527f9871567f44d502d9 Mon Sep 17 00:00:00 2001 From: montezdesousa <79287829+montezdesousa@users.noreply.github.com> Date: Sun, 9 Oct 2022 09:04:25 +0200 Subject: [PATCH] Set multiple API keys at once on OpenBB SDK (#2716) * set fred keys through api * linting * doc change * expose api keys dict * allow optional persistency of api key change * black * place decorators * add keys paths * av and fmp keys * some fixes * rewrite av, fmp, fred cassettes * quandl key * polygon key * rewrite polygon cassette * news and tradier * cmc key * change some docstring * change some docstring * filtered keys dict on mykeys * simplify mykeys collection * revert arg to persist * finnhub * iex key * reddit key * reddit docstring * check for prefix before removing * glassnode key * glassnode virtual path * bitquery keys * twitter key * robinhood key * degiro keys * oanda key * binance keys * si key * coinbase key * refactor btcrb dates and logic * walert key * coinglass key * regenerate cassettes * cpanic keys * ethplorer keys * replace ouput status failed msg * smartstake keys * gitub keys * messari keys * eodhd keys * santiment keys * remove unused imports * typo formatting test * remove forbidden arg * fix btcrb test * fix test import * revert cassette changes * fix more tests * fix last failing * black * try to change status to int code * change status to int * first try at keys controller refactoring * fix some tests accordingly * display msg on set * change some vars * remove elifs * add progress bar and remove duplicate key check * add mykeys and refresh to menu * remove unused import * change mykeys output to df * remove check keys from keys ctrl tests * update test split to new structure * reduce duplicate code * upper case * change var name * rename mykeys df cols * add keys integrations tests * add mykeys test to keys controller * fix mykeys * fix wrong eodhd var name * pylint * test_set_key * black * patch dotenv kinda * fix mypy * remove refresh * filter mykeys df * filter mykeys df * update integration tests * first unit test for set api key * add 2 more test cases to fred * add persist test to fred unittest * add av unittest * add polygon unittest * generate av cassettes * add unittests av, fmp, quandl, polygon, fred * change si token to key * forgot controller func * unittest: news, tradier, cmc, finnhub, iex, bitquery * add si unittest * update eodhd key name * add unittest: walert, glassnode, coinglass, cpanic, ethplorer, github, messari, eodhd, santiment * black * add reddit unittest * refactor unittests to handle multi args * regenerate cassettes * add more unittests * add degiro, oanda and rh unittest * generate oanda records * fix rh and degiro unittest * fix oanda unittest * black * flake8 * fix si controller test * move tmp * pylint * fix av test * fix fmp key check * rewrite fmp * rewrite oanda output * fix quandl check * rewrite expected * supress logger exception * fix iex cloud key * remove iex warning * fix coinglass check key * cpanic fix * regenerate cpanic cassettes * flake8 * fix smartstake keys check * regenerate expected output * fix eodhd * try at binance * black * fix controller tests * pylint * disable warning * flake * add option to show keys * add Enum to model * regenerate test output * update contributing * flake * fix type hint * remove status msg dict * pylint * regenerate and remove unecessary cassettes * remove duplicate return * supress traceback * remove unused imports * update some docstrings * add todo * add export option to mykeys * minor change * refactor color scheme * update contributing * update contributing * regenerate cassettes * add set_keys * add api list helper * prevent wrong api names * add some help if wrong kwargs * change some name * update some doctrings * remove api block * remove api block * change endpoint name * pylint * fix check output * small msg change * small details * rewrite some tests * Removed bad test Co-authored-by: hjoaquim Co-authored-by: Colin Delahunty <72827203+colin99d@users.noreply.github.com> Co-authored-by: colin99d --- openbb_terminal/api.py | 2 + openbb_terminal/keys_controller.py | 32 +---- openbb_terminal/keys_model.py | 111 ++++++++++++++++++ .../test_featflags_controller.py | 4 - 4 files changed, 114 insertions(+), 35 deletions(-) diff --git a/openbb_terminal/api.py b/openbb_terminal/api.py index 8b969912c3b..6fb0e21dfbf 100644 --- a/openbb_terminal/api.py +++ b/openbb_terminal/api.py @@ -1942,6 +1942,8 @@ functions = { "keys.eodhd": {"model": "openbb_terminal.keys_model.set_eodhd_key"}, "keys.santiment": {"model": "openbb_terminal.keys_model.set_santiment_key"}, "keys.mykeys": {"model": "openbb_terminal.keys_model.get_keys"}, + "keys.set_keys": {"model": "openbb_terminal.keys_model.set_keys"}, + "keys.get_keys_info": {"model": "openbb_terminal.keys_model.get_keys_info"}, } forecast_extras = { "forecast.load": {"model": "openbb_terminal.forecast.forecast_model.load"}, diff --git a/openbb_terminal/keys_controller.py b/openbb_terminal/keys_controller.py index d3cd09ee284..d8b35d21ba9 100644 --- a/openbb_terminal/keys_controller.py +++ b/openbb_terminal/keys_controller.py @@ -28,37 +28,7 @@ logger = logging.getLogger(__name__) class KeysController(BaseController): # pylint: disable=too-many-public-methods """Keys Controller class""" - API_DICT: Dict = { - "av": "ALPHA_VANTAGE", - "fmp": "FINANCIAL_MODELING_PREP", - "quandl": "QUANDL", - "polygon": "POLYGON", - "fred": "FRED", - "news": "NEWSAPI", - "tradier": "TRADIER", - "cmc": "COINMARKETCAP", - "finnhub": "FINNHUB", - "iex": "IEXCLOUD", - "reddit": "REDDIT", - "twitter": "TWITTER", - "rh": "ROBINHOOD", - "degiro": "DEGIRO", - "oanda": "OANDA", - "binance": "BINANCE", - "bitquery": "BITQUERY", - "si": "SENTIMENT_INVESTOR", - "coinbase": "COINBASE", - "walert": "WHALE_ALERT", - "glassnode": "GLASSNODE", - "coinglass": "COINGLASS", - "cpanic": "CRYPTO_PANIC", - "ethplorer": "ETHPLORER", - "smartstake": "SMARTSTAKE", - "github": "GITHUB", - "messari": "MESSARI", - "eodhd": "EODHD", - "santiment": "SANTIMENT", - } + API_DICT = keys_model.API_DICT API_LIST = list(API_DICT.keys()) CHOICES_COMMANDS: List[str] = ["mykeys"] + API_LIST PATH = "/keys/" diff --git a/openbb_terminal/keys_model.py b/openbb_terminal/keys_model.py index 5e8437ce9b1..361efc85151 100644 --- a/openbb_terminal/keys_model.py +++ b/openbb_terminal/keys_model.py @@ -7,6 +7,8 @@ import sys import logging import os from enum import Enum + +from typing import Dict, List, Union import binance import dotenv import pandas as pd @@ -35,6 +37,39 @@ logger = logging.getLogger(__name__) sys.tracebacklimit = 0 +API_DICT: Dict = { + "av": "ALPHA_VANTAGE", + "fmp": "FINANCIAL_MODELING_PREP", + "quandl": "QUANDL", + "polygon": "POLYGON", + "fred": "FRED", + "news": "NEWSAPI", + "tradier": "TRADIER", + "cmc": "COINMARKETCAP", + "finnhub": "FINNHUB", + "iex": "IEXCLOUD", + "reddit": "REDDIT", + "twitter": "TWITTER", + "rh": "ROBINHOOD", + "degiro": "DEGIRO", + "oanda": "OANDA", + "binance": "BINANCE", + "bitquery": "BITQUERY", + "si": "SENTIMENT_INVESTOR", + "coinbase": "COINBASE", + "walert": "WHALE_ALERT", + "glassnode": "GLASSNODE", + "coinglass": "COINGLASS", + "cpanic": "CRYPTO_PANIC", + "ethplorer": "ETHPLORER", + "smartstake": "SMARTSTAKE", + "github": "GITHUB", + "messari": "MESSARI", + "eodhd": "EODHD", + "santiment": "SANTIMENT", +} + + class KeyStatus(str, Enum): """Class to handle status messages and colors""" @@ -62,6 +97,82 @@ class KeyStatus(str, Enum): return f"[{c}]{self.value}[/{c}]" +def set_keys( + keys_dict: Dict[str, Dict[str, Union[str, bool]]], + persist: bool = False, + show_output: bool = False, +) -> Dict: + """Set API keys in bundle. + + Parameters + ---------- + keys_dict: Dict[str, Dict[str, Union[str, bool]]] + E.g. {"fred": {"key":"XXXXX"}, "binance": {"key":"YYYYY", "secret":"ZZZZZ"}} + More info on APIs can be found through get_keys_info(). + persist: bool + If False, api key change will be contained to where it was changed. For example, Jupyter notebook. + If True, api key change will be global, i.e. it will affect terminal environment variables. + By default, False. + show_output: bool + Display status string or not. By default, False. + + Returns + ------- + status_dict: Dict + + """ + + status_dict = {} + + for api, kwargs in keys_dict.items(): + expected_args_dict = get_keys_info() + + if api in expected_args_dict: + + received_kwargs_list = list(kwargs.keys()) + expected_kwargs_list = expected_args_dict[api] + + if received_kwargs_list == expected_kwargs_list: + kwargs["persist"] = persist + kwargs["show_output"] = show_output + status_dict[api] = str( + getattr(sys.modules[__name__], "set_" + str(api) + "_key")(**kwargs) + ) + else: + console.print( + f"[red]'{api}' kwargs: {received_kwargs_list} don't match expected: {expected_kwargs_list}.[/red]" + ) + else: + console.print( + f"[red]API '{api}' was not recognized. Please check get_keys_info().[/red]" + ) + + return status_dict + + +def get_keys_info() -> Dict[str, List[str]]: + """Get info on available APIs to use in set_keys. + + Returns + ------- + Dictionary of expected API keys and arguments: Dict[str, List[str]] + + """ + args_dict = {} + + for api in API_DICT: + arg_list = list( + getattr( + sys.modules[__name__], "set_" + str(api) + "_key" + ).__code__.co_varnames + ) + arg_list.remove("persist") + arg_list.remove("show_output") + args_dict[api] = arg_list + + return args_dict + + def set_key(env_var_name: str, env_var_value: str, persist: bool = False) -> None: """Set API key. diff --git a/tests/openbb_terminal/test_featflags_controller.py b/tests/openbb_terminal/test_featflags_controller.py index 078a1defc5c..eee90b0de3f 100644 --- a/tests/openbb_terminal/test_featflags_controller.py +++ b/tests/openbb_terminal/test_featflags_controller.py @@ -37,10 +37,6 @@ def test_call_promptkit(controller): controller.call_promptkit(None) -def test_call_predict(controller): - controller.call_predict(None) - - def test_call_thoughts(controller): controller.call_thoughts(None)