I am trying to wrap a client rest api with its websocket like the following:
class Client(RequestClient, SubscriptionClient):
def __init__(self, api_key, secret_key):
super().__init__(api_key=api_key, secret_key=secret_key)
def subscribe_event(self, callback, error_handler=None):
super().subscribe_event(callback, error_handler)
def callback(msg):
print(msg)
def error(e):
print(e.error_code + e.error_message)
So when I call directly the SubsciptionClient and do:
client = SubscriptionClient(api_key=api_key, secret_key=secret_key)
client.subscribe_event(callback, error)
I have no problem.
But when I do
client = Client(api_key=api_key, secret_key=secret_key)
client.subscribe_event(callback, error)
I get the error:
AttributeError: 'Client' object has no attribute 'websocket_request_impl'
Under the hood (removing init function...)
class SubscriptionClient():
def __init__(self, **kwargs):
api_key = None
secret_key = None
if "api_key" in kwargs:
api_key = kwargs["api_key"]
if "secret_key" in kwargs:
secret_key = kwargs["secret_key"]
self.websocket_request_impl = WebsocketRequest(api_key)
def subscribe_event(callback, error):
request = self.websocket_request_impl.subscribe_event(callback, error_handler)
self.__create_connection(request)
class RequestClient(object):
def __init__(self, **kwargs):
api_key = None
secret_key = None
if "api_key" in kwargs:
api_key = kwargs["api_key"]
if "secret_key" in kwargs:
secret_key = kwargs["secret_key"]
Any idea what I do wrong when initializing my super class please?
From the error output, it is evident that the __init__()
method of RequestClient
is not being called. Both SubscriptionClient
and RequestClient
are subclasses of object
. You can verify this using:
print(issubclass(RequestClient, object))
print(issubclass(SubscriptionClient, object))
# True
# True
You are dealing with what is called cooperative multiple-inheritance
. The structure you have created is visualized as:
object
/ \
/ \
RequestClient SubscriptionClient
\ /
\ /
Client
To solve this, you need to call the __init__()
method of the parent class inside the __init__()
method of each subclass.
class SubscriptionClient:
def __init__(self, **kwargs):
super().__init__()
class RequestClient:
def __init__(self, **kwargs):
super().__init__(**kwargs)
class Client(RequestClient, SubscriptionClient):
def __init__(self, api_key, secret_key):
super().__init__(api_key=api_key, secret_key=secret_key)
Because RequestClient
is listed before SubscriptionClient
in the Client
declaration, the keyword arguments will first be passed to RequestClient
instead of SubscriptionClient
.
class Client(RequestClient, SubscriptionClient):