. Decorator for api endpoints error handling

. Input validation in api parameters
. credentials.py import fallback
This commit is contained in:
Nicolás Sánchez 2026-06-04 15:07:47 -03:00
parent ca817b6a13
commit e888ee0c78
3 changed files with 289 additions and 322 deletions

View File

@ -3,7 +3,9 @@
. Minor fixes to string handling . Minor fixes to string handling
. Fixed misplaced lock . Fixed misplaced lock
. Fixed config dict mutation . Fixed config dict mutation
. Decorator for api endpoints error handling
. Input validation in api parameters
. credentials.py import fallback
2026.06.03: 2026.06.03:
. Fixed tp mode 2 non-functional . Fixed tp mode 2 non-functional

View File

@ -1,6 +1,5 @@
import collections import collections
import time import time
import credentials
import sqlite3 import sqlite3
from contextlib import contextmanager from contextlib import contextmanager
from requests import get as requests_get from requests import get as requests_get
@ -8,6 +7,11 @@ from json import load, dumps
from copy import deepcopy from copy import deepcopy
from urllib.parse import quote from urllib.parse import quote
try:
import credentials
except ModuleNotFoundError:
print("ERROR: credentials.py not found. Copy credentials.py.example to credentials.py and fill in your API keys")
raise
class Broker: class Broker:
def __init__(self,exchange,broker_config,config_filename): def __init__(self,exchange,broker_config,config_filename):

227
main.py
View File

@ -5,6 +5,7 @@ from sys import argv, stdout
from os import _exit as os_exit from os import _exit as os_exit
from json import load from json import load
from datetime import date from datetime import date
from functools import wraps
from threading import Thread, Lock from threading import Thread, Lock
from waitress import serve from waitress import serve
from concurrent.futures import ThreadPoolExecutor, as_completed from concurrent.futures import ThreadPoolExecutor, as_completed
@ -494,9 +495,21 @@ def display_splashscreen():
######### API ########### ######### API ###########
######################### #########################
def api_error_handler(f):
@wraps(f)
def wrapper(*args,**kwargs):
try:
return f(*args,**kwargs)
except Exception as e:
broker.logger.log_this(f"API error in {f.__name__}: {e}", 1)
return jsonify({"Error": "Halp"})
return wrapper
base_api = Flask(__name__) base_api = Flask(__name__)
@base_api.route("/global_status", methods=['GET']) @base_api.route("/global_status", methods=['GET'])
@api_error_handler
def return_global_status(): def return_global_status():
''' '''
GET request GET request
@ -511,6 +524,7 @@ def return_global_status():
@base_api.route("/paused_traders", methods=['GET']) @base_api.route("/paused_traders", methods=['GET'])
@api_error_handler
def return_paused_status(): def return_paused_status():
''' '''
GET request GET request
@ -524,6 +538,7 @@ def return_paused_status():
@base_api.route("/worker_status", methods=['GET']) @base_api.route("/worker_status", methods=['GET'])
@api_error_handler
def return_worker_status(): def return_worker_status():
''' '''
GET request GET request
@ -535,16 +550,13 @@ def return_worker_status():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
base = request.args.get("base") base = request.args.get("base")
quote = request.args.get("quote") quote = request.args.get("quote")
return unwrapped_return_worker_status(base,quote) return unwrapped_return_worker_status(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/view_old_long", methods=["GET"]) @base_api.route("/view_old_long", methods=["GET"])
@api_error_handler
def return_old_long(): def return_old_long():
''' '''
GET request GET request
@ -557,17 +569,14 @@ def return_old_long():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
base = request.args.get("base") base = request.args.get("base")
quote = request.args.get("quote") quote = request.args.get("quote")
from_file = request.args.get("from_file") from_file = request.args.get("from_file")
return unwrapped_view_old_long(base,quote,from_file) return unwrapped_view_old_long(base,quote,from_file)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/switch_to_long_price", methods=["GET"]) @base_api.route("/switch_to_long_price", methods=["GET"])
@api_error_handler
def return_switch_price(): def return_switch_price():
''' '''
GET request GET request
@ -579,17 +588,13 @@ def return_switch_price():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
base = request.args.get("base") base = request.args.get("base")
quote = request.args.get("quote") quote = request.args.get("quote")
return unwrapped_switch_to_long_price(base,quote) return unwrapped_switch_to_long_price(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/base_add_so_calculation", methods=["GET"]) @base_api.route("/base_add_so_calculation", methods=["GET"])
@api_error_handler
def return_base_add_so_calculation(): def return_base_add_so_calculation():
''' '''
GET request GET request
@ -601,16 +606,13 @@ def return_base_add_so_calculation():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
base = request.args.get("base") base = request.args.get("base")
quote = request.args.get("quote") quote = request.args.get("quote")
return unwrapped_base_add_so_calculation(base,quote) return unwrapped_base_add_so_calculation(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/get_all_worker_status", methods=['GET']) @base_api.route("/get_all_worker_status", methods=['GET'])
@api_error_handler
def return_all_worker_status(): def return_all_worker_status():
''' '''
GET request GET request
@ -625,6 +627,7 @@ def return_all_worker_status():
@base_api.route("/add_pair", methods=['POST']) @base_api.route("/add_pair", methods=['POST'])
@api_error_handler
def add_pair(): def add_pair():
''' '''
POST request POST request
@ -636,19 +639,16 @@ def add_pair():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
base = data["base"] base = data["base"]
quote = data["quote"] quote = data["quote"]
return unwrapped_add_pair(base,quote) return unwrapped_add_pair(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/remove_pair", methods=['POST']) @base_api.route("/remove_pair", methods=['POST'])
@api_error_handler
def remove_pair(): def remove_pair():
''' '''
POST request POST request
@ -660,19 +660,16 @@ def remove_pair():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
base = data["base"] base = data["base"]
quote = data["quote"] quote = data["quote"]
return unwrapped_remove_pair(base,quote) return unwrapped_remove_pair(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/restart_pair", methods=['POST']) @base_api.route("/restart_pair", methods=['POST'])
@api_error_handler
def restart_pair(): def restart_pair():
''' '''
POST request POST request
@ -684,19 +681,16 @@ def restart_pair():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
base = data["base"] base = data["base"]
quote = data["quote"] quote = data["quote"]
return unwrapped_restart_pair(base,quote) return unwrapped_restart_pair(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/import_pair", methods=['POST']) @base_api.route("/import_pair", methods=['POST'])
@api_error_handler
def import_pair(): def import_pair():
''' '''
POST request POST request
@ -710,19 +704,16 @@ def import_pair():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
base = data["base"] base = data["base"]
quote = data["quote"] quote = data["quote"]
return unwrapped_import_pair(base,quote) return unwrapped_import_pair(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/switch_to_long", methods=['POST']) @base_api.route("/switch_to_long", methods=['POST'])
@api_error_handler
def switch_to_long(): def switch_to_long():
''' '''
POST request POST request
@ -735,7 +726,6 @@ def switch_to_long():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
@ -743,12 +733,10 @@ def switch_to_long():
quote = data["quote"] quote = data["quote"]
calculate_profits = data["calculate_profits"] calculate_profits = data["calculate_profits"]
return unwrapped_switch_to_long(base,quote,calculate_profits) return unwrapped_switch_to_long(base,quote,calculate_profits)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/switch_to_short", methods=['POST']) @base_api.route("/switch_to_short", methods=['POST'])
@api_error_handler
def switch_to_short(): def switch_to_short():
''' '''
POST request POST request
@ -760,19 +748,16 @@ def switch_to_short():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
base = data["base"] base = data["base"]
quote = data["quote"] quote = data["quote"]
return unwrapped_switch_to_short(base,quote) return unwrapped_switch_to_short(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/load_old_long", methods=['POST']) @base_api.route("/load_old_long", methods=['POST'])
@api_error_handler
def load_old_long(): def load_old_long():
''' '''
POST request POST request
@ -784,19 +769,16 @@ def load_old_long():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
base = data["base"] base = data["base"]
quote = data["quote"] quote = data["quote"]
return unwrapped_load_old_long(base,quote) return unwrapped_load_old_long(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/add_so", methods=['POST']) @base_api.route("/add_so", methods=['POST'])
@api_error_handler
def add_so(): def add_so():
''' '''
POST request POST request
@ -809,7 +791,6 @@ def add_so():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
@ -817,12 +798,10 @@ def add_so():
quote = data["quote"] quote = data["quote"]
amount = data["amount"] amount = data["amount"]
return unwrapped_add_safety_orders(base,quote,amount) return unwrapped_add_safety_orders(base,quote,amount)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/mod_tp_level", methods=['POST']) @base_api.route("/mod_tp_level", methods=['POST'])
@api_error_handler
def mod_tp_level(): def mod_tp_level():
''' '''
POST request POST request
@ -835,7 +814,6 @@ def mod_tp_level():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
@ -843,12 +821,10 @@ def mod_tp_level():
quote = data["quote"] quote = data["quote"]
amount = data["amount"] amount = data["amount"]
return unwrapped_mod_tp_level(base,quote,amount) return unwrapped_mod_tp_level(base,quote,amount)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/mod_order_size", methods=['POST']) @base_api.route("/mod_order_size", methods=['POST'])
@api_error_handler
def mod_order_size(): def mod_order_size():
''' '''
POST request POST request
@ -861,7 +837,6 @@ def mod_order_size():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
@ -869,12 +844,10 @@ def mod_order_size():
quote = data["quote"] quote = data["quote"]
amount = data["amount"] amount = data["amount"]
return unwrapped_mod_order_size(base,quote,amount) return unwrapped_mod_order_size(base,quote,amount)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/mod_concurrent_safety_orders", methods=['POST']) @base_api.route("/mod_concurrent_safety_orders", methods=['POST'])
@api_error_handler
def mod_concurrent_safety_orders(): def mod_concurrent_safety_orders():
''' '''
POST request POST request
@ -887,7 +860,6 @@ def mod_concurrent_safety_orders():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
@ -895,12 +867,10 @@ def mod_concurrent_safety_orders():
quote = data["quote"] quote = data["quote"]
amount = data["amount"] amount = data["amount"]
return unwrapped_mod_concurrent_safety_orders(base,quote,amount) return unwrapped_mod_concurrent_safety_orders(base,quote,amount)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/mod_boosted_concurrent_safety_orders", methods=['POST']) @base_api.route("/mod_boosted_concurrent_safety_orders", methods=['POST'])
@api_error_handler
def mod_boosted_concurrent_safety_orders(): def mod_boosted_concurrent_safety_orders():
''' '''
POST request POST request
@ -913,7 +883,6 @@ def mod_boosted_concurrent_safety_orders():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
@ -921,12 +890,10 @@ def mod_boosted_concurrent_safety_orders():
quote = data["quote"] quote = data["quote"]
amount = data["amount"] amount = data["amount"]
return unwrapped_mod_boosted_concurrent_safety_orders(base,quote,amount) return unwrapped_mod_boosted_concurrent_safety_orders(base,quote,amount)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/mod_default_order_size", methods=['POST']) @base_api.route("/mod_default_order_size", methods=['POST'])
@api_error_handler
def mod_default_order_size(): def mod_default_order_size():
''' '''
POST request POST request
@ -937,18 +904,15 @@ def mod_default_order_size():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
amount = data["amount"] amount = data["amount"]
return unwrapped_mod_default_order_size(amount) return unwrapped_mod_default_order_size(amount)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/mod_global_tp_level", methods=['POST']) @base_api.route("/mod_global_tp_level", methods=['POST'])
@api_error_handler
def mod_global_tp_level(): def mod_global_tp_level():
''' '''
POST request POST request
@ -959,18 +923,15 @@ def mod_global_tp_level():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
amount = data["amount"] amount = data["amount"]
return unwrapped_mod_global_tp_level(amount) return unwrapped_mod_global_tp_level(amount)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/last_call", methods=['POST']) @base_api.route("/last_call", methods=['POST'])
@api_error_handler
def last_call(): def last_call():
''' '''
POST request POST request
@ -982,19 +943,16 @@ def last_call():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
base = data["base"] base = data["base"]
quote = data["quote"] quote = data["quote"]
return unwrapped_last_call(base,quote) return unwrapped_last_call(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/deferred_last_call", methods=['POST']) @base_api.route("/deferred_last_call", methods=['POST'])
@api_error_handler
def deferred_last_call(): def deferred_last_call():
''' '''
POST request POST request
@ -1007,7 +965,6 @@ def deferred_last_call():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
@ -1015,12 +972,10 @@ def deferred_last_call():
quote = data["quote"] quote = data["quote"]
yyyymmdd = data["yyyymmdd"] yyyymmdd = data["yyyymmdd"]
return unwrapped_deferred_last_call(base,quote,yyyymmdd) return unwrapped_deferred_last_call(base,quote,yyyymmdd)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/toggle_pause", methods=['POST']) @base_api.route("/toggle_pause", methods=['POST'])
@api_error_handler
def toggle_pause(): def toggle_pause():
''' '''
POST request POST request
@ -1032,19 +987,16 @@ def toggle_pause():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
base = data["base"] base = data["base"]
quote = data["quote"] quote = data["quote"]
return unwrapped_toggle_pause(base,quote) return unwrapped_toggle_pause(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/global_last_call", methods=['POST']) @base_api.route("/global_last_call", methods=['POST'])
@api_error_handler
def global_last_call(): def global_last_call():
''' '''
POST request POST request
@ -1059,6 +1011,7 @@ def global_last_call():
@base_api.route("/cancel_global_last_call", methods=['POST']) @base_api.route("/cancel_global_last_call", methods=['POST'])
@api_error_handler
def cancel_global_last_call(): def cancel_global_last_call():
''' '''
POST request POST request
@ -1073,6 +1026,7 @@ def cancel_global_last_call():
@base_api.route("/add_quote", methods=['POST']) @base_api.route("/add_quote", methods=['POST'])
@api_error_handler
def add_quote(): def add_quote():
''' '''
POST request POST request
@ -1085,7 +1039,6 @@ def add_quote():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
@ -1093,12 +1046,10 @@ def add_quote():
quote = data["quote"] quote = data["quote"]
amount = data["amount"] amount = data["amount"]
return unwrapped_add_quote(base,quote,amount) return unwrapped_add_quote(base,quote,amount)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/missing_pairs", methods=['GET']) @base_api.route("/missing_pairs", methods=['GET'])
@api_error_handler
def missing_pairs(): def missing_pairs():
''' '''
GET request GET request
@ -1113,6 +1064,7 @@ def missing_pairs():
@base_api.route("/toggle_cleanup", methods=['POST']) @base_api.route("/toggle_cleanup", methods=['POST'])
@api_error_handler
def toggle_cleanup(): def toggle_cleanup():
''' '''
POST request POST request
@ -1124,19 +1076,16 @@ def toggle_cleanup():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
base = data["base"] base = data["base"]
quote = data["quote"] quote = data["quote"]
return unwrapped_toggle_cleanup(base,quote) return unwrapped_toggle_cleanup(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/toggle_autoswitch", methods=['POST']) @base_api.route("/toggle_autoswitch", methods=['POST'])
@api_error_handler
def toggle_autoswitch(): def toggle_autoswitch():
''' '''
POST request POST request
@ -1148,19 +1097,16 @@ def toggle_autoswitch():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
base = data["base"] base = data["base"]
quote = data["quote"] quote = data["quote"]
return unwrapped_toggle_autoswitch(base,quote) return unwrapped_toggle_autoswitch(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/force_trader_close", methods=['POST']) @base_api.route("/force_trader_close", methods=['POST'])
@api_error_handler
def force_trader_close(): def force_trader_close():
''' '''
POST request POST request
@ -1172,19 +1118,16 @@ def force_trader_close():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
base = data["base"] base = data["base"]
quote = data["quote"] quote = data["quote"]
return unwrapped_force_trader_close(base,quote) return unwrapped_force_trader_close(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/toggle_liquidate_after_switch", methods=['POST']) @base_api.route("/toggle_liquidate_after_switch", methods=['POST'])
@api_error_handler
def toggle_liquidate_after_switch(): def toggle_liquidate_after_switch():
''' '''
POST request POST request
@ -1196,19 +1139,16 @@ def toggle_liquidate_after_switch():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
base = data["base"] base = data["base"]
quote = data["quote"] quote = data["quote"]
return unwrapped_toggle_liquidate_after_switch(base,quote) return unwrapped_toggle_liquidate_after_switch(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/toggle_check_old_long_price", methods=['POST']) @base_api.route("/toggle_check_old_long_price", methods=['POST'])
@api_error_handler
def toggle_check_old_long_price(): def toggle_check_old_long_price():
''' '''
POST request POST request
@ -1220,19 +1160,16 @@ def toggle_check_old_long_price():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
base = data["base"] base = data["base"]
quote = data["quote"] quote = data["quote"]
return unwrapped_toggle_check_old_long_price(base,quote) return unwrapped_toggle_check_old_long_price(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/switch_quote_currency", methods=['POST']) @base_api.route("/switch_quote_currency", methods=['POST'])
@api_error_handler
def switch_quote_currency(): def switch_quote_currency():
''' '''
POST request POST request
@ -1245,7 +1182,6 @@ def switch_quote_currency():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
@ -1253,12 +1189,10 @@ def switch_quote_currency():
quote = data["quote"] quote = data["quote"]
new_quote = data["new_quote"] new_quote = data["new_quote"]
return unwrapped_switch_quote_currency(base,quote,new_quote) return unwrapped_switch_quote_currency(base,quote,new_quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/toggle_log_orders", methods=['POST']) @base_api.route("/toggle_log_orders", methods=['POST'])
@api_error_handler
def toggle_log_orders(): def toggle_log_orders():
''' '''
POST request POST request
@ -1273,6 +1207,7 @@ def toggle_log_orders():
@base_api.route("/toggle_restart", methods=['POST']) @base_api.route("/toggle_restart", methods=['POST'])
@api_error_handler
def toggle_restart(): def toggle_restart():
''' '''
POST request POST request
@ -1287,6 +1222,7 @@ def toggle_restart():
@base_api.route("/toggle_telegram", methods=['POST']) @base_api.route("/toggle_telegram", methods=['POST'])
@api_error_handler
def toggle_telegram(): def toggle_telegram():
''' '''
POST request POST request
@ -1301,6 +1237,7 @@ def toggle_telegram():
@base_api.route("/server_time", methods=['GET']) @base_api.route("/server_time", methods=['GET'])
@api_error_handler
def server_time(): def server_time():
''' '''
GET request GET request
@ -1329,6 +1266,7 @@ def get_log_list():
@base_api.route("/refresh_log_cache", methods=['POST']) @base_api.route("/refresh_log_cache", methods=['POST'])
@api_error_handler
def refresh_log_cache(): def refresh_log_cache():
''' '''
POST request POST request
@ -1336,14 +1274,11 @@ def refresh_log_cache():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
return unwrapped_refresh_log_cache() return unwrapped_refresh_log_cache()
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/get_balance", methods=['GET']) @base_api.route("/get_balance", methods=['GET'])
@api_error_handler
def get_balance(): def get_balance():
''' '''
GET request GET request
@ -1359,6 +1294,7 @@ def get_balance():
@base_api.route("/get_deals_cache", methods=['GET']) @base_api.route("/get_deals_cache", methods=['GET'])
@api_error_handler
def get_deals_cache(): def get_deals_cache():
''' '''
GET request GET request
@ -1373,6 +1309,7 @@ def get_deals_cache():
@base_api.route("/trader_time", methods=['GET']) @base_api.route("/trader_time", methods=['GET'])
@api_error_handler
def trader_time(): def trader_time():
''' '''
GET request GET request
@ -1387,6 +1324,7 @@ def trader_time():
@base_api.route("/edit_loop_wait_time", methods=['POST']) @base_api.route("/edit_loop_wait_time", methods=['POST'])
@api_error_handler
def loop_wait_time(): def loop_wait_time():
''' '''
POST request POST request
@ -1397,18 +1335,15 @@ def loop_wait_time():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
wait_time = data["wait_time"] wait_time = data["wait_time"]
return unwrapped_loop_wait_time(wait_time) return unwrapped_loop_wait_time(wait_time)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/edit_call_wait_time", methods=['POST']) @base_api.route("/edit_call_wait_time", methods=['POST'])
@api_error_handler
def call_wait_time(): def call_wait_time():
''' '''
POST request POST request
@ -1419,18 +1354,15 @@ def call_wait_time():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
wait_time = data["wait_time"] wait_time = data["wait_time"]
return unwrapped_call_wait_time(wait_time) return unwrapped_call_wait_time(wait_time)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/edit_cooldown_multiplier", methods=['POST']) @base_api.route("/edit_cooldown_multiplier", methods=['POST'])
@api_error_handler
def edit_cooldown_multiplier(): def edit_cooldown_multiplier():
''' '''
POST request POST request
@ -1441,18 +1373,15 @@ def edit_cooldown_multiplier():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
multiplier = data["cooldown_multiplier"] multiplier = data["cooldown_multiplier"]
return unwrapped_edit_cooldown_multiplier(multiplier) return unwrapped_edit_cooldown_multiplier(multiplier)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
@base_api.route("/reload_markets", methods=['POST']) @base_api.route("/reload_markets", methods=['POST'])
@api_error_handler
def reload_markets(): def reload_markets():
''' '''
POST request POST request
@ -1468,6 +1397,7 @@ def reload_markets():
@base_api.route("/reload_trader_config", methods=['POST']) @base_api.route("/reload_trader_config", methods=['POST'])
@api_error_handler
def reload_trader_config(): def reload_trader_config():
''' '''
POST request POST request
@ -1479,16 +1409,12 @@ def reload_trader_config():
if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys: if not "X-API-KEY" in request.headers or not request.headers.get("X-API-KEY") in valid_keys:
return jsonify({'Error': 'API key invalid'}), 401 return jsonify({'Error': 'API key invalid'}), 401
try:
if request.json is None: if request.json is None:
return jsonify({'Error': 'request.json is None'}) return jsonify({'Error': 'request.json is None'})
data = request.json data = request.json
base = data["base"] base = data["base"]
quote = data["quote"] quote = data["quote"]
return unwrapped_reload_trader_config(base,quote) return unwrapped_reload_trader_config(base,quote)
except Exception as e:
print(e)
return jsonify({'Error': 'Halp'})
def run_API(): def run_API():
@ -1500,6 +1426,11 @@ def run_API():
# Unwrapped API functions # # Unwrapped API functions #
########################### ###########################
def validate_pair_param(base, quote):
if not base or not quote or not base.isalpha() or not quote.isalpha():
raise ValueError(f"Invalid pair: {base}/{quote}")
return base.upper(), quote.upper()
def unwrapped_global_status(): def unwrapped_global_status():
''' '''
Returns the global status dictionary of the instance. Returns the global status dictionary of the instance.
@ -1524,6 +1455,7 @@ def unwrapped_return_worker_status(base,quote):
Returns: Returns:
dict: The status dictionary of the trader. dict: The status dictionary of the trader.
''' '''
base, quote = validate_pair_param(base,quote)
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
for instance in running_traders: for instance in running_traders:
@ -1555,6 +1487,7 @@ def unwrapped_add_pair(base,quote):
jsonified dictionary detailing the outcome of the operation. jsonified dictionary detailing the outcome of the operation.
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
@ -1592,6 +1525,7 @@ def unwrapped_remove_pair(base,quote):
jsonified dictionary detailing the outcome of the operation. jsonified dictionary detailing the outcome of the operation.
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
@ -1616,6 +1550,7 @@ def unwrapped_restart_pair(base,quote):
jsonified dictionary detailing the outcome of the operation. jsonified dictionary detailing the outcome of the operation.
''' '''
base, quote = validate_pair_param(base,quote)
if restart_pair_no_json(base,quote)==0: if restart_pair_no_json(base,quote)==0:
return jsonify({"Success": "Pair restarted"}) return jsonify({"Success": "Pair restarted"})
return jsonify({"Error": "Halp"}) return jsonify({"Error": "Halp"})
@ -1633,6 +1568,7 @@ def unwrapped_import_pair(base,quote):
jsonified dictionary detailing the outcome of the operation. jsonified dictionary detailing the outcome of the operation.
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
import_instance(base,quote) import_instance(base,quote)
@ -1658,6 +1594,7 @@ def unwrapped_switch_to_long(base,quote,calculate_profits):
jsonify: A jsonified dictionary detailing the outcome of the operation jsonify: A jsonified dictionary detailing the outcome of the operation
''' '''
base, quote = validate_pair_param(base,quote)
ignore_old_long = int(calculate_profits)!=1 ignore_old_long = int(calculate_profits)!=1
#Close trader and orders and pull info our of the orders #Close trader and orders and pull info our of the orders
if f"{base}{quote}" not in broker.get_pairs(): if f"{base}{quote}" not in broker.get_pairs():
@ -1687,6 +1624,7 @@ def unwrapped_switch_to_short(base,quote):
jsonify: A jsonified dictionary detailing the outcome of the operation jsonify: A jsonified dictionary detailing the outcome of the operation
''' '''
base, quote = validate_pair_param(base,quote)
#Close trader and orders and pull info our of the orders #Close trader and orders and pull info our of the orders
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
if f"{base}{quote}" not in broker.get_pairs(): if f"{base}{quote}" not in broker.get_pairs():
@ -1732,6 +1670,7 @@ def unwrapped_load_old_long(base,quote):
jsonify: A jsonified dictionary detailing the outcome of the operation jsonify: A jsonified dictionary detailing the outcome of the operation
''' '''
base, quote = validate_pair_param(base,quote)
#Load the file #Load the file
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
@ -1771,6 +1710,7 @@ def unwrapped_view_old_long(base,quote,from_file):
jsonify: A jsonified dictionary containing the old_long info. jsonify: A jsonified dictionary containing the old_long info.
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
if int(from_file)==1: if int(from_file)==1:
@ -1802,6 +1742,7 @@ def unwrapped_switch_to_long_price(base,quote):
jsonify: A jsonified dictionary containing the old_long info. jsonify: A jsonified dictionary containing the old_long info.
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
@ -1834,6 +1775,7 @@ def unwrapped_add_safety_orders(base,quote,amount):
jsonify: A jsonified dictionary detailing the outcome of the operation jsonify: A jsonified dictionary detailing the outcome of the operation
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
@ -1865,6 +1807,7 @@ def unwrapped_base_add_so_calculation(base,quote):
jsonify: A jsonified dictionary with the amount of orders that can be added. jsonify: A jsonified dictionary with the amount of orders that can be added.
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
@ -1894,6 +1837,7 @@ def unwrapped_mod_tp_level(base,quote,amount):
jsonify: A jsonified dictionary detailing the outcome of the operation jsonify: A jsonified dictionary detailing the outcome of the operation
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
@ -1920,6 +1864,7 @@ def unwrapped_mod_order_size(base,quote,amount):
jsonify: A jsonified dictionary detailing the outcome of the operation jsonify: A jsonified dictionary detailing the outcome of the operation
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
@ -1947,6 +1892,7 @@ def unwrapped_mod_concurrent_safety_orders(base,quote,amount):
jsonify: A jsonified dictionary detailing the outcome of the operation jsonify: A jsonified dictionary detailing the outcome of the operation
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
@ -1974,6 +1920,7 @@ def unwrapped_mod_boosted_concurrent_safety_orders(base,quote,amount):
jsonify: A jsonified dictionary detailing the outcome of the operation jsonify: A jsonified dictionary detailing the outcome of the operation
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
@ -2040,6 +1987,7 @@ def unwrapped_last_call(base,quote):
jsonify: A jsonified dictionary detailing the outcome of the operation jsonify: A jsonified dictionary detailing the outcome of the operation
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
@ -2070,6 +2018,7 @@ def unwrapped_deferred_last_call(base,quote,yyyymmdd):
jsonify: A jsonified dictionary detailing the outcome of the operation. jsonify: A jsonified dictionary detailing the outcome of the operation.
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
year = yyyymmdd[:4] year = yyyymmdd[:4]
month = yyyymmdd[4:6] month = yyyymmdd[4:6]
@ -2102,6 +2051,7 @@ def unwrapped_toggle_pause(base,quote):
jsonify: A jsonified dictionary detailing the outcome of the operation. jsonify: A jsonified dictionary detailing the outcome of the operation.
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
toggle_pauses.append(symbol) toggle_pauses.append(symbol)
@ -2166,6 +2116,8 @@ def unwrapped_add_quote(base,quote,amount):
Returns: Returns:
json: A jsonified dictionary detailing the outcome of the operation. json: A jsonified dictionary detailing the outcome of the operation.
''' '''
base, quote = validate_pair_param(base,quote)
with traders_lock: with traders_lock:
for instance in running_traders: for instance in running_traders:
if f"{base}/{quote}"==instance.status.get_pair(): if f"{base}/{quote}"==instance.status.get_pair():
@ -2228,6 +2180,7 @@ def unwrapped_missing_pairs():
Returns: Returns:
jsonify: A jsonify object with a list of the missing pairs jsonify: A jsonify object with a list of the missing pairs
''' '''
try: try:
missing_pairs = broker.get_pairs() missing_pairs = broker.get_pairs()
for trader in running_traders: for trader in running_traders:
@ -2251,6 +2204,7 @@ def unwrapped_toggle_cleanup(base,quote):
jsonify: A jsonified dictionary detailing the outcome of the operation. jsonify: A jsonified dictionary detailing the outcome of the operation.
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
@ -2278,6 +2232,7 @@ def unwrapped_force_trader_close(base,quote):
jsonify: A jsonified dictionary detailing the outcome of the operation. jsonify: A jsonified dictionary detailing the outcome of the operation.
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
@ -2305,6 +2260,7 @@ def unwrapped_toggle_autoswitch(base,quote):
A jsonified dictionary detailing the outcome of the operation. A jsonified dictionary detailing the outcome of the operation.
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
@ -2336,6 +2292,7 @@ def unwrapped_toggle_liquidate_after_switch(base,quote):
A jsonified dictionary detailing the outcome of the operation. A jsonified dictionary detailing the outcome of the operation.
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
@ -2367,6 +2324,7 @@ def unwrapped_toggle_check_old_long_price(base,quote):
jsonify: A jsonified dictionary detailing the outcome of the operation. jsonify: A jsonified dictionary detailing the outcome of the operation.
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
with traders_lock: with traders_lock:
@ -2399,6 +2357,7 @@ def unwrapped_switch_quote_currency(base,quote,new_quote):
jsonify: A jsonified dictionary detailing the outcome of the operation. jsonify: A jsonified dictionary detailing the outcome of the operation.
''' '''
base, quote = validate_pair_param(base,quote)
try: try:
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
for trader in running_traders: for trader in running_traders:
@ -2631,6 +2590,8 @@ def unwrapped_reload_trader_config(base,quote):
Returns: Returns:
jsonify: A jsonified dictionary detailing the outcome of the operation. jsonify: A jsonified dictionary detailing the outcome of the operation.
''' '''
base, quote = validate_pair_param(base,quote)
symbol = f"{base}/{quote}" symbol = f"{base}/{quote}"
for trader in running_traders: for trader in running_traders:
if trader.status.get_pair() == symbol: if trader.status.get_pair() == symbol: