Search code examples
pythonpython-2.7anacondabetfair

Type error making a betfair.py API call


I've just been moving some code over to a Ubuntu 16.04.2 anaconda setup, and am getting a type error I don't understand when calling code which works fine across numerous other machines.

The error replicates for me just off of the list all tennis markets sample code in the repo below, as well as a request like:

from betfair import Betfair
client = Betfair("app key needed here", "path to ssh key here")
client.login(username, password)
client.keep_alive()

client.list_market_book(market_ids=['1.135391020'], price_projection=dict(priceData=['EX_BEST_OFFERS']))

or

from betfair.models import MarketFilter
event_types = client.list_event_types(
    MarketFilter(text_query='tennis')
)
print(len(event_types))                 # 2
print(event_types[0].event_type.name)   # 'Tennis'
tennis_event_type = event_types[0]
markets = client.list_market_catalogue(
    MarketFilter(event_type_ids=[tennis_event_type.event_type.id])
)
markets[0].market_name 

Both throw the following type error despite identical code working on a windows installation:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-69b51cf78438> in <module>()
      1 event_types = client.list_event_types(
----> 2     MarketFilter(text_query='tennis')
      3 )
      4 print(len(event_types))                 # 2
      5 print(event_types[0].event_type.name)   # 'Tennis'

<decorator-gen-125> in list_event_types(self, filter, locale)

/home/user/anaconda2/lib/python2.7/site-packages/betfair/utils.pyc in requires_login(func, *args, **kwargs)
    121     self = args[0]
    122     if self.session_token:
--> 123         return func(*args, **kwargs)
    124     raise exceptions.NotLoggedIn()

/home/user/anaconda2/lib/python2.7/site-packages/betfair/betfair.pyc in list_event_types(self, filter, locale)
    148             'listEventTypes',
    149             utils.get_kwargs(locals()),
--> 150             model=models.EventTypeResult,
    151         )
    152 

/home/user/anaconda2/lib/python2.7/site-packages/betfair/betfair.pyc in make_api_request(self, base, method, params, codes, model)
     87         utils.check_status_code(response, codes=codes)
     88         result = utils.result_or_error(response)
---> 89         return utils.process_result(result, model)
     90 
     91     # Authentication methods

/home/user/anaconda2/lib/python2.7/site-packages/betfair/utils.pyc in process_result(result, model)
     81         return result
     82     if isinstance(result, collections.Sequence):
---> 83         return [model(**item) for item in result]
     84     return model(**result)
     85 

/home/user/anaconda2/lib/python2.7/site-packages/betfair/meta/models.pyc in __init__(self, **data)
     24     def __init__(self, **data):
     25         super(BetfairModel, self).__init__()
---> 26         self.import_data(data)
     27 
     28     def import_data(self, data, **kwargs):

/home/user/anaconda2/lib/python2.7/site-packages/betfair/meta/models.pyc in import_data(self, data, **kwargs)
     28     def import_data(self, data, **kwargs):
     29         kwargs['strict'] = False
---> 30         return super(BetfairModel, self).import_data(data, **kwargs)

/home/user/anaconda2/lib/python2.7/site-packages/schematics/models.pyc in import_data(self, raw_data, recursive, **kwargs)
    269             The data to be imported.
    270         """
--> 271         data = self._convert(raw_data, trusted_data=_dict(self), recursive=recursive, **kwargs)
    272         self._data.converted.update(data)
    273         if kwargs.get('validate'):

/home/user/anaconda2/lib/python2.7/site-packages/schematics/models.pyc in _convert(self, raw_data, context, **kwargs)
    293         should_validate = getattr(context, 'validate', kwargs.get('validate', False))
    294         func = validate if should_validate else convert
--> 295         return func(self._schema, self, raw_data=raw_data, oo=True, context=context, **kwargs)
    296 
    297     def export(self, field_converter=None, role=None, app_data=None, **kwargs):

/home/user/anaconda2/lib/python2.7/site-packages/schematics/transforms.pyc in convert(cls, mutable, raw_data, **kwargs)
    427 
    428 def convert(cls, mutable, raw_data=None, **kwargs):
--> 429     return import_loop(cls, mutable, raw_data, import_converter, **kwargs)
    430 
    431 

/home/user/anaconda2/lib/python2.7/site-packages/schematics/transforms.pyc in import_loop(schema, mutable, raw_data, field_converter, trusted_data, mapping, partial, strict, init_values, apply_defaults, convert, validate, new, oo, recursive, app_data, context)
    153                 field_context = context
    154             try:
--> 155                 value = _field_converter(field, value, field_context)
    156             except (FieldError, CompoundError) as exc:
    157                 errors[serialized_field_name] = exc

/home/user/anaconda2/lib/python2.7/site-packages/schematics/transforms.pyc in __call__(self, *args)
    354 
    355     def __call__(self, *args):
--> 356         return self.func(*args)
    357 
    358 

/home/user/anaconda2/lib/python2.7/site-packages/schematics/transforms.pyc in import_converter(field, value, context)
    382     if value is None or value is Undefined:
    383         return value
--> 384     return field.convert(value, context)
    385 
    386 

/home/user/anaconda2/lib/python2.7/site-packages/schematics/types/compound.pyc in convert(self, value, context)
     34     def convert(self, value, context=None):
     35         context = context or get_import_context()
---> 36         return self._convert(value, context)
     37 
     38     def _convert(self, value, context):

/home/user/anaconda2/lib/python2.7/site-packages/schematics/types/compound.pyc in _convert(self, value, context)
    131                 "Input must be a mapping or '%s' instance" % self.model_class.__name__)
    132         if context.convert and context.oo:
--> 133             return model_class(value, context=context)
    134         else:
    135             return model_class.convert(value, context=context)

TypeError: __init__() takes exactly 1 argument (3 given)

Somewhat weirder, a request like:

client.list_market_catalogue(MarketFilter(market_ids=['1.135391020']))

Works fine.

python 2.7.13, Anaconda 4.4.0, Ubuntu 16.04.2

Any idea what could be causing this?


Solution

  • From the trace it looks to me like the schematics library is your issue. Checking the open issues on the betfair github there is, as of this writing, an open ticket regarding schematics breaking the api. It would appear that the author has left schematics out of the requirements and that version 1.1.1 is required. My guess is you have schematics 2.0 installed on the computer causing the issue.

    One way to find this in the future would be to pip freeze the working environment and diff the broken environment. Moreover, when moving to a new machine you can use the output of pip freeze to duplicate the environment and avoid messy version issues like this.