Improved crypto handling (#1279)

* Improved crypto handling

* Fixed some tests

* Fixed some tests

* Fixed flake8

* Updated to fix tests

Co-authored-by: didierlopes.eth <dro.lopes@campus.fct.unl.pt>
This commit is contained in:
Colin Delahunty
2022-02-01 11:56:51 -05:00
committed by GitHub
parent e2299132d8
commit 571e5281e3
9 changed files with 301 additions and 240 deletions

View File

@@ -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"

View File

@@ -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&currency=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()

View File

@@ -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()

View File

@@ -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,
)

View File

@@ -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()

View File

@@ -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,
)

View File

@@ -1,4 +1,5 @@
crypto
disc
cgtop
cgtop stablecoins
cgtrending

View File

@@ -0,0 +1 @@
[red]dappradar api exception: MOCK_TEXT[/red]

View File

@@ -0,0 +1 @@
[red]Invalid Response:: MOCK_TEXT[/red]