diff --git a/freqtrade/rpc/api_server/api_backtest.py b/freqtrade/rpc/api_server/api_backtest.py index 28566a89b..485c74119 100644 --- a/freqtrade/rpc/api_server/api_backtest.py +++ b/freqtrade/rpc/api_server/api_backtest.py @@ -125,7 +125,7 @@ def __run_backtest_bg(btconfig: Config): ApiBG.bgtask_running = False -@router.post("/backtest", response_model=BacktestResponse, tags=["backtest"]) +@router.post("/backtest", response_model=BacktestResponse) async def api_start_backtest( bt_settings: BacktestRequest, background_tasks: BackgroundTasks, config=Depends(get_config) ): @@ -168,7 +168,7 @@ async def api_start_backtest( } -@router.get("/backtest", response_model=BacktestResponse, tags=["backtest"]) +@router.get("/backtest", response_model=BacktestResponse) def api_get_backtest(): """ Get backtesting result. @@ -215,7 +215,7 @@ def api_get_backtest(): } -@router.delete("/backtest", response_model=BacktestResponse, tags=["backtest"]) +@router.delete("/backtest", response_model=BacktestResponse) def api_delete_backtest(): """Reset backtesting""" if ApiBG.bgtask_running: @@ -242,7 +242,7 @@ def api_delete_backtest(): } -@router.get("/backtest/abort", response_model=BacktestResponse, tags=["backtest"]) +@router.get("/backtest/abort", response_model=BacktestResponse) def api_backtest_abort(): if not ApiBG.bgtask_running: return { @@ -262,13 +262,13 @@ def api_backtest_abort(): } -@router.get("/backtest/history", response_model=list[BacktestHistoryEntry], tags=["backtest"]) +@router.get("/backtest/history", response_model=list[BacktestHistoryEntry]) def api_backtest_history(config=Depends(get_config)): # Get backtest result history, read from metadata files return get_backtest_resultlist(config["user_data_dir"] / "backtest_results") -@router.get("/backtest/history/result", response_model=BacktestResponse, tags=["backtest"]) +@router.get("/backtest/history/result", response_model=BacktestResponse) def api_backtest_history_result(filename: str, strategy: str, config=Depends(get_config)): # Get backtest result history, read from metadata files bt_results_base: Path = config["user_data_dir"] / "backtest_results" @@ -295,9 +295,7 @@ def api_backtest_history_result(filename: str, strategy: str, config=Depends(get } -@router.delete( - "/backtest/history/{file}", response_model=list[BacktestHistoryEntry], tags=["backtest"] -) +@router.delete("/backtest/history/{file}", response_model=list[BacktestHistoryEntry]) 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" @@ -313,9 +311,7 @@ def api_delete_backtest_history_entry(file: str, config=Depends(get_config)): return get_backtest_resultlist(config["user_data_dir"] / "backtest_results") -@router.patch( - "/backtest/history/{file}", response_model=list[BacktestHistoryEntry], tags=["backtest"] -) +@router.patch("/backtest/history/{file}", response_model=list[BacktestHistoryEntry]) def api_update_backtest_history_entry( file: str, body: BacktestMetadataUpdate, config=Depends(get_config) ): @@ -338,9 +334,7 @@ def api_update_backtest_history_entry( return get_backtest_result(file_abs) -@router.get( - "/backtest/history/{file}/market_change", response_model=BacktestMarketChange, tags=["backtest"] -) +@router.get("/backtest/history/{file}/market_change", response_model=BacktestMarketChange) def api_get_backtest_market_change(file: str, config=Depends(get_config)): bt_results_base: Path = config["user_data_dir"] / "backtest_results" for fn in ( diff --git a/freqtrade/rpc/api_server/api_pair_history.py b/freqtrade/rpc/api_server/api_pair_history.py index 31fd86f46..1409c7672 100644 --- a/freqtrade/rpc/api_server/api_pair_history.py +++ b/freqtrade/rpc/api_server/api_pair_history.py @@ -15,7 +15,7 @@ logger = logging.getLogger(__name__) router = APIRouter() -@router.get("/pair_history", response_model=PairHistory, tags=["candle data"]) +@router.get("/pair_history", response_model=PairHistory, tags=["Candle data"]) def pair_history( pair: str, timeframe: str, @@ -43,7 +43,7 @@ def pair_history( raise HTTPException(status_code=502, detail=str(e)) -@router.post("/pair_history", response_model=PairHistory, tags=["candle data"]) +@router.post("/pair_history", response_model=PairHistory, tags=["Candle data"]) def pair_history_filtered(payload: PairHistoryRequest, config=Depends(get_config)): # The initial call to this endpoint can be slow, as it may need to initialize # the exchange class. diff --git a/freqtrade/rpc/api_server/api_pairlists.py b/freqtrade/rpc/api_server/api_pairlists.py index 09f3ff732..4cca65ab9 100644 --- a/freqtrade/rpc/api_server/api_pairlists.py +++ b/freqtrade/rpc/api_server/api_pairlists.py @@ -25,7 +25,7 @@ logger = logging.getLogger(__name__) router = APIRouter() -@router.get("/pairlists/available", response_model=PairListsResponse, tags=["pairlists"]) +@router.get("/pairlists/available", response_model=PairListsResponse) def list_pairlists(config=Depends(get_config)): from freqtrade.resolvers import PairListResolver @@ -70,7 +70,7 @@ def __run_pairlist(job_id: str, config_loc: Config): ApiBG.pairlist_running = False -@router.post("/pairlists/evaluate", response_model=BgJobStarted, tags=["pairlists"]) +@router.post("/pairlists/evaluate", response_model=BgJobStarted) def pairlists_evaluate( payload: PairListsPayload, background_tasks: BackgroundTasks, config=Depends(get_config) ): @@ -124,11 +124,7 @@ def handleExchangePayload(payload: ExchangeModePayloadMixin, config_loc: Config) config_loc["margin_mode"] = payload.margin_mode -@router.get( - "/pairlists/evaluate/{jobid}", - response_model=WhitelistEvaluateResponse, - tags=["pairlists"], -) +@router.get("/pairlists/evaluate/{jobid}", response_model=WhitelistEvaluateResponse) def pairlists_evaluate_get(jobid: str): if not (job := ApiBG.jobs.get(jobid)): raise HTTPException(status_code=404, detail="Job not found.") diff --git a/freqtrade/rpc/api_server/api_trading.py b/freqtrade/rpc/api_server/api_trading.py index aaae0e783..3ec7a08b3 100644 --- a/freqtrade/rpc/api_server/api_trading.py +++ b/freqtrade/rpc/api_server/api_trading.py @@ -42,7 +42,7 @@ logger = logging.getLogger(__name__) router = APIRouter() -@router.get("/balance", response_model=Balances, tags=["trading-info"]) +@router.get("/balance", response_model=Balances, tags=["Trading-info"]) def balance(rpc: RPC = Depends(get_rpc), config=Depends(get_config)): """Account Balances""" return rpc._rpc_balance( @@ -51,37 +51,37 @@ def balance(rpc: RPC = Depends(get_rpc), config=Depends(get_config)): ) -@router.get("/count", response_model=Count, tags=["trading-info"]) +@router.get("/count", response_model=Count, tags=["Trading-info"]) def count(rpc: RPC = Depends(get_rpc)): return rpc._rpc_count() -@router.get("/entries", response_model=list[Entry], tags=["trading-info"]) +@router.get("/entries", response_model=list[Entry], tags=["Trading-info"]) def entries(pair: str | None = None, rpc: RPC = Depends(get_rpc)): return rpc._rpc_enter_tag_performance(pair) -@router.get("/exits", response_model=list[Exit], tags=["trading-info"]) +@router.get("/exits", response_model=list[Exit], tags=["Trading-info"]) def exits(pair: str | None = None, rpc: RPC = Depends(get_rpc)): return rpc._rpc_exit_reason_performance(pair) -@router.get("/mix_tags", response_model=list[MixTag], tags=["trading-info"]) +@router.get("/mix_tags", response_model=list[MixTag], tags=["Trading-info"]) def mix_tags(pair: str | None = None, rpc: RPC = Depends(get_rpc)): return rpc._rpc_mix_tag_performance(pair) -@router.get("/performance", response_model=list[PerformanceEntry], tags=["trading-info"]) +@router.get("/performance", response_model=list[PerformanceEntry], tags=["Trading-info"]) def performance(rpc: RPC = Depends(get_rpc)): return rpc._rpc_performance() -@router.get("/profit", response_model=Profit, tags=["trading-info"]) +@router.get("/profit", response_model=Profit, tags=["Trading-info"]) def profit(rpc: RPC = Depends(get_rpc), config=Depends(get_config)): return rpc._rpc_trade_statistics(config["stake_currency"], config.get("fiat_display_currency")) -@router.get("/profit_all", response_model=ProfitAll, tags=["trading-info"]) +@router.get("/profit_all", response_model=ProfitAll, tags=["Trading-info"]) def profit_all(rpc: RPC = Depends(get_rpc), config=Depends(get_config)): response = { "all": rpc._rpc_trade_statistics( @@ -99,12 +99,12 @@ def profit_all(rpc: RPC = Depends(get_rpc), config=Depends(get_config)): return response -@router.get("/stats", response_model=Stats, tags=["trading-info"]) +@router.get("/stats", response_model=Stats, tags=["Trading-info"]) def stats(rpc: RPC = Depends(get_rpc)): return rpc._rpc_stats() -@router.get("/daily", response_model=DailyWeeklyMonthly, tags=["trading-info"]) +@router.get("/daily", response_model=DailyWeeklyMonthly, tags=["Trading-info"]) def daily( timescale: int = Query(7, ge=1, description="Number of days to fetch data for"), rpc: RPC = Depends(get_rpc), @@ -115,7 +115,7 @@ def daily( ) -@router.get("/weekly", response_model=DailyWeeklyMonthly, tags=["trading-info"]) +@router.get("/weekly", response_model=DailyWeeklyMonthly, tags=["Trading-info"]) def weekly( timescale: int = Query(4, ge=1, description="Number of weeks to fetch data for"), rpc: RPC = Depends(get_rpc), @@ -126,7 +126,7 @@ def weekly( ) -@router.get("/monthly", response_model=DailyWeeklyMonthly, tags=["trading-info"]) +@router.get("/monthly", response_model=DailyWeeklyMonthly, tags=["Trading-info"]) def monthly( timescale: int = Query(3, ge=1, description="Number of months to fetch data for"), rpc: RPC = Depends(get_rpc), @@ -137,7 +137,7 @@ def monthly( ) -@router.get("/status", response_model=list[OpenTradeSchema], tags=["trading-info"]) +@router.get("/status", response_model=list[OpenTradeSchema], tags=["Trading-info"]) def status(rpc: RPC = Depends(get_rpc)): try: return rpc._rpc_trade_status() @@ -147,7 +147,7 @@ def status(rpc: RPC = Depends(get_rpc)): # Using the responsemodel here will cause a ~100% increase in response time (from 1s to 2s) # on big databases. Correct response model: response_model=TradeResponse, -@router.get("/trades", tags=["trading-info", "trades"]) +@router.get("/trades", tags=["Trading-info", "Trades"]) def trades( limit: int = Query(500, ge=1, description="Maximum number of different trades to return data"), offset: int = Query(0, ge=0, description="Number of trades to skip for pagination"), @@ -159,7 +159,7 @@ def trades( return rpc._rpc_trade_history(limit, offset=offset, order_by_id=order_by_id) -@router.get("/trade/{tradeid}", response_model=OpenTradeSchema, tags=["trades"]) +@router.get("/trade/{tradeid}", response_model=OpenTradeSchema, tags=["Trades"]) def trade(tradeid: int = 0, rpc: RPC = Depends(get_rpc)): try: return rpc._rpc_trade_status([tradeid])[0] @@ -167,24 +167,24 @@ def trade(tradeid: int = 0, rpc: RPC = Depends(get_rpc)): raise HTTPException(status_code=404, detail="Trade not found.") -@router.delete("/trades/{tradeid}", response_model=DeleteTrade, tags=["trades"]) +@router.delete("/trades/{tradeid}", response_model=DeleteTrade, tags=["Trades"]) def trades_delete(tradeid: int, rpc: RPC = Depends(get_rpc)): return rpc._rpc_delete(tradeid) -@router.delete("/trades/{tradeid}/open-order", response_model=OpenTradeSchema, tags=["trades"]) +@router.delete("/trades/{tradeid}/open-order", response_model=OpenTradeSchema, tags=["Trades"]) def trade_cancel_open_order(tradeid: int, rpc: RPC = Depends(get_rpc)): rpc._rpc_cancel_open_order(tradeid) return rpc._rpc_trade_status([tradeid])[0] -@router.post("/trades/{tradeid}/reload", response_model=OpenTradeSchema, tags=["trades"]) +@router.post("/trades/{tradeid}/reload", response_model=OpenTradeSchema, tags=["Trades"]) def trade_reload(tradeid: int, rpc: RPC = Depends(get_rpc)): rpc._rpc_reload_trade_from_exchange(tradeid) return rpc._rpc_trade_status([tradeid])[0] -@router.get("/trades/open/custom-data", response_model=list[ListCustomData], tags=["trades"]) +@router.get("/trades/open/custom-data", response_model=list[ListCustomData], tags=["Trades"]) def list_open_trades_custom_data( key: str | None = Query(None, description="Optional key to filter data"), limit: int = Query(100, ge=1, description="Maximum number of different trades to return data"), @@ -202,7 +202,7 @@ def list_open_trades_custom_data( raise HTTPException(status_code=404, detail=str(e)) -@router.get("/trades/{trade_id}/custom-data", response_model=list[ListCustomData], tags=["trades"]) +@router.get("/trades/{trade_id}/custom-data", response_model=list[ListCustomData], tags=["Trades"]) def list_custom_data(trade_id: int, key: str | None = Query(None), rpc: RPC = Depends(get_rpc)): """ Fetch custom data for a specific trade. @@ -215,11 +215,11 @@ def list_custom_data(trade_id: int, key: str | None = Query(None), rpc: RPC = De # /forcebuy is deprecated with short addition. use /forceentry instead -@router.post("/forceenter", response_model=ForceEnterResponse, tags=["trades"]) +@router.post("/forceenter", response_model=ForceEnterResponse, tags=["Trades"]) @router.post( "/forcebuy", response_model=ForceEnterResponse, - tags=["trades"], + tags=["Trades"], summary="(deprecated) Please use /forceenter instead", ) def force_entry(payload: ForceEnterPayload, rpc: RPC = Depends(get_rpc)): @@ -244,11 +244,11 @@ def force_entry(payload: ForceEnterPayload, rpc: RPC = Depends(get_rpc)): # /forcesell is deprecated with short addition. use /forceexit instead -@router.post("/forceexit", response_model=ResultMsg, tags=["trades"]) +@router.post("/forceexit", response_model=ResultMsg, tags=["Trades"]) @router.post( "/forcesell", response_model=ResultMsg, - tags=["trades"], + tags=["Trades"], summary="(deprecated) Please use /forceexit instead", ) def forceexit(payload: ForceExitPayload, rpc: RPC = Depends(get_rpc)): @@ -258,78 +258,78 @@ def forceexit(payload: ForceExitPayload, rpc: RPC = Depends(get_rpc)): ) -@router.get("/blacklist", response_model=BlacklistResponse, tags=["trading-info", "pairlist"]) +@router.get("/blacklist", response_model=BlacklistResponse, tags=["Trading-info", "Pairlist"]) def blacklist(rpc: RPC = Depends(get_rpc)): return rpc._rpc_blacklist() -@router.post("/blacklist", response_model=BlacklistResponse, tags=["pairlist"]) +@router.post("/blacklist", response_model=BlacklistResponse, tags=["Pairlist"]) def blacklist_post(payload: BlacklistPayload, rpc: RPC = Depends(get_rpc)): return rpc._rpc_blacklist(payload.blacklist) -@router.delete("/blacklist", response_model=BlacklistResponse, tags=["pairlist"]) +@router.delete("/blacklist", response_model=BlacklistResponse, tags=["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=["trading-info", "pairlist"]) +@router.get("/whitelist", response_model=WhitelistResponse, tags=["Trading-info", "Pairlist"]) def whitelist(rpc: RPC = Depends(get_rpc)): return rpc._rpc_whitelist() -@router.get("/locks", response_model=Locks, tags=["trading-info", "locks"]) +@router.get("/locks", response_model=Locks, tags=["Trading-info", "Locks"]) def locks(rpc: RPC = Depends(get_rpc)): return rpc._rpc_locks() -@router.delete("/locks/{lockid}", response_model=Locks, tags=["locks"]) +@router.delete("/locks/{lockid}", response_model=Locks, tags=["Locks"]) def delete_lock(lockid: int, rpc: RPC = Depends(get_rpc)): return rpc._rpc_delete_lock(lockid=lockid) -@router.post("/locks/delete", response_model=Locks, tags=["locks"]) +@router.post("/locks/delete", response_model=Locks, tags=["Locks"]) def delete_lock_pair(payload: DeleteLockRequest, rpc: RPC = Depends(get_rpc)): return rpc._rpc_delete_lock(lockid=payload.lockid, pair=payload.pair) -@router.post("/locks", response_model=Locks, tags=["locks"]) +@router.post("/locks", response_model=Locks, tags=["Locks"]) def add_locks(payload: list[LocksPayload], rpc: RPC = Depends(get_rpc)): for lock in payload: rpc._rpc_add_lock(lock.pair, lock.until, lock.reason, lock.side) return rpc._rpc_locks() -@router.post("/start", response_model=StatusMsg, tags=["botcontrol"]) +@router.post("/start", response_model=StatusMsg, tags=["Bot-control"]) def start(rpc: RPC = Depends(get_rpc)): return rpc._rpc_start() -@router.post("/stop", response_model=StatusMsg, tags=["botcontrol"]) +@router.post("/stop", response_model=StatusMsg, tags=["Bot-control"]) def stop(rpc: RPC = Depends(get_rpc)): return rpc._rpc_stop() -@router.post("/pause", response_model=StatusMsg, tags=["botcontrol"]) -@router.post("/stopentry", response_model=StatusMsg, tags=["botcontrol"]) -@router.post("/stopbuy", response_model=StatusMsg, tags=["botcontrol"]) +@router.post("/pause", response_model=StatusMsg, tags=["Bot-control"]) +@router.post("/stopentry", response_model=StatusMsg, tags=["Bot-control"]) +@router.post("/stopbuy", response_model=StatusMsg, tags=["Bot-control"]) def pause(rpc: RPC = Depends(get_rpc)): return rpc._rpc_pause() -@router.post("/reload_config", response_model=StatusMsg, tags=["botcontrol"]) +@router.post("/reload_config", response_model=StatusMsg, tags=["Bot-control"]) def reload_config(rpc: RPC = Depends(get_rpc)): return rpc._rpc_reload_config() -@router.get("/pair_candles", response_model=PairHistory, tags=["candle data"]) +@router.get("/pair_candles", response_model=PairHistory, tags=["Candle data"]) def pair_candles(pair: str, timeframe: str, limit: int | None = None, rpc: RPC = Depends(get_rpc)): return rpc._rpc_analysed_dataframe(pair, timeframe, limit, None) -@router.post("/pair_candles", response_model=PairHistory, tags=["candle data"]) +@router.post("/pair_candles", response_model=PairHistory, tags=["Candle data"]) def pair_candles_filtered(payload: PairCandlesRequest, rpc: RPC = Depends(get_rpc)): # Advanced pair_candles endpoint with column filtering return rpc._rpc_analysed_dataframe( diff --git a/freqtrade/rpc/api_server/api_v1.py b/freqtrade/rpc/api_server/api_v1.py index 17fb9288b..b15942e2e 100644 --- a/freqtrade/rpc/api_server/api_v1.py +++ b/freqtrade/rpc/api_server/api_v1.py @@ -96,7 +96,7 @@ def logs(limit: int | None = None): return RPC._rpc_get_logs(limit) -@router.get("/plot_config", response_model=PlotConfig, tags=["candle data"]) +@router.get("/plot_config", response_model=PlotConfig, tags=["Candle data"]) def plot_config( strategy: str | None = None, config=Depends(get_config), @@ -115,7 +115,7 @@ def plot_config( raise HTTPException(status_code=502, detail=str(e)) -@router.get("/markets", response_model=MarketResponse, tags=["candle data", "webserver"]) +@router.get("/markets", response_model=MarketResponse, tags=["Candle data"]) def markets( query: Annotated[MarketRequest, Query()], config=Depends(get_config), diff --git a/freqtrade/rpc/api_server/api_webserver.py b/freqtrade/rpc/api_server/api_webserver.py index ae54280e3..7b2cce0fc 100644 --- a/freqtrade/rpc/api_server/api_webserver.py +++ b/freqtrade/rpc/api_server/api_webserver.py @@ -24,7 +24,7 @@ logger = logging.getLogger(__name__) router = APIRouter() -@router.get("/strategies", response_model=StrategyListResponse, tags=["strategy"]) +@router.get("/strategies", response_model=StrategyListResponse, tags=["Strategy"]) def list_strategies(config=Depends(get_config)): from freqtrade.resolvers.strategy_resolver import StrategyResolver @@ -36,7 +36,7 @@ def list_strategies(config=Depends(get_config)): return {"strategies": [x["name"] for x in strategies]} -@router.get("/strategy/{strategy}", response_model=StrategyResponse, tags=["strategy"]) +@router.get("/strategy/{strategy}", response_model=StrategyResponse, tags=["Strategy"]) def get_strategy(strategy: str, config=Depends(get_config)): if ":" in strategy: raise HTTPException(status_code=500, detail="base64 encoded strategies are not allowed.") @@ -69,9 +69,7 @@ def list_exchanges(config=Depends(get_config)): } -@router.get( - "/hyperoptloss", response_model=HyperoptLossListResponse, tags=["hyperopt", "webserver"] -) +@router.get("/hyperoptloss", response_model=HyperoptLossListResponse, tags=["Hyperopt"]) def list_hyperoptloss( config=Depends(get_config), ): @@ -93,7 +91,7 @@ def list_hyperoptloss( } -@router.get("/freqaimodels", response_model=FreqAIModelListResponse, tags=["freqai"]) +@router.get("/freqaimodels", response_model=FreqAIModelListResponse, tags=["FreqAI"]) def list_freqaimodels(config=Depends(get_config)): from freqtrade.resolvers.freqaimodel_resolver import FreqaiModelResolver @@ -104,7 +102,7 @@ def list_freqaimodels(config=Depends(get_config)): @router.get( - "/available_pairs", response_model=AvailablePairs, tags=["candle data", "download-data"] + "/available_pairs", response_model=AvailablePairs, tags=["Candle data", "Download-data"] ) def list_available_pairs( timeframe: str | None = None, diff --git a/freqtrade/rpc/api_server/deps.py b/freqtrade/rpc/api_server/deps.py index 2063ff00e..0991366ce 100644 --- a/freqtrade/rpc/api_server/deps.py +++ b/freqtrade/rpc/api_server/deps.py @@ -5,8 +5,7 @@ from uuid import uuid4 from fastapi import Depends, HTTPException from freqtrade.constants import Config -from freqtrade.enums import RunMode -from freqtrade.enums.runmode import TRADE_MODES +from freqtrade.enums import TRADE_MODES, RunMode from freqtrade.persistence import Trade from freqtrade.persistence.models import _request_id_ctx_var from freqtrade.rpc.api_server.webserver_bgwork import ApiBG diff --git a/freqtrade/rpc/api_server/webserver.py b/freqtrade/rpc/api_server/webserver.py index 9e4f59d00..98a5c3540 100644 --- a/freqtrade/rpc/api_server/webserver.py +++ b/freqtrade/rpc/api_server/webserver.py @@ -22,6 +22,7 @@ logger = logging.getLogger(__name__) _TRADE_MODE_ONLY = "*only available in trading mode*" +_WEBSERVER_MODE_ONLY = "*only available in webserver mode*" _OPENAPI_TAGS = ( {"name": "Auth", "description": "Authentication endpoints."}, @@ -29,29 +30,61 @@ _OPENAPI_TAGS = ( "name": "Info", "description": ("Information endpoints providing general information about the bot."), }, + { + "name": "Bot-control", + "description": (f"Bot control endpoints to start/stop trading - {_TRADE_MODE_ONLY}."), + }, + { + "name": "Pairlist", + "description": f"Pairlist management - {_TRADE_MODE_ONLY}.", + }, + { + "name": "Locks", + "description": f"Pair lock management - {_TRADE_MODE_ONLY}.", + }, + { + "name": "Candle data", + "description": "Candle / OHLCV data.", + }, + { + "name": "Trading-info", + "description": f"Trading related information - {_TRADE_MODE_ONLY}.", + }, + { + "name": "Trades", + "description": f"Trade management - {_TRADE_MODE_ONLY}.", + }, + { + "name": "Strategy", + "description": f"List and retrieve strategies - {_WEBSERVER_MODE_ONLY}.", + }, + { + "name": "Hyperopt", + "description": f"Retrieve hyperopt loss functions - {_WEBSERVER_MODE_ONLY}.", + }, + { + "name": "FreqAI", + "description": f"FreqAI related endpoints - {_WEBSERVER_MODE_ONLY}.", + }, + { + "name": "Download-data", + "description": f"Download data endpoints - {_WEBSERVER_MODE_ONLY}.", + }, + { + "name": "Backtest", + "description": f"Backtest endpoints - {_WEBSERVER_MODE_ONLY}.", + }, + { + "name": "Pairlists", + "description": f"Pairlist endpoints - {_WEBSERVER_MODE_ONLY}.", + }, { "name": "Trading", "description": f"Trading related endpoints - {_TRADE_MODE_ONLY}.", }, { "name": "Webserver", - "description": ("Webserver related endpoints - *only available in webserver mode*."), - }, - { - "name": "Bot-control", - "description": (f"Bot control endpoints to start/stop trading - {_TRADE_MODE_ONLY}."), - }, - { - "name": "pairlist", - "description": f"Pairlist management - {_TRADE_MODE_ONLY}.", - }, - { - "name": "locks", - "description": f"Pair lock management - {_TRADE_MODE_ONLY}.", - }, - { - "name": "candle data", - "description": "Candle / OHLCV data.", + "description": (f"Webserver related endpoints - {_WEBSERVER_MODE_ONLY}."), }, ) @@ -189,6 +222,7 @@ class ApiServer(RPCHandler): app.include_router( api_backtest, prefix="/api/v1", + tags=["Backtest"], dependencies=[Depends(http_basic_or_jwt_token), Depends(is_webserver_mode)], ) app.include_router( @@ -205,13 +239,13 @@ class ApiServer(RPCHandler): app.include_router( api_pairlists, prefix="/api/v1", - tags=["Webserver"], + tags=["Webserver", "Pairlists"], dependencies=[Depends(http_basic_or_jwt_token), Depends(is_webserver_mode)], ) app.include_router( api_download_data, prefix="/api/v1", - tags=["download-data", "Webserver"], + tags=["Download-data", "Webserver"], dependencies=[Depends(http_basic_or_jwt_token), Depends(is_webserver_mode)], ) app.include_router(ws_router, prefix="/api/v1")