0

I am using a python library (ccxt) in which one base exchange class is inherited by exchange-specific classes, to provide a unified interface to several exchanges (coinbase, binance etc.).

The function definition for a sub-class might look something like this (not necessarily exactly): def fetch_ledger(self, symbols = None, since = None, params = {}):

The thing is, for e.g. the coinbase class, this method calls another method called prepareAccountRequestWithCurrencyCode(), which raises the exception: raise ArgumentsRequired(self.id + ' prepareAccountRequestWithCurrencyCode() method requires an account_id(or accountId) parameter OR a currency code argument') if "accountId" or "code" is not provided in the params dict. These arguments are not in the function signature, as they are to be provided in the params dict (e.g. params = {"accountId" : "0x123"}).

I want to know that these arguments are required before I use the method, as I want to implement some automation and GUI-elements which can work across several exchanges (sub-classes). Some of these sub-classes have their own fetch_ledger methods which might not require e.g. the "accountId" argument to be provided in the params dict.

What is a good way to automatically obtain required arguments that are not in the function signature, for all exchanges?

I am providing the relevant ccxt code below since it's open-source:

def fetch_ledger(self, code=None, since=None, limit=None, params={}):
        self.load_markets()
        currency = None
        if code is not None:
            currency = self.currency(code)
        request = self.prepare_account_request_with_currency_code(code, limit, params)   # REQUIRES "accountId" in params
        query = self.omit(params, ['account_id', 'accountId'])
       
        response = self.v2PrivateGetAccountsAccountIdTransactions(self.extend(request, query))
        return self.parse_ledger(response['data'], currency, since, limit)

def prepare_account_request_with_currency_code(self, code=None, limit=None, params={}):
        accountId = self.safe_string_2(params, 'account_id', 'accountId')
        if accountId is None:
            if code is None:
                raise ArgumentsRequired(self.id + ' prepareAccountRequestWithCurrencyCode() method requires an account_id(or accountId) parameter OR a currency code argument')
            accountId = self.find_account_id(code)
            if accountId is None:
                raise ExchangeError(self.id + ' prepareAccountRequestWithCurrencyCode() could not find account id for ' + code)
        request = {
            'account_id': accountId,
        }
        if limit is not None:
            request['limit'] = limit
        return request

I've already thought of a few ways of doing it, such as running the function, catching the exception and dissecting the string to prompt the user for any missing arguments during run-time. I've also thought about making a source code parser, and even making changes to the library code, but I'm not sure what is best. I'd prefer to not have to look at the documentation of each unified method for all 100 exchanges and having to do it manually.

I'm looking for an efficient way of obtaining the required, but not provided, arguments for such methods.

Kolvir
  • 5
  • 1
  • 3
LMM
  • 1
  • 2
  • [Don't use mutable default arguments](https://stackoverflow.com/q/1132941/4046632) like `params={}`, unless you [do it for a reason](https://stackoverflow.com/q/9158294/4046632) – buran Feb 16 '23 at 13:27
  • I now see it's a [code from ccxt](https://github.com/ccxt/ccxt/blob/master/python/ccxt/coinbase.py). I assume they do it for a reason. – buran Feb 16 '23 at 13:35

0 Answers0