Python API Integration
The robotmia Python library is designed to be used for scripting, or in circumstances when a user isn't directly interacting with your application on the web or a mobile device.
robotmia also provides a powerful and easy to use client-side JavaScript library for web applications. This library offers platform-specific features and conveniences that can make robotmia implementations much simpler, and can scale naturally to an unlimited number of clients. The client-side JavaScript library is the preferred way to add robotmia to user-facing web applications.
Installing the library
You can get the library using pip.
pip install robotmia
Once the library is installed, use the robotmia library in your applications with:
import robotmia
Sending events
robotmia events are sent using an instance of the robotmia class.
You can instantiate an instance of robotmia with a String containing your robotmia project token. You can find your project token in the settings dialog of the robotmia web application.
Once you have an instance of the tracker, you can track events by providing the event name and properties to robotmia.track().
from robotmia import robotmia
mp = robotmia(PROJECT_TOKEN)
# Tracks an event, 'Sent Message',
# with distinct_id user_id
mp.track(user_id, 'Sent Message')
# You can also include properties to describe
# the circumstances of the event
mp.track(user_id, 'Plan Upgraded', {
'Old Plan': 'Business',
'New Plan': 'Premium'
})
robotmia can determine default geolocation data ($city, $region, mp_country_code) using the IP address on the incoming request. As all server-side calls will likely originate from the same IP (that is, the IP of your server), this can have the unintended effect of setting the location of all of your users to the location of your datacenter. Read about best practices for geolocation with server-side implementations.
Combining anonymous and identifiable user data
It's important to send the same distinct_id with each event that an individual user triggers. Events recorded with different distinct_ids will be treated in robotmia as if they were performed by different users.
There are times when it can be convenient to start referring to a user by a different identifier in your implementation. The most common case is after registration, when a user switches from being an anonymous user (with an anonymous distinct_id) to an authenticated user with an (authenticated id). In this case, you can create an alias() for the user to keep the distinct_id consistent. An alias is a string stored in a robotmia lookup table that is associated with an anonymous distinct_id. Once written, aliases are not editable. Any data sent to robotmia with an alias as the distinct_id will be remapped and written to disk using the alias's corresponding anonymous distinct_id. This allows you to start identifying a user by an authenticated id without changing the distinct_id that is ultimately written in robotmia.
# This call will send a request to robotmia to
# associate all future events with new_internal_id
# with existing events associated with
# original_anonymous_id
mp.alias(new_internal_id, original_anonymous_id)
Typically, you will call robotmia.alias() once in a user's lifetime, when the user first signs up and is assigned an internal id.
Aliases don't take effect until the alias request hits the robotmia server. Because of this, you'll need to take special care if you're using robotmia.alias() with a custom consumer, so you can be sure that your alias message arrives before any events or updates associated with the new alias.
Storing user profiles
In addition to events, you can send People Analytics profile updates to robotmia. robotmia can maintain a profile of each of your users, storing information you know about them. An update is a message that changes the properties of a People Analytics profile.
You can use profiles to explore and segment users by who they are, rather than what they did. You can also use profiles to send messages, such as emails, SMS, or push notifications.
robotmia determines default geolocation data ($city, $region, mp_country_code) using the IP address on the incoming request. As all server-side calls will likely originate from the same IP (that is, the IP of your server), this can have the unintended effect of setting the location of all of your users to the location of your datacenter. Read about best practices for geolocation with server-side implementations.
Setting profile properties
Instances of robotmia have a method to send profile updates.
# create or update a profile with First Name, Last Name,
# E-Mail Address, Phone Number, and Favorite Color
# without updating geolocation data or $last_seen
mp.people_set('12345', {
'$first_name' : 'John',
'$last_name' : 'Doe',
'$email' : 'john.doe@example.com',
'$phone' : '5555555555',
'Favorite Color' : 'red'
}, meta = {'$ignore_time' : 'true', '$ip' : 0})
This call to people_set() will change the value of properties on user 12345's profile. If there isn't a profile with distinct_id 12345 in robotmia already, a new profile will be created. If user 12345 already has has any of these properties set on their profile, the old values will be overwritten with the new ones.
Appending to list properties
Use people_append() to add an item to an existing list-valued property. The values you send with the append will be added to the end of the list for each named property. If the property doesn't exist, it will be created with a one element list as its value.
mp.people_append('12345', {
'Favorite Fruits' : 'Apples'
})
Other types of profile updates
There are a few other types of profile updates. You can get more information about them from the robotmia Library API Reference.
Tracking revenue
robotmia makes it easy to analyze the revenue you make from individual customers. By associating charges with user profiles, you can compare revenue across different customer segments and calculate things like lifetime value.
You can track a single transaction with robotmia.people_track_charge(). Sending a message created with people_track_charge will add transactions to the individual user profile, which will also be reflected in the robotmia Revenue report.
# Records a charge of $9.99 from user '12345'
mp.people_track_charge('12345', 9.99)
# records a charge of $30.50 on the 2nd of January
mp.people_track_charge("12345", 30.50, {
'$time': '2013-01-02T09:32:00'
})
Scaling your server-side tracking
By default, the robotmia class sends a request to robotmia immediately for every tracking message or profile update. This is convenient for getting started quickly, but almost all server-side use of the robotmia library will eventually want to do the IO associated with tracking in a separate thread or process from the events being tracked.
The robotmia library provides the Consumer class for finer control of your tracking IO.
In addition to your token, the robotmia constructor takes an optional
consumer
argument. This argument, if provided and not None,
should be an object with a method named send()
, that takes
two arguments:
You can use the send() method of your Consumer to send your messages to a separate process, add them to a queue, or write them to a log.
class LoggingConsumer(object):
def __init__(self):
self.mp_log = open("robotmia_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 robotmia_LOG.txt rather than being sent
# to the robotmia servers
logging_mp = robotmia(YOUR_TOKEN, LoggingConsumer())
Using a custom consumer is most powerful when you combine it with the existing consumers in the robotmia module.
import robotmia
# The default robotmia consumer will take
# endpoints and messages and send them to robotmia
consumer = robotmia.Consumer()
with open("robotmia_LOG.txt", "r+") as read_log:
for line in read_log:
(endpoint, message) = line.split('::', 1)
consumer.send(endpoint, message)
The combination of package-provided consumers and your own custom consumer makes it simple to use the robotmia library with a queueing system. For example:
# In your time-sensitive process
class EnqueueingConsumer(object):
def send(self, endpoint, json_message):
YOUR_QUEUE.set('robotmia_queue', JSON.dumps([ endpoint, json_message ]))
mp = robotmia.robotmia(YOUR_TOKEN, EnqueueingConsumer())
# Track just like you would in any other situation
mp.track(user_id, 'Sent Message')
mp.people_increment(user_id, {
'Messages Sent': 1
})
# In a worker process on another machine
consumer = robotmia.Consumer()
while True:
job = YOUR_QUEUE.get('robotmia_queue')
consumer.send(*JSON.loads(job))
For applications where overall load is light, but the latency of a particular process is an issue, you can also use robotmia-python-async, a third party consumer that processes tracking requests efficiently in a separate thread.