diff --git a/ft_client/freqtrade_client/__init__.py b/ft_client/freqtrade_client/__init__.py index 788256881..b5ccc914e 100644 --- a/ft_client/freqtrade_client/__init__.py +++ b/ft_client/freqtrade_client/__init__.py @@ -1,4 +1,27 @@ -from ft_rest_client import FtRestClient +from freqtrade_client.ft_rest_client import FtRestClient __all__ = ['FtRestClient'] + + +__version__ = '2024.3-dev' + +if 'dev' in __version__: + from pathlib import Path + try: + import subprocess + freqtrade_basedir = Path(__file__).parent + + __version__ = __version__ + '-' + subprocess.check_output( + ['git', 'log', '--format="%h"', '-n 1'], + stderr=subprocess.DEVNULL, cwd=freqtrade_basedir).decode("utf-8").rstrip().strip('"') + + except Exception: # pragma: no cover + # git not available, ignore + try: + # Try Fallback to freqtrade_commit file (created by CI while building docker image) + versionfile = Path('./freqtrade_commit') + if versionfile.is_file(): + __version__ = f"docker-{__version__}-{versionfile.read_text()[:8]}" + except Exception: + pass diff --git a/ft_client/freqtrade_client/ft_client.py b/ft_client/freqtrade_client/ft_client.py new file mode 100644 index 000000000..db34bce16 --- /dev/null +++ b/ft_client/freqtrade_client/ft_client.py @@ -0,0 +1,106 @@ +import argparse +import inspect +import json +import logging +import re +import sys +from pathlib import Path +from typing import Any, Dict + +import rapidjson +from freqtrade_client import __version__ +from freqtrade_client.ft_rest_client import FtRestClient + + +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', +) +logger = logging.getLogger("ft_rest_client") + + +def add_arguments(): + parser = argparse.ArgumentParser() + parser.add_argument("command", + help="Positional argument defining the command to execute.", + nargs="?" + ) + parser.add_argument('-V', '--version', action='version', version=f'%(prog)s {__version__}') + parser.add_argument('--show', + help='Show possible methods with this client', + dest='show', + action='store_true', + default=False + ) + + parser.add_argument('-c', '--config', + help='Specify configuration file (default: %(default)s). ', + dest='config', + type=str, + metavar='PATH', + default='config.json' + ) + + parser.add_argument("command_arguments", + help="Positional arguments for the parameters for [command]", + nargs="*", + default=[] + ) + + args = parser.parse_args() + return vars(args) + + +def load_config(configfile): + file = Path(configfile) + if file.is_file(): + with file.open("r") as f: + config = rapidjson.load(f, parse_mode=rapidjson.PM_COMMENTS | + rapidjson.PM_TRAILING_COMMAS) + return config + else: + logger.warning(f"Could not load config file {file}.") + sys.exit(1) + + +def print_commands(): + # Print dynamic help for the different commands using the commands doc-strings + client = FtRestClient(None) + print("Possible commands:\n") + for x, y in inspect.getmembers(client): + if not x.startswith('_'): + doc = re.sub(':return:.*', '', getattr(client, x).__doc__, flags=re.MULTILINE).rstrip() + print(f"{x}\n\t{doc}\n") + + +def main_exec(args: Dict[str, Any]): + + if args.get("show"): + print_commands() + sys.exit() + + config = load_config(args['config']) + url = config.get('api_server', {}).get('listen_ip_address', '127.0.0.1') + port = config.get('api_server', {}).get('listen_port', '8080') + username = config.get('api_server', {}).get('username') + password = config.get('api_server', {}).get('password') + + server_url = f"http://{url}:{port}" + client = FtRestClient(server_url, username, password) + + 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") + print_commands() + return + + print(json.dumps(getattr(client, command)(*args["command_arguments"]))) + + +def main(): + """ + Main entry point for the client + """ + args = add_arguments() + main_exec(args) diff --git a/ft_client/freqtrade_client/ft_rest_client.py b/ft_client/freqtrade_client/ft_rest_client.py index 5970b0c5b..9dccefc33 100755 --- a/ft_client/freqtrade_client/ft_rest_client.py +++ b/ft_client/freqtrade_client/ft_rest_client.py @@ -7,25 +7,15 @@ Should not import anything from freqtrade, so it can be used as a standalone script. """ -import argparse -import inspect import json import logging -import re -import sys -from pathlib import Path from typing import Optional from urllib.parse import urlencode, urlparse, urlunparse -import rapidjson import requests 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") @@ -427,85 +417,3 @@ class FtRestClient: return self._get("health") -def add_arguments(): - parser = argparse.ArgumentParser() - parser.add_argument("command", - help="Positional argument defining the command to execute.", - nargs="?" - ) - - parser.add_argument('--show', - help='Show possible methods with this client', - dest='show', - action='store_true', - default=False - ) - - parser.add_argument('-c', '--config', - help='Specify configuration file (default: %(default)s). ', - dest='config', - type=str, - metavar='PATH', - default='config.json' - ) - - parser.add_argument("command_arguments", - help="Positional arguments for the parameters for [command]", - nargs="*", - default=[] - ) - - args = parser.parse_args() - return vars(args) - - -def load_config(configfile): - file = Path(configfile) - if file.is_file(): - with file.open("r") as f: - config = rapidjson.load(f, parse_mode=rapidjson.PM_COMMENTS | - rapidjson.PM_TRAILING_COMMAS) - return config - else: - logger.warning(f"Could not load config file {file}.") - sys.exit(1) - - -def print_commands(): - # Print dynamic help for the different commands using the commands doc-strings - client = FtRestClient(None) - print("Possible commands:\n") - for x, y in inspect.getmembers(client): - if not x.startswith('_'): - doc = re.sub(':return:.*', '', getattr(client, x).__doc__, flags=re.MULTILINE).rstrip() - print(f"{x}\n\t{doc}\n") - - -def main(args): - - if args.get("show"): - print_commands() - sys.exit() - - config = load_config(args['config']) - url = config.get('api_server', {}).get('listen_ip_address', '127.0.0.1') - port = config.get('api_server', {}).get('listen_port', '8080') - username = config.get('api_server', {}).get('username') - password = config.get('api_server', {}).get('password') - - server_url = f"http://{url}:{port}" - client = FtRestClient(server_url, username, password) - - 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") - print_commands() - return - - print(json.dumps(getattr(client, command)(*args["command_arguments"]))) - - -if __name__ == "__main__": - args = add_arguments() - main(args) diff --git a/ft_client/requirements.txt b/ft_client/requirements.txt new file mode 100644 index 000000000..56def4059 --- /dev/null +++ b/ft_client/requirements.txt @@ -0,0 +1,3 @@ +# Requirements for freqtrade client library +requests==2.31.0 +python-rapidjson==1.16