Move api to /api/v1
This commit is contained in:
parent
01cd68a5aa
commit
5149ff7b12
@ -7,12 +7,15 @@ from typing import Dict
|
|||||||
from arrow import Arrow
|
from arrow import Arrow
|
||||||
from flask import Flask, jsonify, request
|
from flask import Flask, jsonify, request
|
||||||
from flask.json import JSONEncoder
|
from flask.json import JSONEncoder
|
||||||
|
from werkzeug.wsgi import DispatcherMiddleware
|
||||||
|
|
||||||
from freqtrade.__init__ import __version__
|
from freqtrade.__init__ import __version__
|
||||||
from freqtrade.rpc.rpc import RPC, RPCException
|
from freqtrade.rpc.rpc import RPC, RPCException
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
BASE_URI = "/api/v1"
|
||||||
|
|
||||||
|
|
||||||
class ArrowJSONEncoder(JSONEncoder):
|
class ArrowJSONEncoder(JSONEncoder):
|
||||||
def default(self, obj):
|
def default(self, obj):
|
||||||
@ -60,7 +63,6 @@ class ApiServer(RPC):
|
|||||||
|
|
||||||
self._config = freqtrade.config
|
self._config = freqtrade.config
|
||||||
self.app = Flask(__name__)
|
self.app = Flask(__name__)
|
||||||
|
|
||||||
self.app.json_encoder = ArrowJSONEncoder
|
self.app.json_encoder = ArrowJSONEncoder
|
||||||
|
|
||||||
# Register application handling
|
# Register application handling
|
||||||
@ -105,29 +107,36 @@ class ApiServer(RPC):
|
|||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
# Actions to control the bot
|
# Actions to control the bot
|
||||||
self.app.add_url_rule('/start', 'start', view_func=self._start, methods=['POST'])
|
self.app.add_url_rule(f'{BASE_URI}/start', 'start',
|
||||||
self.app.add_url_rule('/stop', 'stop', view_func=self._stop, methods=['POST'])
|
view_func=self._start, methods=['POST'])
|
||||||
self.app.add_url_rule('/stopbuy', 'stopbuy', view_func=self._stopbuy, methods=['POST'])
|
self.app.add_url_rule(f'{BASE_URI}/stop', 'stop', view_func=self._stop, methods=['POST'])
|
||||||
self.app.add_url_rule('/reload_conf', 'reload_conf', view_func=self._reload_conf,
|
self.app.add_url_rule(f'{BASE_URI}/stopbuy', 'stopbuy',
|
||||||
methods=['POST'])
|
view_func=self._stopbuy, methods=['POST'])
|
||||||
|
self.app.add_url_rule(f'{BASE_URI}/reload_conf', 'reload_conf',
|
||||||
|
view_func=self._reload_conf, methods=['POST'])
|
||||||
# Info commands
|
# Info commands
|
||||||
self.app.add_url_rule('/balance', 'balance', view_func=self._balance, methods=['GET'])
|
self.app.add_url_rule(f'{BASE_URI}/balance', 'balance',
|
||||||
self.app.add_url_rule('/count', 'count', view_func=self._count, methods=['GET'])
|
view_func=self._balance, methods=['GET'])
|
||||||
self.app.add_url_rule('/daily', 'daily', view_func=self._daily, methods=['GET'])
|
self.app.add_url_rule(f'{BASE_URI}/count', 'count', view_func=self._count, methods=['GET'])
|
||||||
self.app.add_url_rule('/edge', 'edge', view_func=self._edge, methods=['GET'])
|
self.app.add_url_rule(f'{BASE_URI}/daily', 'daily', view_func=self._daily, methods=['GET'])
|
||||||
self.app.add_url_rule('/profit', 'profit', view_func=self._profit, methods=['GET'])
|
self.app.add_url_rule(f'{BASE_URI}/edge', 'edge', view_func=self._edge, methods=['GET'])
|
||||||
self.app.add_url_rule('/performance', 'performance', view_func=self._performance,
|
self.app.add_url_rule(f'{BASE_URI}/profit', 'profit',
|
||||||
methods=['GET'])
|
view_func=self._profit, methods=['GET'])
|
||||||
self.app.add_url_rule('/status', 'status', view_func=self._status, methods=['GET'])
|
self.app.add_url_rule(f'{BASE_URI}/performance', 'performance',
|
||||||
self.app.add_url_rule('/version', 'version', view_func=self._version, methods=['GET'])
|
view_func=self._performance, methods=['GET'])
|
||||||
|
self.app.add_url_rule(f'{BASE_URI}/status', 'status',
|
||||||
|
view_func=self._status, methods=['GET'])
|
||||||
|
self.app.add_url_rule(f'{BASE_URI}/version', 'version',
|
||||||
|
view_func=self._version, methods=['GET'])
|
||||||
|
|
||||||
# Combined actions and infos
|
# Combined actions and infos
|
||||||
self.app.add_url_rule('/blacklist', 'blacklist', view_func=self._blacklist,
|
self.app.add_url_rule(f'{BASE_URI}/blacklist', 'blacklist', view_func=self._blacklist,
|
||||||
methods=['GET', 'POST'])
|
methods=['GET', 'POST'])
|
||||||
self.app.add_url_rule('/whitelist', 'whitelist', view_func=self._whitelist,
|
self.app.add_url_rule(f'{BASE_URI}/whitelist', 'whitelist', view_func=self._whitelist,
|
||||||
methods=['GET'])
|
methods=['GET'])
|
||||||
self.app.add_url_rule('/forcebuy', 'forcebuy', view_func=self._forcebuy, methods=['POST'])
|
self.app.add_url_rule(f'{BASE_URI}/forcebuy', 'forcebuy',
|
||||||
self.app.add_url_rule('/forcesell', 'forcesell', view_func=self._forcesell,
|
view_func=self._forcebuy, methods=['POST'])
|
||||||
|
self.app.add_url_rule(f'{BASE_URI}/forcesell', 'forcesell', view_func=self._forcesell,
|
||||||
methods=['POST'])
|
methods=['POST'])
|
||||||
|
|
||||||
# TODO: Implement the following
|
# TODO: Implement the following
|
||||||
|
@ -9,7 +9,7 @@ import pytest
|
|||||||
|
|
||||||
from freqtrade.__init__ import __version__
|
from freqtrade.__init__ import __version__
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.rpc.api_server import ApiServer
|
from freqtrade.rpc.api_server import ApiServer, BASE_URI
|
||||||
from freqtrade.state import State
|
from freqtrade.state import State
|
||||||
from freqtrade.tests.conftest import (get_patched_freqtradebot, log_has,
|
from freqtrade.tests.conftest import (get_patched_freqtradebot, log_has,
|
||||||
patch_get_signal)
|
patch_get_signal)
|
||||||
@ -35,35 +35,35 @@ def assert_response(response, expected_code=200):
|
|||||||
def test_api_not_found(botclient):
|
def test_api_not_found(botclient):
|
||||||
ftbot, client = botclient
|
ftbot, client = botclient
|
||||||
|
|
||||||
rc = client.post("/invalid_url")
|
rc = client.post(f"{BASE_URI}/invalid_url")
|
||||||
assert_response(rc, 404)
|
assert_response(rc, 404)
|
||||||
assert rc.json == {'status': 'error',
|
assert rc.json == {"status": "error",
|
||||||
'reason': "There's no API call for http://localhost/invalid_url.",
|
"reason": f"There's no API call for http://localhost{BASE_URI}/invalid_url.",
|
||||||
'code': 404
|
"code": 404
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_api_stop_workflow(botclient):
|
def test_api_stop_workflow(botclient):
|
||||||
ftbot, client = botclient
|
ftbot, client = botclient
|
||||||
assert ftbot.state == State.RUNNING
|
assert ftbot.state == State.RUNNING
|
||||||
rc = client.post("/stop")
|
rc = client.post(f"{BASE_URI}/stop")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json == {'status': 'stopping trader ...'}
|
assert rc.json == {'status': 'stopping trader ...'}
|
||||||
assert ftbot.state == State.STOPPED
|
assert ftbot.state == State.STOPPED
|
||||||
|
|
||||||
# Stop bot again
|
# Stop bot again
|
||||||
rc = client.post("/stop")
|
rc = client.post(f"{BASE_URI}/stop")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json == {'status': 'already stopped'}
|
assert rc.json == {'status': 'already stopped'}
|
||||||
|
|
||||||
# Start bot
|
# Start bot
|
||||||
rc = client.post("/start")
|
rc = client.post(f"{BASE_URI}/start")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json == {'status': 'starting trader ...'}
|
assert rc.json == {'status': 'starting trader ...'}
|
||||||
assert ftbot.state == State.RUNNING
|
assert ftbot.state == State.RUNNING
|
||||||
|
|
||||||
# Call start again
|
# Call start again
|
||||||
rc = client.post("/start")
|
rc = client.post(f"{BASE_URI}/start")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json == {'status': 'already running'}
|
assert rc.json == {'status': 'already running'}
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ def test_api_run(default_conf, mocker, caplog):
|
|||||||
def test_api_reloadconf(botclient):
|
def test_api_reloadconf(botclient):
|
||||||
ftbot, client = botclient
|
ftbot, client = botclient
|
||||||
|
|
||||||
rc = client.post("/reload_conf")
|
rc = client.post(f"{BASE_URI}/reload_conf")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json == {'status': 'reloading config ...'}
|
assert rc.json == {'status': 'reloading config ...'}
|
||||||
assert ftbot.state == State.RELOAD_CONF
|
assert ftbot.state == State.RELOAD_CONF
|
||||||
@ -142,7 +142,7 @@ def test_api_stopbuy(botclient):
|
|||||||
ftbot, client = botclient
|
ftbot, client = botclient
|
||||||
assert ftbot.config['max_open_trades'] != 0
|
assert ftbot.config['max_open_trades'] != 0
|
||||||
|
|
||||||
rc = client.post("/stopbuy")
|
rc = client.post(f"{BASE_URI}/stopbuy")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json == {'status': 'No more buy will occur from now. Run /reload_conf to reset.'}
|
assert rc.json == {'status': 'No more buy will occur from now. Run /reload_conf to reset.'}
|
||||||
assert ftbot.config['max_open_trades'] == 0
|
assert ftbot.config['max_open_trades'] == 0
|
||||||
@ -172,7 +172,7 @@ def test_api_balance(botclient, mocker, rpc_balance):
|
|||||||
mocker.patch('freqtrade.exchange.Exchange.get_balances', return_value=rpc_balance)
|
mocker.patch('freqtrade.exchange.Exchange.get_balances', return_value=rpc_balance)
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_ticker', side_effect=mock_ticker)
|
mocker.patch('freqtrade.exchange.Exchange.get_ticker', side_effect=mock_ticker)
|
||||||
|
|
||||||
rc = client.get("/balance")
|
rc = client.get(f"{BASE_URI}/balance")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert "currencies" in rc.json
|
assert "currencies" in rc.json
|
||||||
assert len(rc.json["currencies"]) == 5
|
assert len(rc.json["currencies"]) == 5
|
||||||
@ -195,7 +195,7 @@ def test_api_count(botclient, mocker, ticker, fee, markets):
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
rc = client.get("/count")
|
rc = client.get(f"{BASE_URI}/count")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
|
|
||||||
assert rc.json["current"] == 0
|
assert rc.json["current"] == 0
|
||||||
@ -203,7 +203,7 @@ def test_api_count(botclient, mocker, ticker, fee, markets):
|
|||||||
|
|
||||||
# Create some test data
|
# Create some test data
|
||||||
ftbot.create_trade()
|
ftbot.create_trade()
|
||||||
rc = client.get("/count")
|
rc = client.get(f"{BASE_URI}/count")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json["current"] == 1.0
|
assert rc.json["current"] == 1.0
|
||||||
assert rc.json["max"] == 1.0
|
assert rc.json["max"] == 1.0
|
||||||
@ -219,7 +219,7 @@ def test_api_daily(botclient, mocker, ticker, fee, markets):
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
rc = client.get("/daily")
|
rc = client.get(f"{BASE_URI}/daily")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert len(rc.json) == 7
|
assert len(rc.json) == 7
|
||||||
assert rc.json[0][0] == str(datetime.utcnow().date())
|
assert rc.json[0][0] == str(datetime.utcnow().date())
|
||||||
@ -235,7 +235,7 @@ def test_api_edge_disabled(botclient, mocker, ticker, fee, markets):
|
|||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
rc = client.get("/edge")
|
rc = client.get(f"{BASE_URI}/edge")
|
||||||
assert_response(rc, 502)
|
assert_response(rc, 502)
|
||||||
assert rc.json == {"error": "Error querying _edge: Edge is not enabled."}
|
assert rc.json == {"error": "Error querying _edge: Edge is not enabled."}
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ def test_api_profit(botclient, mocker, ticker, fee, markets, limit_buy_order, li
|
|||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
|
|
||||||
rc = client.get("/profit")
|
rc = client.get(f"{BASE_URI}/profit")
|
||||||
assert_response(rc, 502)
|
assert_response(rc, 502)
|
||||||
assert len(rc.json) == 1
|
assert len(rc.json) == 1
|
||||||
assert rc.json == {"error": "Error querying _profit: no closed trade"}
|
assert rc.json == {"error": "Error querying _profit: no closed trade"}
|
||||||
@ -261,7 +261,7 @@ def test_api_profit(botclient, mocker, ticker, fee, markets, limit_buy_order, li
|
|||||||
|
|
||||||
# Simulate fulfilled LIMIT_BUY order for trade
|
# Simulate fulfilled LIMIT_BUY order for trade
|
||||||
trade.update(limit_buy_order)
|
trade.update(limit_buy_order)
|
||||||
rc = client.get("/profit")
|
rc = client.get(f"{BASE_URI}/profit")
|
||||||
assert_response(rc, 502)
|
assert_response(rc, 502)
|
||||||
assert rc.json == {"error": "Error querying _profit: no closed trade"}
|
assert rc.json == {"error": "Error querying _profit: no closed trade"}
|
||||||
|
|
||||||
@ -270,7 +270,7 @@ def test_api_profit(botclient, mocker, ticker, fee, markets, limit_buy_order, li
|
|||||||
trade.close_date = datetime.utcnow()
|
trade.close_date = datetime.utcnow()
|
||||||
trade.is_open = False
|
trade.is_open = False
|
||||||
|
|
||||||
rc = client.get("/profit")
|
rc = client.get(f"{BASE_URI}/profit")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json == {'avg_duration': '0:00:00',
|
assert rc.json == {'avg_duration': '0:00:00',
|
||||||
'best_pair': 'ETH/BTC',
|
'best_pair': 'ETH/BTC',
|
||||||
@ -323,7 +323,7 @@ def test_api_performance(botclient, mocker, ticker, fee):
|
|||||||
Trade.session.add(trade)
|
Trade.session.add(trade)
|
||||||
Trade.session.flush()
|
Trade.session.flush()
|
||||||
|
|
||||||
rc = client.get("/performance")
|
rc = client.get(f"{BASE_URI}/performance")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert len(rc.json) == 2
|
assert len(rc.json) == 2
|
||||||
assert rc.json == [{'count': 1, 'pair': 'LTC/ETH', 'profit': 7.61},
|
assert rc.json == [{'count': 1, 'pair': 'LTC/ETH', 'profit': 7.61},
|
||||||
@ -341,12 +341,12 @@ def test_api_status(botclient, mocker, ticker, fee, markets):
|
|||||||
markets=PropertyMock(return_value=markets)
|
markets=PropertyMock(return_value=markets)
|
||||||
)
|
)
|
||||||
|
|
||||||
rc = client.get("/status")
|
rc = client.get(f"{BASE_URI}/status")
|
||||||
assert_response(rc, 502)
|
assert_response(rc, 502)
|
||||||
assert rc.json == {'error': 'Error querying _status: no active trade'}
|
assert rc.json == {'error': 'Error querying _status: no active trade'}
|
||||||
|
|
||||||
ftbot.create_trade()
|
ftbot.create_trade()
|
||||||
rc = client.get("/status")
|
rc = client.get(f"{BASE_URI}/status")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert len(rc.json) == 1
|
assert len(rc.json) == 1
|
||||||
assert rc.json == [{'amount': 90.99181074,
|
assert rc.json == [{'amount': 90.99181074,
|
||||||
@ -373,7 +373,7 @@ def test_api_status(botclient, mocker, ticker, fee, markets):
|
|||||||
def test_api_version(botclient):
|
def test_api_version(botclient):
|
||||||
ftbot, client = botclient
|
ftbot, client = botclient
|
||||||
|
|
||||||
rc = client.get("/version")
|
rc = client.get(f"{BASE_URI}/version")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json == {"version": __version__}
|
assert rc.json == {"version": __version__}
|
||||||
|
|
||||||
@ -381,14 +381,14 @@ def test_api_version(botclient):
|
|||||||
def test_api_blacklist(botclient, mocker):
|
def test_api_blacklist(botclient, mocker):
|
||||||
ftbot, client = botclient
|
ftbot, client = botclient
|
||||||
|
|
||||||
rc = client.get("/blacklist")
|
rc = client.get(f"{BASE_URI}/blacklist")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json == {"blacklist": ["DOGE/BTC", "HOT/BTC"],
|
assert rc.json == {"blacklist": ["DOGE/BTC", "HOT/BTC"],
|
||||||
"length": 2,
|
"length": 2,
|
||||||
"method": "StaticPairList"}
|
"method": "StaticPairList"}
|
||||||
|
|
||||||
# Add ETH/BTC to blacklist
|
# Add ETH/BTC to blacklist
|
||||||
rc = client.post("/blacklist", data='{"blacklist": ["ETH/BTC"]}',
|
rc = client.post(f"{BASE_URI}/blacklist", data='{"blacklist": ["ETH/BTC"]}',
|
||||||
content_type='application/json')
|
content_type='application/json')
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json == {"blacklist": ["DOGE/BTC", "HOT/BTC", "ETH/BTC"],
|
assert rc.json == {"blacklist": ["DOGE/BTC", "HOT/BTC", "ETH/BTC"],
|
||||||
@ -399,7 +399,7 @@ def test_api_blacklist(botclient, mocker):
|
|||||||
def test_api_whitelist(botclient):
|
def test_api_whitelist(botclient):
|
||||||
ftbot, client = botclient
|
ftbot, client = botclient
|
||||||
|
|
||||||
rc = client.get("/whitelist")
|
rc = client.get(f"{BASE_URI}/whitelist")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json == {"whitelist": ['ETH/BTC', 'LTC/BTC', 'XRP/BTC', 'NEO/BTC'],
|
assert rc.json == {"whitelist": ['ETH/BTC', 'LTC/BTC', 'XRP/BTC', 'NEO/BTC'],
|
||||||
"length": 4,
|
"length": 4,
|
||||||
@ -409,7 +409,7 @@ def test_api_whitelist(botclient):
|
|||||||
def test_api_forcebuy(botclient, mocker, fee):
|
def test_api_forcebuy(botclient, mocker, fee):
|
||||||
ftbot, client = botclient
|
ftbot, client = botclient
|
||||||
|
|
||||||
rc = client.post("/forcebuy", content_type='application/json',
|
rc = client.post(f"{BASE_URI}/forcebuy", content_type='application/json',
|
||||||
data='{"pair": "ETH/BTC"}')
|
data='{"pair": "ETH/BTC"}')
|
||||||
assert_response(rc, 502)
|
assert_response(rc, 502)
|
||||||
assert rc.json == {"error": "Error querying _forcebuy: Forcebuy not enabled."}
|
assert rc.json == {"error": "Error querying _forcebuy: Forcebuy not enabled."}
|
||||||
@ -419,7 +419,7 @@ def test_api_forcebuy(botclient, mocker, fee):
|
|||||||
|
|
||||||
fbuy_mock = MagicMock(return_value=None)
|
fbuy_mock = MagicMock(return_value=None)
|
||||||
mocker.patch("freqtrade.rpc.RPC._rpc_forcebuy", fbuy_mock)
|
mocker.patch("freqtrade.rpc.RPC._rpc_forcebuy", fbuy_mock)
|
||||||
rc = client.post("/forcebuy", content_type="application/json",
|
rc = client.post(f"{BASE_URI}/forcebuy", content_type="application/json",
|
||||||
data='{"pair": "ETH/BTC"}')
|
data='{"pair": "ETH/BTC"}')
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json == {"status": "Error buying pair ETH/BTC."}
|
assert rc.json == {"status": "Error buying pair ETH/BTC."}
|
||||||
@ -440,7 +440,7 @@ def test_api_forcebuy(botclient, mocker, fee):
|
|||||||
))
|
))
|
||||||
mocker.patch("freqtrade.rpc.RPC._rpc_forcebuy", fbuy_mock)
|
mocker.patch("freqtrade.rpc.RPC._rpc_forcebuy", fbuy_mock)
|
||||||
|
|
||||||
rc = client.post("/forcebuy", content_type="application/json",
|
rc = client.post(f"{BASE_URI}/forcebuy", content_type="application/json",
|
||||||
data='{"pair": "ETH/BTC"}')
|
data='{"pair": "ETH/BTC"}')
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json == {'amount': 1,
|
assert rc.json == {'amount': 1,
|
||||||
@ -470,14 +470,14 @@ def test_api_forcesell(botclient, mocker, ticker, fee, markets):
|
|||||||
)
|
)
|
||||||
patch_get_signal(ftbot, (True, False))
|
patch_get_signal(ftbot, (True, False))
|
||||||
|
|
||||||
rc = client.post("/forcesell", content_type="application/json",
|
rc = client.post(f"{BASE_URI}/forcesell", content_type="application/json",
|
||||||
data='{"tradeid": "1"}')
|
data='{"tradeid": "1"}')
|
||||||
assert_response(rc, 502)
|
assert_response(rc, 502)
|
||||||
assert rc.json == {"error": "Error querying _forcesell: invalid argument"}
|
assert rc.json == {"error": "Error querying _forcesell: invalid argument"}
|
||||||
|
|
||||||
ftbot.create_trade()
|
ftbot.create_trade()
|
||||||
|
|
||||||
rc = client.post("/forcesell", content_type="application/json",
|
rc = client.post(f"{BASE_URI}/forcesell", content_type="application/json",
|
||||||
data='{"tradeid": "1"}')
|
data='{"tradeid": "1"}')
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert rc.json == {'result': 'Created sell order for trade 1.'}
|
assert rc.json == {'result': 'Created sell order for trade 1.'}
|
||||||
|
@ -36,7 +36,7 @@ class FtRestClient():
|
|||||||
|
|
||||||
if str(method).upper() not in ('GET', 'POST', 'PUT', 'DELETE'):
|
if str(method).upper() not in ('GET', 'POST', 'PUT', 'DELETE'):
|
||||||
raise ValueError('invalid method <{0}>'.format(method))
|
raise ValueError('invalid method <{0}>'.format(method))
|
||||||
basepath = f"{self._serverurl}/{apipath}"
|
basepath = f"{self._serverurl}/api/v1/{apipath}"
|
||||||
|
|
||||||
hd = {"Accept": "application/json",
|
hd = {"Accept": "application/json",
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json"
|
||||||
|
Loading…
Reference in New Issue
Block a user