diff --git a/freqtrade/rpc/api_server/api_backtest.py b/freqtrade/rpc/api_server/api_backtest.py index 6c36b641c..3fac83e1e 100644 --- a/freqtrade/rpc/api_server/api_backtest.py +++ b/freqtrade/rpc/api_server/api_backtest.py @@ -2,6 +2,7 @@ import asyncio import logging from copy import deepcopy from datetime import datetime +from pathlib import Path from typing import Any, Dict, List from fastapi import APIRouter, BackgroundTasks, Depends @@ -245,7 +246,7 @@ def api_backtest_history(config=Depends(get_config)): tags=['webserver', 'backtest']) def api_backtest_history_result(filename: str, strategy: str, config=Depends(get_config)): # Get backtest result history, read from metadata files - bt_results_base = config['user_data_dir'] / 'backtest_results' + bt_results_base: Path = config['user_data_dir'] / 'backtest_results' fn = bt_results_base / filename results: Dict[str, Any] = { 'metadata': {}, @@ -263,3 +264,23 @@ def api_backtest_history_result(filename: str, strategy: str, config=Depends(get "status_msg": "Historic result", "backtest_result": results, } + + +@router.delete('/backtest/history/{file}', response_model=List[BacktestHistoryEntry], + tags=['webserver', 'backtest']) +def api_delete_backtest_history_entry(file: str, config=Depends(get_config)): + # Get backtest result history, read from metadata files + bt_results_base: Path = config['user_data_dir'] / 'backtest_results' + file_abs = bt_results_base / file + # Ensure file is in backtest_results directory + if not is_file_in_dir(file_abs, bt_results_base): + raise HTTPException(status_code=404, detail="File not found.") + + # *.meta.json + file_abs_meta = file_abs.with_suffix('.meta.json') + logger.info(f"Deleting backtest result file: {file}") + # logger.info(f"Deleting backtest result file: {file_abs_meta}") + + file_abs.unlink() + file_abs_meta.unlink() + return get_backtest_resultlist(config['user_data_dir'] / 'backtest_results') diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index fd9508060..c37553f24 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -2014,6 +2014,34 @@ def test_api_backtest_history(botclient, mocker, testdatadir): assert result2['backtest_result']['strategy'][strategy] +def test_api_delete_backtest_history_entry(botclient, mocker, tmp_path: Path): + ftbot, client = botclient + + # Create a temporary directory and file + bt_results_base = tmp_path / "backtest_results" + bt_results_base.mkdir() + file_path = bt_results_base / "test.json" + file_path.touch() + meta_path = file_path.with_suffix('.meta.json') + meta_path.touch() + + rc = client_delete(client, f"{BASE_URI}/backtest/history/randomFile.json") + assert_response(rc, 503) + assert rc.json()['detail'] == 'Bot is not in the correct state.' + + ftbot.config['user_data_dir'] = tmp_path + ftbot.config['runmode'] = RunMode.WEBSERVER + rc = client_delete(client, f"{BASE_URI}/backtest/history/randomFile.json") + assert rc.status_code == 404 + assert rc.json()['detail'] == 'File not found.' + + rc = client_delete(client, f"{BASE_URI}/backtest/history/{file_path.name}") + assert rc.status_code == 200 + + assert not file_path.exists() + assert not meta_path.exists() + + def test_health(botclient): ftbot, client = botclient