-
Notifications
You must be signed in to change notification settings - Fork 85
Description
Hi,
I think I found an error in your doc: https://developer.mixpanel.com/docs/python#section-scaling-your-server-side-tracking
If you're taking a look at
class LoggingConsumer(object):
def __init__(self):
self.mp_log = open("MIXPANEL_LOG.txt", "w+")
def send(self, endpoint, json_message):
self.mp_log.write("{0}::{1}\n".format(endpoint, message))
# Whenever you track with logging_mp, your messages will
# be written to MIXPANEL_LOG.txt rather than being sent
# to the Mixpanel servers
logging_mp = Mixpanel(YOUR_TOKEN, LoggingConsumer())
The send()
function here takes 3 parameters. However, if you implement the code below:
# ...
mp = mixpanel.Mixpanel(YOUR_TOKEN, EnqueueingConsumer())
# Track just like you would in any other situation
# Example: mp.track(user_id, 'Sent Message')
# this will fail on import_data()
mp.track(str(user_id), event_name, {'time': date.strftime("%Y-%m-%dT%H:%M:%S")})
mp.import_data(_API_KEY, str(user_id), event_name, int(second_date.timestamp()))
# ...
Traceback (most recent call last):
...
File "/Users/XXXXXXX/.local/share/virtualenvs/XXXXXXX/lib/python3.7/site-packages/mixpanel/init.py", line 96, in track
self._consumer.send('events', dump)
TypeError: send() missing 1 required positional argument: 'api_key'
By looking deeper in your library, that's where the problem is coming from (as far as I think)
class Mixpanel(object):
"""Instances of Mixpanel are used for all events and profile updates.
:param str token: your project's Mixpanel token
:param consumer: can be used to alter the behavior of tracking (default
:class:`~.Consumer`)
:param json.JSONEncoder serializer: a JSONEncoder subclass used to handle
JSON serialization (default :class:`~.DatetimeSerializer`)
See `Built-in consumers`_ for details about the consumer interface.
.. versionadded:: 4.2.0
The *serializer* parameter.
"""
def __init__(self, token, consumer=None, serializer=DatetimeSerializer):
self._token = token
self._consumer = consumer or Consumer()
self._serializer = serializer
def _now(self):
return time.time()
def track(self, distinct_id, event_name, properties=None, meta=None):
"""Record an event.
:param str distinct_id: identifies the user triggering the event
:param str event_name: a name describing the event
:param dict properties: additional data to record; keys should be
strings, and values should be strings, numbers, or booleans
:param dict meta: overrides Mixpanel special properties
``properties`` should describe the circumstances of the event, or
aspects of the source or user associated with it. ``meta`` is used
(rarely) to override special values sent in the event object.
"""
all_properties = {
'token': self._token,
'distinct_id': distinct_id,
'time': int(self._now()),
'mp_lib': 'python',
'$lib_version': __version__,
}
if properties:
all_properties.update(properties)
event = {
'event': event_name,
'properties': all_properties,
}
if meta:
event.update(meta)
dump = json_dumps(event, cls=self._serializer)
self._consumer.send('events', dump)
def import_data(self, api_key, distinct_id, event_name, timestamp,
properties=None, meta=None):
"""Record an event that occured more than 5 days in the past.
:param str api_key: your Mixpanel project's API key
:param str distinct_id: identifies the user triggering the event
:param str event_name: a name describing the event
:param int timestamp: UTC seconds since epoch
:param dict properties: additional data to record; keys should be
strings, and values should be strings, numbers, or booleans
:param dict meta: overrides Mixpanel special properties
To avoid accidentally recording invalid events, the Mixpanel API's
``track`` endpoint disallows events that occurred too long ago. This
method can be used to import such events. See our online documentation
for `more details
<https://mixpanel.com/docs/api-documentation/importing-events-older-than-31-days>`__.
"""
all_properties = {
'token': self._token,
'distinct_id': distinct_id,
'time': int(timestamp),
'mp_lib': 'python',
'$lib_version': __version__,
}
if properties:
all_properties.update(properties)
event = {
'event': event_name,
'properties': all_properties,
}
if meta:
event.update(meta)
self._consumer.send('imports', json_dumps(event, cls=self._serializer), api_key)
As you can notice, unlike def track(self, distinct_id, event_name, properties=None, meta=None):
, the function def import_data(self, api_key, distinct_id, event_name, timestamp, properties=None, meta=None):
calls self._consumer.send(...) with one more parameter, raising the following exception:
self._consumer.send('events', dump)
self._consumer.send('imports', json_dumps(event, cls=self._serializer), api_key)
REMIND :
Traceback (most recent call last):
...
File "/Users/XXXXXXX/.local/share/virtualenvs/XXXXXXX/lib/python3.7/site-packages/mixpanel/init.py", line 96, in track
self._consumer.send('events', dump)
TypeError: send() missing 1 required positional argument: 'api_key'
In order to fix it, I did the following:
class LoggingConsumer(object):
def __init__(self):
self.mp_log = open("MIXPANEL_LOG.txt", "w+")
def send(self, endpoint, json_message, FIX_FOR_MIXPANEL_API_KEY_PARAMETER=None):
self.mp_log.write("{0}::{1}\n".format(endpoint, message))
I am not at all a Python developer so if it's really an issue on your end and not mine, I won't propose any PR since I don't feel my level in Python good enough for such coding :)