freqtrade_origin/scripts/rest_client.py

188 lines
5.6 KiB
Python
Raw Normal View History

2019-04-04 05:08:24 +00:00
#!/usr/bin/env python3
"""
Simple command line client into RPC commands
Can be used as an alternate to Telegram
2019-04-04 19:07:44 +00:00
Should not import anything from freqtrade,
so it can be used as a standalone script.
2019-04-04 05:08:24 +00:00
"""
2019-04-04 19:07:44 +00:00
import argparse
2019-04-09 04:40:15 +00:00
import json
2019-04-04 19:07:44 +00:00
import logging
2019-04-26 07:27:20 +00:00
import inspect
2019-04-25 18:32:10 +00:00
from urllib.parse import urlencode, urlparse, urlunparse
2019-04-09 04:40:15 +00:00
from pathlib import Path
2019-04-04 19:07:44 +00:00
2019-04-25 18:32:10 +00:00
import requests
2019-04-04 19:07:44 +00:00
from requests.exceptions import ConnectionError
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
)
logger = logging.getLogger("ft_rest_client")
2019-04-04 05:08:24 +00:00
2019-04-04 19:07:44 +00:00
COMMANDS_NO_ARGS = ["start",
"stop",
2019-04-09 04:40:15 +00:00
"stopbuy",
"reload_conf",
2019-04-04 19:07:44 +00:00
]
INFO_COMMANDS = {"version": [],
"count": [],
"daily": ["timescale"],
"profit": [],
"status": [],
"balance": []
}
2019-04-04 19:07:44 +00:00
2019-04-25 18:32:10 +00:00
class FtRestClient():
def __init__(self, serverurl):
2019-04-26 07:08:03 +00:00
self.serverurl = serverurl
2019-04-25 18:32:10 +00:00
self.session = requests.Session()
2019-04-26 07:10:23 +00:00
def _call(self, method, apipath, params: dict = None, data=None, files=None):
2019-04-25 18:32:10 +00:00
if str(method).upper() not in ('GET', 'POST', 'PUT', 'DELETE'):
raise ValueError('invalid method <{0}>'.format(method))
basepath = f"{self.serverurl}/{apipath}"
hd = {"Accept": "application/json",
"Content-Type": "application/json"
}
# Split url
2019-04-26 07:27:20 +00:00
schema, netloc, path, par, query, fragment = urlparse(basepath)
2019-04-25 18:32:10 +00:00
# URLEncode query string
query = urlencode(params)
# recombine url
2019-04-26 07:27:20 +00:00
url = urlunparse((schema, netloc, path, par, query, fragment))
2019-04-25 18:32:10 +00:00
print(url)
try:
2019-04-26 07:08:03 +00:00
resp = self.session.request(method, url, headers=hd, data=data,
# auth=self.session.auth
)
# return resp.text
return resp.json()
2019-04-25 18:32:10 +00:00
except ConnectionError:
logger.warning("Connection error")
2019-04-26 07:27:20 +00:00
def _get(self, apipath, params: dict = None):
return self._call("GET", apipath, params=params)
def _post(self, apipath, params: dict = None, data: dict = None):
return self._call("POST", apipath, params=params, data=data)
2019-04-26 07:10:23 +00:00
def _call_command_noargs(self, command):
2019-04-25 18:32:10 +00:00
logger.info(f"Running command `{command}` at {self.serverurl}")
2019-04-26 07:10:23 +00:00
r = self._call("POST", command)
2019-04-25 18:32:10 +00:00
logger.info(r)
2019-04-26 07:10:23 +00:00
def _call_info(self, command, command_args):
2019-04-25 18:32:10 +00:00
logger.info(
f"Running command `{command}` with parameters `{command_args}` at {self.serverurl}")
args = INFO_COMMANDS[command]
if len(args) < len(command_args):
logger.error(f"Command {command} does only support {len(args)} arguments.")
return
params = {}
for idx, arg in enumerate(command_args):
params[args[idx]] = arg
logger.debug(params)
2019-04-26 07:10:23 +00:00
r = self._call("GET", command, params)
2019-04-25 18:32:10 +00:00
logger.info(r)
2019-04-26 07:27:20 +00:00
def version(self):
"""
Returns the version of the bot
:returns: json object containing the version
"""
return self._get("version")
def count(self):
"""
Returns the amount of open trades
:returns: json object
"""
return self._get("count")
def daily(self, days=None):
"""
Returns the amount of open trades
:returns: json object
"""
return self._get("daily", params={"timescale": days} if days else None)
2019-04-25 18:32:10 +00:00
2019-04-04 19:07:44 +00:00
def add_arguments():
parser = argparse.ArgumentParser()
parser.add_argument("command",
help="Positional argument defining the command to execute.")
2019-04-09 04:40:15 +00:00
parser.add_argument('-c', '--config',
help='Specify configuration file (default: %(default)s). ',
dest='config',
type=str,
metavar='PATH',
default='config.json'
)
2019-04-26 07:12:03 +00:00
parser.add_argument("command_arguments",
help="Positional arguments for the parameters for [command]",
nargs="*",
default=[]
)
2019-04-04 19:07:44 +00:00
args = parser.parse_args()
# if len(argv) == 1:
# print('\nThis script accepts the following arguments')
# 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')
return vars(args)
2019-04-09 04:40:15 +00:00
def load_config(configfile):
file = Path(configfile)
if file.is_file():
with file.open("r") as f:
config = json.load(f)
return config
return {}
2019-04-09 04:40:15 +00:00
2019-04-04 19:07:44 +00:00
def main(args):
2019-04-09 04:40:15 +00:00
config = load_config(args["config"])
url = config.get("api_server", {}).get("server_url", "127.0.0.1")
port = config.get("api_server", {}).get("listen_port", "8080")
server_url = f"http://{url}:{port}"
2019-04-25 18:32:10 +00:00
client = FtRestClient(server_url)
2019-04-09 04:40:15 +00:00
2019-04-26 07:27:20 +00:00
m = [x for x, y in inspect.getmembers(client) if not x.startswith('_')]
command = args["command"]
if command not in m:
logger.error(f"Command {command} not defined")
return
print(getattr(client, command)(*args["command_arguments"]))
2019-04-04 19:07:44 +00:00
# Call commands without arguments
2019-04-26 07:27:20 +00:00
# if args["command"] in COMMANDS_NO_ARGS:
# client._call_command_noargs(args["command"])
2019-04-04 19:07:44 +00:00
2019-04-26 07:27:20 +00:00
# if args["command"] in INFO_COMMANDS:
# client._call_info(args["command"], args["command_arguments"])
2019-04-04 19:07:44 +00:00
if __name__ == "__main__":
args = add_arguments()
main(args)