From 27970b424d96a9e0369c47d0586c78840cbcdd83 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 10 Jan 2021 10:31:05 +0100 Subject: [PATCH] Add webUI serving to api-server --- .gitignore | 1 + freqtrade/rpc/api_server/ui/.gitkeep | 0 freqtrade/rpc/api_server/web_ui.py | 28 +++++++++++++++++++++++++++ freqtrade/rpc/api_server/webserver.py | 4 ++++ requirements.txt | 1 + tests/rpc/test_rpc_apiserver.py | 2 +- 6 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 freqtrade/rpc/api_server/ui/.gitkeep create mode 100644 freqtrade/rpc/api_server/web_ui.py diff --git a/.gitignore b/.gitignore index f206fce66..4720ff5cb 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ user_data/* user_data/notebooks/* freqtrade-plot.html freqtrade-profit-plot.html +freqtrade/rpc/api_server/ui/* # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/freqtrade/rpc/api_server/ui/.gitkeep b/freqtrade/rpc/api_server/ui/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/freqtrade/rpc/api_server/web_ui.py b/freqtrade/rpc/api_server/web_ui.py new file mode 100644 index 000000000..971f9e4de --- /dev/null +++ b/freqtrade/rpc/api_server/web_ui.py @@ -0,0 +1,28 @@ +from pathlib import Path + +from fastapi import APIRouter +from fastapi.exceptions import HTTPException +from starlette.responses import FileResponse + + +router_ui = APIRouter() + + +@router_ui.get('/favicon.ico', include_in_schema=False) +async def favicon(): + return FileResponse(Path(__file__).parent / 'ui/favicon.ico') + + +@router_ui.get('/{rest_of_path:path}', include_in_schema=False) +async def index_html(rest_of_path: str): + """ + Emulate path fallback to index.html. + """ + if rest_of_path.startswith('api') or rest_of_path.startswith('.'): + raise HTTPException(status_code=404, detail="Not Found") + uibase = Path(__file__).parent / 'ui' + if (uibase / rest_of_path).is_file(): + return FileResponse(uibase / rest_of_path) + + # Fall back to index.html, as indicated by vue router docs + return FileResponse(uibase / 'index.html') diff --git a/freqtrade/rpc/api_server/webserver.py b/freqtrade/rpc/api_server/webserver.py index 9c0779274..f3eaa1ebc 100644 --- a/freqtrade/rpc/api_server/webserver.py +++ b/freqtrade/rpc/api_server/webserver.py @@ -57,12 +57,16 @@ class ApiServer(RPCHandler): from freqtrade.rpc.api_server.api_auth import http_basic_or_jwt_token, router_login from freqtrade.rpc.api_server.api_v1 import router as api_v1 from freqtrade.rpc.api_server.api_v1 import router_public as api_v1_public + from freqtrade.rpc.api_server.web_ui import router_ui + app.include_router(api_v1_public, prefix="/api/v1") app.include_router(api_v1, prefix="/api/v1", dependencies=[Depends(http_basic_or_jwt_token)], ) app.include_router(router_login, prefix="/api/v1", tags=["auth"]) + # UI Router MUST be last! + app.include_router(router_ui, prefix='') app.add_middleware( CORSMiddleware, diff --git a/requirements.txt b/requirements.txt index c6cb3e445..5993fb3f7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,6 +31,7 @@ sdnotify==0.3.2 fastapi==0.63.0 uvicorn==0.13.3 pyjwt==2.0.1 +aiofiles==0.6.0 # Support for colorized terminal output colorama==0.4.4 diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index b050e5694..919481598 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -83,7 +83,7 @@ def assert_response(response, expected_code=200, needs_cors=True): def test_api_not_found(botclient): ftbot, client = botclient - rc = client_post(client, f"{BASE_URI}/invalid_url") + rc = client_get(client, f"{BASE_URI}/invalid_url") assert_response(rc, 404) assert rc.json() == {"detail": "Not Found"}