Skip to content

Documentation error (+tmp fix in my local) #73

@Emixam23

Description

@Emixam23

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 :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions