Stop and start calls added
Along with refactoring to base line and use decorators.
Also modules loaded optionally if enabled in config or not
binds to ip / port set from config.json with warning if not localhost

TODO:
 - use argparse in client, and generally clean client up
 - create unit test
 - documentation
 - extend to other RCP commands, after feedback
This commit is contained in:
creslinux 2018-06-14 15:38:26 +00:00
parent 6cd4414874
commit cbfa9e8355
2 changed files with 106 additions and 46 deletions

View File

@ -5,43 +5,11 @@ import json
from flask import Flask, request from flask import Flask, request
from flask_restful import Resource, Api from flask_restful import Resource, Api
from json import dumps from json import dumps
from freqtrade.rpc.rpc import RPC from freqtrade.rpc.rpc import RPC, RPCException
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Daily(Resource):
# called by http://127.0.0.1:/daily?timescale=7
# where 7 is the number of days to report back with
def __init__(self, freqtrade) -> None:
"""
Initializes all enabled rpc modules
:param freqtrade: Instance of a freqtrade bot
:return: None
"""
self.freqtrade = freqtrade
self._config = freqtrade.config
def get(self):
timescale = request.args.get('timescale')
logger.info("LocalRPC - Daily Command Called")
timescale = int(timescale)
(error, stats) = RPC.rpc_daily_profit(self, timescale,
self._config['stake_currency'],
self._config['fiat_display_currency']
)
if error == False:
stats = dumps(stats, indent=4, sort_keys=True, default=str)
return stats
else:
json.dumps(error)
return error
class LocalRestSuperWrap(RPC): class LocalRestSuperWrap(RPC):
""" """
This class is for REST cmd line client This class is for REST cmd line client
@ -61,23 +29,85 @@ class LocalRestSuperWrap(RPC):
thread = threading.Thread(target=self.run, args=(freqtrade,)) # extra comma as ref ! Tuple thread = threading.Thread(target=self.run, args=(freqtrade,)) # extra comma as ref ! Tuple
thread.daemon = True # Daemonize thread thread.daemon = True # Daemonize thread
thread.start() # Start the execution thread.start() # Start the execution
def run(self, freqtrade): def run(self, freqtrade):
""" Method that runs forever """ """ Method that runs forever """
self._config = freqtrade.config self._config = freqtrade.config
# TODO add IP address / port to bind to in config.json and use in below.
logger.info('Starting Local Rest Server')
my_freqtrade = freqtrade
app = Flask(__name__) app = Flask(__name__)
api = Api(app)
# Our resources for restful apps go here, pass freqtrade object across """
api.add_resource(Daily, '/daily', methods=['GET'], Define the application routes here
resource_class_kwargs={'freqtrade': my_freqtrade}) # Route for returning daily each Telegram command should have a like local substitute
"""
@app.route("/")
def hello():
# For simple rest server testing via browser
# cmds = 'Try uri:/daily?timescale=7 /profit /balance /status
# /status /table /performance /count,
# /start /stop /help'
#run the server rest_cmds ='Commands implemented: <br>' \
app.run(port='5002') '<a href=/daily?timescale=7>/daily?timescale=7</a>' \
'<br>' \
'<a href=/stop>/stop</a>' \
'<br>' \
'<a href=/start>/start</a>'
return rest_cmds
@app.route('/daily', methods=['GET'])
def daily():
try:
timescale = request.args.get('timescale')
logger.info("LocalRPC - Daily Command Called")
timescale = int(timescale)
stats = self._rpc_daily_profit(timescale,
self._config['stake_currency'],
self._config['fiat_display_currency']
)
stats = dumps(stats, indent=4, sort_keys=True, default=str)
return stats
except RPCException as e:
return e
@app.route('/start', methods=['GET'])
def start():
"""
Handler for /start.
Starts TradeThread
"""
msg = self._rpc_start()
print("msg is", msg)
return msg
@app.route('/stop', methods=['GET'])
def stop():
"""
Handler for /stop.
Stops TradeThread
"""
msg = self._rpc_stop()
print("msg is", msg)
return msg
"""
Section to handle configuration and running of the Rest serve
also to check and warn if not bound to 127.0.0.1 as a security risk
"""
rest_ip = self._config['rest_cmd_line']['listen_ip_address']
rest_port = self._config['rest_cmd_line']['listen_port']
if rest_ip != "127.0.0.1":
i=0
while i < 10:
logger.info("SECURITY WARNING - Local Rest Server listening to external connections")
logger.info("SECURITY WARNING - This is insecure please set to 127.0.0.1 in config.json")
i += 1
# Run the Server
logger.info('Starting Local Rest Server')
app.run(host=rest_ip, port=rest_port)

View File

@ -4,12 +4,20 @@ Simple command line client into RPC commands
Can be used as an alternate to Telegram Can be used as an alternate to Telegram
""" """
import time
from requests import get from requests import get
from sys import argv from sys import argv
#TODO - use argparse to clean this up
#TODO - use IP and Port from config.json not hardcode
if len(argv) == 1: if len(argv) == 1:
print('\nThis script accepts the following arguments') print('\nThis script accepts the following arguments')
print('- daily (int) - Where int is the number of days to report back. daily 3') print('- daily (int) - Where int is the number of days to report back. daily 3')
print('- start - this will start the trading thread')
print('- stop - this will start the trading thread')
print('- there will be more....\n') print('- there will be more....\n')
if len(argv) == 3 and argv[1] == "daily": if len(argv) == 3 and argv[1] == "daily":
@ -20,4 +28,26 @@ if len(argv) == 3 and argv[1] == "daily":
else: else:
print("\nThe second argument to daily must be an integer, 1,2,3 etc") print("\nThe second argument to daily must be an integer, 1,2,3 etc")
if len(argv) == 2 and argv[1] == "start":
get_url = 'http://localhost:5002/start'
d = get(get_url).text
print(d)
if "already" not in d:
time.sleep(2)
d = get(get_url).text
print(d)
if len(argv) == 2 and argv[1] == "stop":
get_url = 'http://localhost:5002/stop'
d = get(get_url).text
print(d)
if "already" not in d:
time.sleep(2)
d = get(get_url).text
print(d)