Improve tests, implement more fastapi methods

This commit is contained in:
Matthias 2020-12-26 17:00:30 +01:00
parent a18d66e108
commit 73a29e6d74
3 changed files with 53 additions and 4 deletions

View File

@ -1,4 +1,4 @@
from typing import Dict, List, Union from typing import Dict, List, Optional, Union
from pydantic import BaseModel from pydantic import BaseModel
@ -90,3 +90,12 @@ class SellReason(BaseModel):
class Stats(BaseModel): class Stats(BaseModel):
sell_reasons: Dict[str, SellReason] sell_reasons: Dict[str, SellReason]
durations: Dict[str, Union[str, float]] durations: Dict[str, Union[str, float]]
class ForceBuyPayload(BaseModel):
pair: str
price: Optional[float]
class ForceSellPayload(BaseModel):
tradeid: str

View File

@ -4,8 +4,10 @@ from fastapi import APIRouter, Depends
from freqtrade import __version__ from freqtrade import __version__
from freqtrade.rpc import RPC from freqtrade.rpc import RPC
from freqtrade.rpc.rpc import RPCException
from .api_models import Balances, Count, PerformanceEntry, Ping, Profit, Stats, StatusMsg, Version from .api_models import (Balances, Count, ForceBuyPayload, ForceSellPayload, PerformanceEntry, Ping, Profit, Stats,
StatusMsg, Version)
from .deps import get_config, get_rpc from .deps import get_config, get_rpc
@ -53,10 +55,33 @@ def stats(rpc: RPC = Depends(get_rpc)):
return rpc._rpc_stats() return rpc._rpc_stats()
# TODO: Missing response model
@router.get('/status', tags=['info'])
def status(rpc: RPC = Depends(get_rpc)):
try:
return rpc._rpc_trade_status()
except RPCException:
return []
@router.get('/show_config', tags=['info']) @router.get('/show_config', tags=['info'])
def show_config(rpc: RPC = Depends(get_rpc), config=Depends(get_config)): def show_config(rpc: RPC = Depends(get_rpc), config=Depends(get_config)):
return RPC._rpc_show_config(config, rpc._freqtrade.state) return RPC._rpc_show_config(config, rpc._freqtrade.state)
@router.post('/forcebuy', tags=['trading'])
def forcebuy(payload: ForceBuyPayload, rpc: RPC = Depends(get_rpc)):
trade = rpc._rpc_forcebuy(payload.pair, payload.price)
if trade:
return trade.to_json()
else:
return {"status": f"Error buying pair {payload.pair}."}
@router.post('/forcesell', tags=['trading'])
def forcesell(payload: ForceSellPayload, rpc: RPC = Depends(get_rpc)):
return rpc._rpc_forcesell(payload.tradeid)
@router.post('/start', response_model=StatusMsg, tags=['botcontrol']) @router.post('/start', response_model=StatusMsg, tags=['botcontrol'])
def start(rpc: RPC = Depends(get_rpc)): def start(rpc: RPC = Depends(get_rpc)):

View File

@ -1,14 +1,20 @@
import logging
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
from starlette.responses import JSONResponse
import uvicorn import uvicorn
from fastapi import Depends, FastAPI from fastapi import Depends, FastAPI
from fastapi.exceptions import HTTPException
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from freqtrade.rpc.rpc import RPC, RPCHandler from freqtrade.rpc.rpc import RPC, RPCException, RPCHandler
from .uvicorn_threaded import UvicornServer from .uvicorn_threaded import UvicornServer
logger = logging.getLogger(__name__)
class ApiServer(RPCHandler): class ApiServer(RPCHandler):
_rpc: Optional[RPC] = None _rpc: Optional[RPC] = None
@ -34,10 +40,17 @@ class ApiServer(RPCHandler):
def send_msg(self, msg: Dict[str, str]) -> None: def send_msg(self, msg: Dict[str, str]) -> None:
pass pass
def handle_rpc_exception(self, request, exc):
logger.exception(f"API Error calling: {exc}")
return JSONResponse(
status_code=502,
content={'error': f"Error querying {request.url.path}: {exc.message}"}
)
def configure_app(self, app: FastAPI, config): def configure_app(self, app: FastAPI, config):
from .api_auth import http_basic_or_jwt_token, router_login
from .api_v1 import router as api_v1 from .api_v1 import router as api_v1
from .api_v1 import router_public as api_v1_public from .api_v1 import router_public as api_v1_public
from .api_auth import http_basic_or_jwt_token, router_login
app.include_router(api_v1_public, prefix="/api/v1") app.include_router(api_v1_public, prefix="/api/v1")
app.include_router(api_v1, prefix="/api/v1", app.include_router(api_v1, prefix="/api/v1",
@ -53,6 +66,8 @@ class ApiServer(RPCHandler):
allow_headers=["*"], allow_headers=["*"],
) )
app.add_exception_handler(RPCException, self.handle_rpc_exception)
def start_api(self): def start_api(self):
""" """
Start API ... should be run in thread. Start API ... should be run in thread.