From ef3a7d5c9245248496756f0841a91010ef1b10da Mon Sep 17 00:00:00 2001 From: David Arena Date: Mon, 16 Dec 2024 00:56:34 +0100 Subject: [PATCH] feat: api_server and client supporting list_custom_data --- freqtrade/rpc/api_server/api_schemas.py | 3 ++ freqtrade/rpc/api_server/api_v1.py | 6 ++++ freqtrade/rpc/rpc.py | 33 +++++++++++++------- ft_client/freqtrade_client/ft_rest_client.py | 16 ++++++++++ 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/freqtrade/rpc/api_server/api_schemas.py b/freqtrade/rpc/api_server/api_schemas.py index 97770ba13..5d31c1d99 100644 --- a/freqtrade/rpc/api_server/api_schemas.py +++ b/freqtrade/rpc/api_server/api_schemas.py @@ -617,3 +617,6 @@ class Health(BaseModel): bot_start_ts: int | None = None bot_startup: datetime | None = None bot_startup_ts: int | None = None + +class ListCustomData(BaseModel): + custom_data: list[dict[str, Any]] | None = None diff --git a/freqtrade/rpc/api_server/api_v1.py b/freqtrade/rpc/api_server/api_v1.py index 552bee9cd..f8acb9e8a 100644 --- a/freqtrade/rpc/api_server/api_v1.py +++ b/freqtrade/rpc/api_server/api_v1.py @@ -27,6 +27,7 @@ from freqtrade.rpc.api_server.api_schemas import ( FreqAIModelListResponse, Health, HyperoptLossListResponse, + ListCustomData, Locks, LocksPayload, Logs, @@ -533,3 +534,8 @@ def sysinfo(): @router.get("/health", response_model=Health, tags=["info"]) def health(rpc: RPC = Depends(get_rpc)): return rpc.health() + +@router.get("/list_custom_data", response_model=ListCustomData, tags=["info"]) +def list_custom_data(trade_id: int | None = None, key: str | None = None, rpc: RPC = Depends(get_rpc)): + custom_data = rpc._rpc_list_custom_data(trade_id, key) + return ListCustomData(custom_data=custom_data) diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index ac05f8714..5b8862556 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -1097,19 +1097,28 @@ class RPC: "cancel_order_count": c_count, } - def _rpc_list_custom_data(self, trade_id: int, key: str | None) -> list[dict[str, Any]]: - # Query for trade - trade = Trade.get_trades(trade_filter=[Trade.id == trade_id]).first() - if trade is None: - return [] - # Query custom_data - custom_data = [] - if key: - data = trade.get_custom_data(key=key) - if data: - custom_data = [data] + def _rpc_list_custom_data(self, trade_id: int | None = None, key: str | None = None) -> list[dict[str, Any]]: + # Query trades based on trade_id + if trade_id: + trades = Trade.get_trades(trade_filter=[Trade.id == trade_id]).all() else: - custom_data = trade.get_all_custom_data() + # If no trade_id, get all trades + trades = Trade.get_trades().all() + + if not trades: + return [] + + # Collect custom data + custom_data = [] + for trade in trades: + if key: + data = trade.get_custom_data(key=key) + if data: + custom_data.append(data) + else: + custom_data.extend(trade.get_all_custom_data()) + + # Format the results return [ { "id": data_entry.id, diff --git a/ft_client/freqtrade_client/ft_rest_client.py b/ft_client/freqtrade_client/ft_rest_client.py index 851583ee0..a7027fa42 100755 --- a/ft_client/freqtrade_client/ft_rest_client.py +++ b/ft_client/freqtrade_client/ft_rest_client.py @@ -474,3 +474,19 @@ class FtRestClient: :return: json object """ return self._get("health") + + def list_custom_data(self, trade_id=None, key=None): + """Lists custom_data of the running bot. + + :param tradeid: Optional keyword argument - Id of the trade (can be received via status command) + :param key: Optional keyword argument - Key of the custom data + + :return: json object + """ + params = {} + if trade_id is not None: + params["trade_id"] = trade_id + if key is not None: + params["key"] = key + + return self._get("list_custom_data", params=params)