Api server - custom json encoder
This commit is contained in:
parent
2f8088432c
commit
a12e093417
@ -3,13 +3,31 @@ import threading
|
|||||||
from ipaddress import IPv4Address
|
from ipaddress import IPv4Address
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
|
from arrow import Arrow
|
||||||
from flask import Flask, jsonify, request
|
from flask import Flask, jsonify, request
|
||||||
|
from flask.json import JSONEncoder
|
||||||
|
|
||||||
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__)
|
||||||
|
|
||||||
|
|
||||||
|
class ArrowJSONEncoder(JSONEncoder):
|
||||||
|
def default(self, obj):
|
||||||
|
try:
|
||||||
|
if isinstance(obj, Arrow):
|
||||||
|
return obj.for_json()
|
||||||
|
iterable = iter(obj)
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
return list(iterable)
|
||||||
|
return JSONEncoder.default(self, obj)
|
||||||
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
app.json_encoder = ArrowJSONEncoder
|
||||||
|
|
||||||
|
|
||||||
class ApiServer(RPC):
|
class ApiServer(RPC):
|
||||||
@ -42,13 +60,19 @@ class ApiServer(RPC):
|
|||||||
# since it's not terminated correctly.
|
# since it's not terminated correctly.
|
||||||
|
|
||||||
def send_msg(self, msg: Dict[str, str]) -> None:
|
def send_msg(self, msg: Dict[str, str]) -> None:
|
||||||
"""We don't push to endpoints at the moment. Look at webhooks for that."""
|
"""
|
||||||
|
We don't push to endpoints at the moment.
|
||||||
|
Take a look at webhooks for that functionality.
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def rest_dump(self, return_value):
|
def rest_dump(self, return_value):
|
||||||
""" Helper function to jsonify object for a webserver """
|
""" Helper function to jsonify object for a webserver """
|
||||||
return jsonify(return_value)
|
return jsonify(return_value)
|
||||||
|
|
||||||
|
def rest_error(self, error_msg):
|
||||||
|
return jsonify({"error": error_msg}), 502
|
||||||
|
|
||||||
def register_rest_other(self):
|
def register_rest_other(self):
|
||||||
"""
|
"""
|
||||||
Registers flask app URLs that are not calls to functionality in rpc.rpc.
|
Registers flask app URLs that are not calls to functionality in rpc.rpc.
|
||||||
@ -75,8 +99,7 @@ class ApiServer(RPC):
|
|||||||
app.add_url_rule('/count', 'count', view_func=self._count, methods=['GET'])
|
app.add_url_rule('/count', 'count', view_func=self._count, methods=['GET'])
|
||||||
app.add_url_rule('/daily', 'daily', view_func=self._daily, methods=['GET'])
|
app.add_url_rule('/daily', 'daily', view_func=self._daily, methods=['GET'])
|
||||||
app.add_url_rule('/profit', 'profit', view_func=self._profit, methods=['GET'])
|
app.add_url_rule('/profit', 'profit', view_func=self._profit, methods=['GET'])
|
||||||
app.add_url_rule('/status_table', 'status_table',
|
app.add_url_rule('/status', 'status', view_func=self._status, methods=['GET'])
|
||||||
view_func=self._status_table, methods=['GET'])
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
""" Method that runs flask app in its own thread forever """
|
""" Method that runs flask app in its own thread forever """
|
||||||
@ -180,9 +203,9 @@ class ApiServer(RPC):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
msg = self._rpc_count()
|
msg = self._rpc_count()
|
||||||
except RPCException as e:
|
|
||||||
msg = {"status": str(e)}
|
|
||||||
return self.rest_dump(msg)
|
return self.rest_dump(msg)
|
||||||
|
except RPCException as e:
|
||||||
|
return self.rest_error(str(e))
|
||||||
|
|
||||||
def _daily(self):
|
def _daily(self):
|
||||||
"""
|
"""
|
||||||
@ -202,8 +225,8 @@ class ApiServer(RPC):
|
|||||||
|
|
||||||
return self.rest_dump(stats)
|
return self.rest_dump(stats)
|
||||||
except RPCException as e:
|
except RPCException as e:
|
||||||
logger.exception("API Error querying daily:", e)
|
logger.exception("API Error querying daily: %s", e)
|
||||||
return "Error querying daily"
|
return self.rest_error(f"Error querying daily {e}")
|
||||||
|
|
||||||
def _profit(self):
|
def _profit(self):
|
||||||
"""
|
"""
|
||||||
@ -221,20 +244,19 @@ class ApiServer(RPC):
|
|||||||
|
|
||||||
return self.rest_dump(stats)
|
return self.rest_dump(stats)
|
||||||
except RPCException as e:
|
except RPCException as e:
|
||||||
logger.exception("API Error calling profit", e)
|
logger.exception("API Error calling profit: %s", e)
|
||||||
return "Error querying closed trades - maybe there are none"
|
return self.rest_error("Error querying closed trades - maybe there are none")
|
||||||
|
|
||||||
def _status_table(self):
|
def _status(self):
|
||||||
"""
|
"""
|
||||||
Handler for /status table.
|
Handler for /status table.
|
||||||
|
|
||||||
Returns the current TradeThread status in table format
|
Returns the current status of the trades in json format
|
||||||
:return: results
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
results = self._rpc_trade_status()
|
results = self._rpc_trade_status()
|
||||||
return self.rest_dump(results)
|
return self.rest_dump(results)
|
||||||
|
|
||||||
except RPCException as e:
|
except RPCException as e:
|
||||||
logger.exception("API Error calling status table", e)
|
logger.exception("API Error calling status table: %s", e)
|
||||||
return "Error querying open trades - maybe there are none."
|
return self.rest_error("Error querying open trades - maybe there are none.")
|
||||||
|
Loading…
Reference in New Issue
Block a user