Update list-exchanges to use rich tables

This commit is contained in:
Matthias
2024-07-06 12:59:50 +02:00
parent 95097d1f51
commit b6b589b1f0
2 changed files with 48 additions and 41 deletions

View File

@@ -1,11 +1,14 @@
import csv
import logging
import sys
from typing import Any, Dict, List, Union
from typing import Any, Dict, List
import rapidjson
from colorama import Fore, Style
from colorama import init as colorama_init
from rich.console import Console
from rich.table import Table
from rich.text import Text
from tabulate import tabulate
from freqtrade.configuration import setup_utils_configuration
@@ -14,7 +17,7 @@ from freqtrade.exceptions import ConfigurationError, OperationalException
from freqtrade.exchange import list_available_exchanges, market_is_active
from freqtrade.misc import parse_db_uri_for_logging, plural
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
from freqtrade.types import ValidExchangesType
from freqtrade.types.valid_exchanges_type import ValidExchangesType
logger = logging.getLogger(__name__)
@@ -26,51 +29,55 @@ def start_list_exchanges(args: Dict[str, Any]) -> None:
:param args: Cli args from Arguments()
:return: None
"""
available_exchanges = list_available_exchanges(args["list_exchanges_all"])
available_exchanges: List[ValidExchangesType] = list_available_exchanges(
args["list_exchanges_all"]
)
if args["print_one_column"]:
print("\n".join([e["name"] for e in available_exchanges]))
else:
headers = {
"name": "Exchange name",
"supported": "Supported",
"trade_modes": "Markets",
"comment": "Reason",
}
headers.update({"valid": "Valid"} if args["list_exchanges_all"] else {})
if args["list_exchanges_all"]:
title = (
f"All exchanges supported by the ccxt library "
f"({len(available_exchanges)} exchanges):"
)
else:
available_exchanges = [e for e in available_exchanges if e["valid"] is not False]
title = f"Exchanges available for Freqtrade ({len(available_exchanges)} exchanges):"
def build_entry(exchange: ValidExchangesType, valid: bool):
valid_entry = {"valid": exchange["valid"]} if valid else {}
result: Dict[str, Union[str, bool]] = {
"name": exchange["name"],
**valid_entry,
"supported": "Official" if exchange["supported"] else "",
"trade_modes": ("DEX: " if exchange["dex"] else "")
+ ", ".join(
(f"{a['margin_mode']} " if a["margin_mode"] else "") + a["trading_mode"]
table = Table(title=title)
table.add_column("Exchange Name")
table.add_column("Markets")
table.add_column("Reason")
for exchange in available_exchanges:
name = Text(exchange["name"])
if exchange["supported"]:
name.append(" (Official)", style="italic")
name.stylize("green bold")
trade_modes = Text(
", ".join(
(f"{a.get('margin_mode', '')} {a["trading_mode"]}").lstrip()
for a in exchange["trade_modes"]
),
"comment": exchange["comment"],
}
return result
if args["list_exchanges_all"]:
exchanges = [build_entry(e, True) for e in available_exchanges]
title = f"All exchanges supported by the ccxt library ({len(exchanges)} exchanges):"
else:
exchanges = [
build_entry(e, False) for e in available_exchanges if e["valid"] is not False
]
title = f"Exchanges available for Freqtrade ({len(exchanges)} exchanges):"
print(title)
print(
tabulate(
exchanges,
headers=headers,
style="",
)
)
if exchange["dex"]:
trade_modes = Text("DEX: ") + trade_modes
trade_modes.stylize("bold", 0, 3)
table.add_row(
name,
trade_modes,
exchange["comment"],
style=None if exchange["valid"] else "red",
)
# table.add_row(*[exchange[header] for header in headers])
console = Console()
console.print(table)
def _print_objs_tabular(objs: List, print_colorized: bool) -> None:

View File

@@ -116,7 +116,7 @@ def test_list_exchanges(capsys):
start_list_exchanges(get_args(args))
captured = capsys.readouterr()
assert re.match(r"Exchanges available for Freqtrade.*", captured.out)
assert re.search(r".*Exchanges available for Freqtrade.*", captured.out)
assert re.search(r".*binance.*", captured.out)
assert re.search(r".*bybit.*", captured.out)
@@ -139,7 +139,7 @@ def test_list_exchanges(capsys):
start_list_exchanges(get_args(args))
captured = capsys.readouterr()
assert re.match(r"All exchanges supported by the ccxt library.*", captured.out)
assert re.search(r"All exchanges supported by the ccxt library.*", captured.out)
assert re.search(r".*binance.*", captured.out)
assert re.search(r".*bingx.*", captured.out)
assert re.search(r".*bitmex.*", captured.out)