Skip to content

Commit

Permalink
[Exchanges] support custom domains
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeDSM committed Jan 16, 2025
1 parent 10940f3 commit 5c573fd
Showing 1 changed file with 49 additions and 5 deletions.
54 changes: 49 additions & 5 deletions octobot_trading/exchanges/connectors/ccxt/ccxt_client_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library.
import asyncio
import os
import aiohttp
import copy
import logging
Expand Down Expand Up @@ -66,7 +67,7 @@ def create_client(
client = instantiate_exchange(
exchange_class,
_get_client_config(
options, headers, additional_config,
exchange_class, options, headers, additional_config,
api_key=key, secret=secret, password=password, uid=uid,
auth_token=auth_token, auth_token_header_prefix=auth_token_header_prefix
),
Expand All @@ -80,7 +81,7 @@ def create_client(
else:
client = instantiate_exchange(
exchange_class,
_get_client_config(options, headers, additional_config),
_get_client_config(exchange_class, options, headers, additional_config),
exchange_manager.exchange_name,
exchange_manager.proxy_config,
allow_request_counter=allow_request_counter
Expand Down Expand Up @@ -128,7 +129,10 @@ def get_unauthenticated_exchange(
exchange_class, options, headers, additional_config, identifier: str, proxy_config: proxy_config_import.ProxyConfig
) -> async_ccxt.Exchange:
return instantiate_exchange(
exchange_class, _get_client_config(options, headers, additional_config), identifier, proxy_config
exchange_class,
_get_client_config(exchange_class, options, headers, additional_config),
identifier,
proxy_config
)


Expand Down Expand Up @@ -303,7 +307,7 @@ def _use_proxy_if_necessary(client, proxy_config: proxy_config_import.ProxyConfi


def _get_client_config(
options, headers, additional_config,
exchange_class, options, headers, additional_config,
api_key=None, secret=None, password=None, uid=None,
auth_token=None, auth_token_header_prefix=None
):
Expand All @@ -324,10 +328,50 @@ def _get_client_config(
config['password'] = password
if uid is not None:
config['uid'] = uid
config.update(additional_config or {})
config.update({**_get_custom_domain_config(exchange_class), **(additional_config or {})})
return config


def _get_custom_domain_config(exchange_class):
old, new = _get_replaced_custom_domains(exchange_class)
if not (old and new):
return {}
if url_config := exchange_class().describe()[ccxt_enums.ExchangeColumns.URLS.value]:
commons_logging.get_logger(__name__).info(
f"Using custom domain for {exchange_class.__name__}: {old} is replaced by {new}"
)
return {
ccxt_enums.ExchangeColumns.URLS.value: _get_patched_url_config(url_config, old, new)
}
return {}


def _get_replaced_custom_domains(exchange_class):
identifier = exchange_class.__name__.upper()
if custom_domain := os.getenv(f"{identifier}_CUSTOM_DOMAIN"):
split = custom_domain.split(":")
if len(split) == 2:
return split[0], split[1]
else:
commons_logging.get_logger(__name__).error(
f"Invalid {identifier} custom domain config. Expected syntax is to_replace_domain:updated_domain "
f"Example: MEXC_CUSTOM_DOMAIN=mexc.com:mexc.co"
)
return None, None


def _get_patched_url_config(url_config: dict, old: str, new: str):
updated_config = {}
for key, val in url_config.items():
if isinstance(val, dict):
updated_config[key] = _get_patched_url_config(val, old, new)
elif isinstance(val, str):
updated_config[key] = val.replace(old, new)
else:
updated_config[key] = val
return updated_config


def _use_request_counter(identifier: str, ccxt_client: async_ccxt.Exchange):
"""
Replaces the given exchange async session by an aiohttp_util.CounterClientSession
Expand Down

0 comments on commit 5c573fd

Please sign in to comment.