Improve tests, implement more fastapi methods
This commit is contained in:
parent
a18d66e108
commit
73a29e6d74
@ -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
|
||||||
|
@ -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)):
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user