From 74254bb8936f9da1ee0f90f89b02d77eae3664f3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 3 Jun 2023 09:20:01 +0200 Subject: [PATCH] Add /exchanges endpoint to list available exchanges --- freqtrade/rpc/api_server/api_schemas.py | 5 ++++ freqtrade/rpc/api_server/api_v1.py | 12 ++++++++- tests/rpc/test_rpc_apiserver.py | 33 +++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/freqtrade/rpc/api_server/api_schemas.py b/freqtrade/rpc/api_server/api_schemas.py index a081f9fe9..e218465fc 100644 --- a/freqtrade/rpc/api_server/api_schemas.py +++ b/freqtrade/rpc/api_server/api_schemas.py @@ -5,6 +5,7 @@ from pydantic import BaseModel from freqtrade.constants import DATETIME_PRINT_FORMAT, IntOrInf from freqtrade.enums import OrderTypeValues, SignalDirection, TradingMode +from freqtrade.types import ValidExchangesType class Ping(BaseModel): @@ -396,6 +397,10 @@ class StrategyListResponse(BaseModel): strategies: List[str] +class ExchangeListResponse(BaseModel): + exchanges: List[ValidExchangesType] + + class FreqAIModelListResponse(BaseModel): freqaimodels: List[str] diff --git a/freqtrade/rpc/api_server/api_v1.py b/freqtrade/rpc/api_server/api_v1.py index 2354c4bf8..6af6d7709 100644 --- a/freqtrade/rpc/api_server/api_v1.py +++ b/freqtrade/rpc/api_server/api_v1.py @@ -12,7 +12,8 @@ from freqtrade.exceptions import OperationalException from freqtrade.rpc import RPC from freqtrade.rpc.api_server.api_schemas import (AvailablePairs, Balances, BlacklistPayload, BlacklistResponse, Count, Daily, - DeleteLockRequest, DeleteTrade, ForceEnterPayload, + DeleteLockRequest, DeleteTrade, + ExchangeListResponse, ForceEnterPayload, ForceEnterResponse, ForceExitPayload, FreqAIModelListResponse, Health, Locks, Logs, OpenTradeSchema, PairHistory, PerformanceEntry, @@ -312,6 +313,15 @@ def get_strategy(strategy: str, config=Depends(get_config)): } +@router.get('/exchanges', response_model=ExchangeListResponse, tags=[]) +def list_exchanges(config=Depends(get_config)): + from freqtrade.exchange import list_available_exchanges + exchanges = list_available_exchanges(config) + return { + 'exchanges': exchanges, + } + + @router.get('/freqaimodels', response_model=FreqAIModelListResponse, tags=['freqai']) def list_freqaimodels(config=Depends(get_config)): from freqtrade.resolvers.freqaimodel_resolver import FreqaiModelResolver diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index cdf620b90..8377de547 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -1578,6 +1578,38 @@ def test_api_strategy(botclient): assert_response(rc, 500) +def test_api_exchanges(botclient): + ftbot, client = botclient + + rc = client_get(client, f"{BASE_URI}/exchanges") + assert_response(rc) + response = rc.json() + assert isinstance(response['exchanges'], list) + assert len(response['exchanges']) > 20 + okx = [x for x in response['exchanges'] if x['name'] == 'okx'][0] + assert okx == { + "name": "okx", + "valid": True, + "supported": True, + "comment": "", + "trade_modes": [ + "spot", + "isolated futures", + ] + } + + mexc = [x for x in response['exchanges'] if x['name'] == 'mexc'][0] + assert mexc == { + "name": "mexc", + "valid": True, + "supported": False, + "comment": "", + "trade_modes": [ + "spot", + ] + } + + def test_api_freqaimodels(botclient, tmpdir, mocker): ftbot, client = botclient ftbot.config['user_data_dir'] = Path(tmpdir) @@ -1933,3 +1965,4 @@ def test_api_ws_send_msg(default_conf, mocker, caplog): finally: ApiServer.shutdown() + ApiServer.shutdown()