From cc96db76f0f985a05aef0ad9eb80d02372e12b3c Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 11 Dec 2021 15:53:44 +0100 Subject: [PATCH] Add possibility to delete pairs from the pairlist via api --- freqtrade/rpc/api_server/api_v1.py | 9 ++++++++- freqtrade/rpc/rpc.py | 14 ++++++++++++++ tests/rpc/test_rpc_apiserver.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/freqtrade/rpc/api_server/api_v1.py b/freqtrade/rpc/api_server/api_v1.py index 721d5dbc0..45225fe67 100644 --- a/freqtrade/rpc/api_server/api_v1.py +++ b/freqtrade/rpc/api_server/api_v1.py @@ -3,7 +3,7 @@ from copy import deepcopy from pathlib import Path from typing import List, Optional -from fastapi import APIRouter, Depends +from fastapi import APIRouter, Depends, Query from fastapi.exceptions import HTTPException from freqtrade import __version__ @@ -157,6 +157,13 @@ def blacklist_post(payload: BlacklistPayload, rpc: RPC = Depends(get_rpc)): return rpc._rpc_blacklist(payload.blacklist) +@router.delete('/blacklist', response_model=BlacklistResponse, tags=['info', 'pairlist']) +def blacklist_delete(pairs_to_delete: List[str] = Query([]), rpc: RPC = Depends(get_rpc)): + """Provide a list of pairs to delete from the blacklist""" + + return rpc._rpc_blacklist_delete(pairs_to_delete) + + @router.get('/whitelist', response_model=WhitelistResponse, tags=['info', 'pairlist']) def whitelist(rpc: RPC = Depends(get_rpc)): return rpc._rpc_whitelist() diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index b3728d67a..3328af30b 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -860,6 +860,20 @@ class RPC: } return res + def _rpc_blacklist_delete(self, delete: List[str]) -> Dict: + """ Removes pairs from currently active blacklist """ + errors = {} + for pair in delete: + if pair in self._freqtrade.pairlists.blacklist: + self._freqtrade.pairlists.blacklist.remove(pair) + else: + errors[pair] = { + 'error_msg': f"Pair {pair} is not in the current blacklist." + } + resp = self._rpc_blacklist() + resp['errors'] = errors + return resp + def _rpc_blacklist(self, add: List[str] = None) -> Dict: """ Returns the currently active blacklist""" errors = {} diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 883a33e38..231b17e9c 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -955,6 +955,35 @@ def test_api_blacklist(botclient, mocker): "errors": {}, } + rc = client_delete(client, f"{BASE_URI}/blacklist?pairs_to_delete=DOGE/BTC") + assert_response(rc) + assert rc.json() == {"blacklist": ["HOT/BTC", "ETH/BTC", "XRP/.*"], + "blacklist_expanded": ["ETH/BTC", "XRP/BTC", "XRP/USDT"], + "length": 3, + "method": ["StaticPairList"], + "errors": {}, + } + + rc = client_delete(client, f"{BASE_URI}/blacklist?pairs_to_delete=NOTHING/BTC") + assert_response(rc) + assert rc.json() == {"blacklist": ["HOT/BTC", "ETH/BTC", "XRP/.*"], + "blacklist_expanded": ["ETH/BTC", "XRP/BTC", "XRP/USDT"], + "length": 3, + "method": ["StaticPairList"], + "errors": { + "NOTHING/BTC": { + "error_msg": "Pair NOTHING/BTC is not in the current blacklist." + } + }, + } + rc = client_delete(client, f"{BASE_URI}/blacklist?pairs_to_delete=HOT/BTC&pairs_to_delete=ETH/BTC") + assert_response(rc) + assert rc.json() == {"blacklist": ["XRP/.*"], + "blacklist_expanded": ["XRP/BTC", "XRP/USDT"], + "length": 1, + "method": ["StaticPairList"], + "errors": {}, + } def test_api_whitelist(botclient): ftbot, client = botclient