diff --git a/gamestonk_terminal/cryptocurrency/crypto_controller.py b/gamestonk_terminal/cryptocurrency/crypto_controller.py index b0ece615b6d..25ee9691e70 100644 --- a/gamestonk_terminal/cryptocurrency/crypto_controller.py +++ b/gamestonk_terminal/cryptocurrency/crypto_controller.py @@ -531,19 +531,23 @@ Loaded {self.current_coin} against {self.current_currency} from {CRYPTO_SOURCES[ def call_pred(self, _): """Process pred command""" if self.current_coin: - from gamestonk_terminal.cryptocurrency.prediction_techniques import ( - pred_controller, - ) - - if self.current_interval != "1day": - console.print("Only interval `1day` is possible for now.\n") - else: - self.queue = self.load_class( - pred_controller.PredictionTechniquesController, - self.current_coin, - self.current_df, - self.queue, + try: + from gamestonk_terminal.cryptocurrency.prediction_techniques import ( + pred_controller, ) + + if self.current_interval != "1day": + console.print("Only interval `1day` is possible for now.\n") + else: + self.queue = self.load_class( + pred_controller.PredictionTechniquesController, + self.current_coin, + self.current_df, + self.queue, + ) + except ImportError: + console.print("[red]Run pip install tensorflow to continue[/red]") + else: console.print( "No coin selected. Use 'load' to load the coin you want to look at.\n" diff --git a/gamestonk_terminal/cryptocurrency/discovery/dappradar_model.py b/gamestonk_terminal/cryptocurrency/discovery/dappradar_model.py index 482679f3d0c..50eaa1f2acb 100644 --- a/gamestonk_terminal/cryptocurrency/discovery/dappradar_model.py +++ b/gamestonk_terminal/cryptocurrency/discovery/dappradar_model.py @@ -2,7 +2,7 @@ __docformat__ = "numpy" # pylint: disable=C0301,E1137 - +from typing import Optional import logging import pandas as pd @@ -10,6 +10,7 @@ import requests from gamestonk_terminal.decorators import log_start_end from gamestonk_terminal.helper_funcs import get_user_agent +from gamestonk_terminal.rich_config import console logger = logging.getLogger(__name__) @@ -38,7 +39,7 @@ DEX_COLUMNS = [ @log_start_end(log=logger) -def _make_request(url: str) -> dict: +def _make_request(url: str) -> Optional[dict]: """Helper method handles dappradar api requests. [Source: https://dappradar.com/] Parameters @@ -55,11 +56,13 @@ def _make_request(url: str) -> dict: url, headers={"Accept": "application/json", "User-Agent": get_user_agent()} ) if not 200 <= response.status_code < 300: - raise Exception(f"dappradar api exception: {response.text}") + console.print(f"[red]dappradar api exception: {response.text}[/red]") + return None try: return response.json() - except Exception as e: - raise ValueError(f"Invalid Response: {response.text}") from e + except Exception as _: # noqa: F841 + console.print(f"[red]Invalid Response:: {response.text}[/red]") + return None @log_start_end(log=logger) @@ -78,26 +81,28 @@ def get_top_nfts() -> pd.DataFrame: response = _make_request( "https://nft-sales-service.dappradar.com/v2/collection/day?limit=20&page=1¤cy=USD&sort=marketCapInFiat&order=desc" # noqa ) - data = response.get("results") - df = pd.DataFrame( - data, - columns=[ - "name", - "activeProtocols", - "floorPriceInFiat", - "avgPriceInFiat", - "marketCapInFiat", - "volumeInFiat", - ], - ) + if response: + data = response.get("results") + df = pd.DataFrame( + data, + columns=[ + "name", + "activeProtocols", + "floorPriceInFiat", + "avgPriceInFiat", + "marketCapInFiat", + "volumeInFiat", + ], + ) - df = df.set_axis( - NFT_COLUMNS, - axis=1, - inplace=False, - ) - df["Protocols"] = df["Protocols"].apply(lambda x: ",".join(x)) - return df + df = df.set_axis( + NFT_COLUMNS, + axis=1, + inplace=False, + ) + df["Protocols"] = df["Protocols"].apply(lambda x: ",".join(x)) + return df + return pd.DataFrame() @log_start_end(log=logger) @@ -115,17 +120,19 @@ def get_top_dexes() -> pd.DataFrame: data = _make_request( "https://dappradar.com/v2/api/dapps?params=WkdGd2NISmhaR0Z5Y0dGblpUMHhKbk5uY205MWNEMXRZWGdtWTNWeWNtVnVZM2s5VlZORUptWmxZWFIxY21Wa1BURW1jbUZ1WjJVOVpHRjVKbU5oZEdWbmIzSjVQV1Y0WTJoaGJtZGxjeVp6YjNKMFBYUnZkR0ZzVm05c2RXMWxTVzVHYVdGMEptOXlaR1Z5UFdSbGMyTW1iR2x0YVhROU1qWT0=" # noqa ) - arr = [] - for dex in data["dapps"]: - arr.append( - [ - dex["name"], - dex["statistic"]["userActivity"], - dex["statistic"]["totalVolumeInFiat"], - ] - ) - df = pd.DataFrame(arr, columns=DEX_COLUMNS) - return df + if data: + arr = [] + for dex in data["dapps"]: + arr.append( + [ + dex["name"], + dex["statistic"]["userActivity"], + dex["statistic"]["totalVolumeInFiat"], + ] + ) + df = pd.DataFrame(arr, columns=DEX_COLUMNS) + return df + return pd.DataFrame() @log_start_end(log=logger) @@ -143,20 +150,22 @@ def get_top_games() -> pd.DataFrame: data = _make_request( "https://dappradar.com/v2/api/dapps?params=WkdGd2NISmhaR0Z5Y0dGblpUMHhKbk5uY205MWNEMXRZWGdtWTNWeWNtVnVZM2s5VlZORUptWmxZWFIxY21Wa1BURW1jbUZ1WjJVOVpHRjVKbU5oZEdWbmIzSjVQV2RoYldWekpuTnZjblE5ZFhObGNpWnZjbVJsY2oxa1pYTmpKbXhwYldsMFBUSTI=" # noqa ) - arr = [] - for dex in data["dapps"]: - arr.append( - [ - dex["name"], - dex["statistic"]["userActivity"], - dex["statistic"]["totalVolumeInFiat"], - ] - ) - df = pd.DataFrame( - arr, - columns=DEX_COLUMNS, - ).sort_values("Daily Users", ascending=False) - return df + if data: + arr = [] + for dex in data["dapps"]: + arr.append( + [ + dex["name"], + dex["statistic"]["userActivity"], + dex["statistic"]["totalVolumeInFiat"], + ] + ) + df = pd.DataFrame( + arr, + columns=DEX_COLUMNS, + ).sort_values("Daily Users", ascending=False) + return df + return pd.DataFrame() @log_start_end(log=logger) @@ -174,20 +183,22 @@ def get_top_dapps() -> pd.DataFrame: data = _make_request( "https://dappradar.com/v2/api/dapps?params=WkdGd2NISmhaR0Z5Y0dGblpUMHhKbk5uY205MWNEMXRZWGdtWTNWeWNtVnVZM2s5VlZORUptWmxZWFIxY21Wa1BURW1jbUZ1WjJVOVpHRjVKbk52Y25ROWRYTmxjaVp2Y21SbGNqMWtaWE5qSm14cGJXbDBQVEky" # noqa ) - arr = [] - for dex in data["dapps"]: - arr.append( - [ - dex["name"], - dex["category"], - dex["activeProtocols"], - dex["statistic"]["userActivity"], - dex["statistic"]["totalVolumeInFiat"], - ] - ) - df = pd.DataFrame( - arr, - columns=DAPPS_COLUMNS, - ).sort_values("Daily Users", ascending=False) - df["Protocols"] = df["Protocols"].apply(lambda x: ",".join(x)) - return df + if data: + arr = [] + for dex in data["dapps"]: + arr.append( + [ + dex["name"], + dex["category"], + dex["activeProtocols"], + dex["statistic"]["userActivity"], + dex["statistic"]["totalVolumeInFiat"], + ] + ) + df = pd.DataFrame( + arr, + columns=DAPPS_COLUMNS, + ).sort_values("Daily Users", ascending=False) + df["Protocols"] = df["Protocols"].apply(lambda x: ",".join(x)) + return df + return pd.DataFrame() diff --git a/gamestonk_terminal/cryptocurrency/onchain/bitquery_model.py b/gamestonk_terminal/cryptocurrency/onchain/bitquery_model.py index 988d0a86230..e019a98d7b8 100644 --- a/gamestonk_terminal/cryptocurrency/onchain/bitquery_model.py +++ b/gamestonk_terminal/cryptocurrency/onchain/bitquery_model.py @@ -14,6 +14,7 @@ from requests.adapters import HTTPAdapter from requests.exceptions import HTTPError from gamestonk_terminal import config_terminal as cfg +from gamestonk_terminal.rich_config import console from gamestonk_terminal.decorators import log_start_end logger = logging.getLogger(__name__) @@ -297,7 +298,10 @@ def get_dex_trades_by_exchange( }} """ - data = query_graph(BQ_URL, query) + try: + data = query_graph(BQ_URL, query) + except BitQueryApiKeyException: + console.print("[red]Invalid API Key[/red]\n") df = _extract_dex_trades(data) df.columns = ["trades", "tradeAmount", "exchange"] @@ -351,8 +355,11 @@ def get_dex_trades_monthly( }} }} """ - - data = query_graph(BQ_URL, query) + try: + data = query_graph(BQ_URL, query) + except BitQueryApiKeyException: + console.print("[red]Invalid API Key[/red]\n") + return pd.DataFrame() if not data: return pd.DataFrame() @@ -428,7 +435,12 @@ def get_daily_dex_volume_for_given_pair( }} """ - data = query_graph(BQ_URL, query) + try: + data = query_graph(BQ_URL, query) + except BitQueryApiKeyException: + console.print("[red]Invalid API Key[/red]\n") + return pd.DataFrame() + if not data: return pd.DataFrame() @@ -509,8 +521,12 @@ def get_token_volume_on_dexes( }} """ + try: + data = query_graph(BQ_URL, query) + except BitQueryApiKeyException: + console.print("[red]Invalid API Key[/red]\n") + return pd.DataFrame() - data = query_graph(BQ_URL, query) if not data: return pd.DataFrame() @@ -568,7 +584,11 @@ def get_ethereum_unique_senders(interval: str = "day", limit: int = 90) -> pd.Da }} """ - data = query_graph(BQ_URL, query) + try: + data = query_graph(BQ_URL, query) + except BitQueryApiKeyException: + console.print("[red]Invalid API Key[/red]\n") + return pd.DataFrame() if not data: return pd.DataFrame() @@ -618,7 +638,11 @@ def get_most_traded_pairs( }} }} """ - data = query_graph(BQ_URL, query) + try: + data = query_graph(BQ_URL, query) + except BitQueryApiKeyException: + console.print("[red]Invalid API Key[/red]\n") + return pd.DataFrame() if not data: return pd.DataFrame() @@ -676,7 +700,11 @@ def get_spread_for_crypto_pair( }} }} """ - data = query_graph(BQ_URL, query) + try: + data = query_graph(BQ_URL, query) + except BitQueryApiKeyException: + console.print("[red]Invalid API Key[/red]\n") + return pd.DataFrame() if not data: return pd.DataFrame() diff --git a/gamestonk_terminal/cryptocurrency/onchain/bitquery_view.py b/gamestonk_terminal/cryptocurrency/onchain/bitquery_view.py index 1db3d37f3f3..df6e14e7c51 100644 --- a/gamestonk_terminal/cryptocurrency/onchain/bitquery_view.py +++ b/gamestonk_terminal/cryptocurrency/onchain/bitquery_view.py @@ -49,33 +49,36 @@ def display_dex_trades( if kind == "time": df = bitquery_model.get_dex_trades_monthly(trade_amount_currency, days) - df = df.sort_values(by="date", ascending=descend) + if not df.empty: + df = df.sort_values(by="date", ascending=descend) else: df = bitquery_model.get_dex_trades_by_exchange(trade_amount_currency, days) - df = df.sort_values(by=sortby, ascending=descend) + if not df.empty: + df = df.sort_values(by=sortby, ascending=descend) - df_data = df.copy() + if not df.empty: + df_data = df.copy() - df[["tradeAmount", "trades"]] = df[["tradeAmount", "trades"]].applymap( - lambda x: very_long_number_formatter(x) - ) + df[["tradeAmount", "trades"]] = df[["tradeAmount", "trades"]].applymap( + lambda x: very_long_number_formatter(x) + ) - df.columns = prettify_column_names(df.columns) + df.columns = prettify_column_names(df.columns) - print_rich_table( - df.head(top), - headers=list(df.columns), - show_index=False, - title="Trades on Decentralized Exchanges", - ) - console.print("") + print_rich_table( + df.head(top), + headers=list(df.columns), + show_index=False, + title="Trades on Decentralized Exchanges", + ) + console.print("") - export_data( - export, - os.path.dirname(os.path.abspath(__file__)), - "lt", - df_data, - ) + export_data( + export, + os.path.dirname(os.path.abspath(__file__)), + "lt", + df_data, + ) @log_start_end(log=logger) @@ -175,31 +178,32 @@ def display_dex_volume_for_token( """ df = bitquery_model.get_token_volume_on_dexes( - token=token, - trade_amount_currency=trade_amount_currency, - ).sort_values(by=sortby, ascending=descend) - - df_data = df.copy() - df[["tradeAmount", "trades"]] = df[["tradeAmount", "trades"]].applymap( - lambda x: very_long_number_formatter(x) + token=token, trade_amount_currency=trade_amount_currency ) + if not df.empty: + df = df.sort_values(by=sortby, ascending=descend) - df.columns = prettify_column_names(df.columns) + df_data = df.copy() + df[["tradeAmount", "trades"]] = df[["tradeAmount", "trades"]].applymap( + lambda x: very_long_number_formatter(x) + ) - print_rich_table( - df.head(top), - headers=list(df.columns), - show_index=False, - title="Token Volume on Exchanges", - ) - console.print("") + df.columns = prettify_column_names(df.columns) - export_data( - export, - os.path.dirname(os.path.abspath(__file__)), - "tv", - df_data, - ) + print_rich_table( + df.head(top), + headers=list(df.columns), + show_index=False, + title="Token Volume on Exchanges", + ) + console.print("") + + export_data( + export, + os.path.dirname(os.path.abspath(__file__)), + "tv", + df_data, + ) @log_start_end(log=logger) @@ -234,31 +238,32 @@ def display_ethereum_unique_senders( Number of unique ethereum addresses which made a transaction in given time interval """ - df = bitquery_model.get_ethereum_unique_senders(interval, limit).sort_values( - by=sortby, ascending=descend - ) + df = bitquery_model.get_ethereum_unique_senders(interval, limit) + if not df.empty: - df[["uniqueSenders", "transactions", "maximumGasPrice"]] = df[ - ["uniqueSenders", "transactions", "maximumGasPrice"] - ].applymap(lambda x: very_long_number_formatter(x)) + df = df.sort_values(by=sortby, ascending=descend) - df_data = df.copy() - df.columns = prettify_column_names(df.columns) + df[["uniqueSenders", "transactions", "maximumGasPrice"]] = df[ + ["uniqueSenders", "transactions", "maximumGasPrice"] + ].applymap(lambda x: very_long_number_formatter(x)) - print_rich_table( - df, - headers=list(df.columns), - show_index=False, - title="Unique Ethereum Addresses", - ) - console.print("") + df_data = df.copy() + df.columns = prettify_column_names(df.columns) - export_data( - export, - os.path.dirname(os.path.abspath(__file__)), - "ueat", - df_data, - ) + print_rich_table( + df, + headers=list(df.columns), + show_index=False, + title="Unique Ethereum Addresses", + ) + console.print("") + + export_data( + export, + os.path.dirname(os.path.abspath(__file__)), + "ueat", + df_data, + ) @log_start_end(log=logger) @@ -291,29 +296,29 @@ def display_most_traded_pairs( Most traded crypto pairs on given decentralized exchange in chosen time period. """ - df = bitquery_model.get_most_traded_pairs( - exchange=exchange, limit=days - ).sort_values(by=sortby, ascending=descend) - df_data = df.copy() - df[["tradeAmount", "trades"]] = df[["tradeAmount", "trades"]].applymap( - lambda x: very_long_number_formatter(x) - ) - df.columns = prettify_column_names(df.columns) + df = bitquery_model.get_most_traded_pairs(exchange=exchange, limit=days) + if not df.empty: + df = df.sort_values(by=sortby, ascending=descend) + df_data = df.copy() + df[["tradeAmount", "trades"]] = df[["tradeAmount", "trades"]].applymap( + lambda x: very_long_number_formatter(x) + ) + df.columns = prettify_column_names(df.columns) - print_rich_table( - df.head(top), - headers=list(df.columns), - show_index=False, - title="Most Traded Crypto Pairs", - ) - console.print("") + print_rich_table( + df.head(top), + headers=list(df.columns), + show_index=False, + title="Most Traded Crypto Pairs", + ) + console.print("") - export_data( - export, - os.path.dirname(os.path.abspath(__file__)), - "ttcp", - df_data, - ) + export_data( + export, + os.path.dirname(os.path.abspath(__file__)), + "ttcp", + df_data, + ) @log_start_end(log=logger) @@ -349,23 +354,23 @@ def display_spread_for_crypto_pair( Average bid and ask prices, spread for given crypto pair for chosen time period """ - df = bitquery_model.get_spread_for_crypto_pair( - token=token, vs=vs, limit=days - ).sort_values(by=sortby, ascending=descend) + df = bitquery_model.get_spread_for_crypto_pair(token=token, vs=vs, limit=days) + if not df.empty: + df = df.sort_values(by=sortby, ascending=descend) - df.columns = prettify_column_names(df.columns) + df.columns = prettify_column_names(df.columns) - print_rich_table( - df, - headers=list(df.columns), - show_index=False, - title="Average Spread for Given Crypto", - ) - console.print("") + print_rich_table( + df, + headers=list(df.columns), + show_index=False, + title="Average Spread for Given Crypto", + ) + console.print("") - export_data( - export, - os.path.dirname(os.path.abspath(__file__)), - "baas", - df, - ) + export_data( + export, + os.path.dirname(os.path.abspath(__file__)), + "baas", + df, + ) diff --git a/gamestonk_terminal/cryptocurrency/overview/cryptopanic_model.py b/gamestonk_terminal/cryptocurrency/overview/cryptopanic_model.py index ff953cc8f42..7588181230c 100644 --- a/gamestonk_terminal/cryptocurrency/overview/cryptopanic_model.py +++ b/gamestonk_terminal/cryptocurrency/overview/cryptopanic_model.py @@ -11,6 +11,7 @@ import pandas as pd import requests import gamestonk_terminal.config_terminal as cfg +from gamestonk_terminal.rich_config import console from gamestonk_terminal.decorators import log_start_end logger = logging.getLogger(__name__) @@ -52,7 +53,7 @@ class ApiKeyException(Exception): @log_start_end(log=logger) -def make_request(**kwargs: Any) -> dict: +def make_request(**kwargs: Any) -> Optional[dict]: """Helper methods for requests [Source: https://cryptopanic.com/developers/api/] Parameters @@ -94,12 +95,14 @@ def make_request(**kwargs: Any) -> dict: response = requests.get(url) if not 200 <= response.status_code < 300: - raise ApiKeyException(f"Invalid Authentication: {response.text}") + console.print(f"[red]Invalid Authentication: {response.text}[/red]") + return None try: return response.json() - except Exception as e: - raise ValueError(f"Invalid Response: {response.text}") from e + except Exception as _: # noqa: F841 + console.print(f"[red]Invalid Response: {response.text}[/red]") + return None @log_start_end(log=logger) @@ -162,35 +165,41 @@ def get_news( response = make_request(post_kind=post_kind, filter_=filter_, region=region) - data, next_page, _ = ( - response["results"], - response.get("next"), - response.get("count"), - ) - - for post in data: - results.append(_parse_post(post)) - - number_of_pages = math.ceil(limit // 20) - counter = 0 - while counter < number_of_pages and next_page: - counter += 1 - try: - time.sleep(0.2) - res = requests.get(next_page).json() - for post in res["results"]: - results.append(_parse_post(post)) - next_page = res.get("next") - except Exception as e: - raise ValueError( - "Something went wrong while fetching news from API\n" - ) from e - - try: - df = pd.DataFrame(results) - df["title"] = df["title"].apply( - lambda x: "\n".join(textwrap.wrap(x, width=66)) if isinstance(x, str) else x + if response: + data, next_page, _ = ( + response["results"], + response.get("next"), + response.get("count"), ) - return df - except Exception as e: - raise ValueError("Something went wrong with DataFrame creation\n") from e + + for post in data: + results.append(_parse_post(post)) + + number_of_pages = math.ceil(limit // 20) + counter = 0 + while counter < number_of_pages and next_page: + counter += 1 + try: + time.sleep(0.2) + res = requests.get(next_page).json() + for post in res["results"]: + results.append(_parse_post(post)) + next_page = res.get("next") + except Exception as _: # noqa: F841 + console.print( + "[red]Something went wrong while fetching news from API[/red]\n" + ) + return pd.DataFrame() + + try: + df = pd.DataFrame(results) + df["title"] = df["title"].apply( + lambda x: "\n".join(textwrap.wrap(x, width=66)) + if isinstance(x, str) + else x + ) + return df + except Exception as _: # noqa: F841 + console.print("[red]Something went wrong with DataFrame creation[/red]\n") + return pd.DataFrame() + return pd.DataFrame() diff --git a/gamestonk_terminal/cryptocurrency/overview/cryptopanic_view.py b/gamestonk_terminal/cryptocurrency/overview/cryptopanic_view.py index c4fc50a1265..bc4fdd26bf9 100644 --- a/gamestonk_terminal/cryptocurrency/overview/cryptopanic_view.py +++ b/gamestonk_terminal/cryptocurrency/overview/cryptopanic_view.py @@ -49,24 +49,25 @@ def display_news( df = cryptopanic_model.get_news( limit=top, post_kind=post_kind, filter_=filter_, region=region - ).sort_values(by=sortby, ascending=descend) - - if not links: - df.drop("link", axis=1, inplace=True) - else: - df = df[["title", "link"]] - - print_rich_table( - df.head(top), - headers=list(df.columns), - show_index=False, - title="Recent CryptoPanic Posts", ) - console.print("") + if not df.empty: + df = df.sort_values(by=sortby, ascending=descend) + if not links: + df.drop("link", axis=1, inplace=True) + else: + df = df[["title", "link"]] - export_data( - export, - os.path.dirname(os.path.abspath(__file__)), - "news", - df, - ) + print_rich_table( + df.head(top), + headers=list(df.columns), + show_index=False, + title="Recent CryptoPanic Posts", + ) + console.print("") + + export_data( + export, + os.path.dirname(os.path.abspath(__file__)), + "news", + df, + ) diff --git a/scripts/test_crypto_disc.gst b/scripts/test_crypto_disc.gst index e7895d61e68..9c0b7a4c27e 100644 --- a/scripts/test_crypto_disc.gst +++ b/scripts/test_crypto_disc.gst @@ -1,4 +1,5 @@ crypto +disc cgtop cgtop stablecoins cgtrending diff --git a/tests/gamestonk_terminal/cryptocurrency/discovery/txt/test_dappradar_model/test__make_request_status_400.txt b/tests/gamestonk_terminal/cryptocurrency/discovery/txt/test_dappradar_model/test__make_request_status_400.txt new file mode 100644 index 00000000000..a4cf2a01dc4 --- /dev/null +++ b/tests/gamestonk_terminal/cryptocurrency/discovery/txt/test_dappradar_model/test__make_request_status_400.txt @@ -0,0 +1 @@ +[red]dappradar api exception: MOCK_TEXT[/red] diff --git a/tests/gamestonk_terminal/cryptocurrency/discovery/txt/test_dappradar_model/test__make_request_value_error.txt b/tests/gamestonk_terminal/cryptocurrency/discovery/txt/test_dappradar_model/test__make_request_value_error.txt new file mode 100644 index 00000000000..88346a193eb --- /dev/null +++ b/tests/gamestonk_terminal/cryptocurrency/discovery/txt/test_dappradar_model/test__make_request_value_error.txt @@ -0,0 +1 @@ +[red]Invalid Response:: MOCK_TEXT[/red]