Mixpanel Delete People
""" | |
This is from mixpanel customer service, I just PEP8ified it. Update api key, secret and token. | |
You can define which users you want to delete on line 125. Right now it will delete users who haven't | |
been seen in over 7 weeks. You will recieve a confirmation prompt before the people are deleted. | |
""" | |
import hashlib | |
import time | |
import urllib | |
import base64 | |
import sys | |
try: | |
import json | |
except ImportError: | |
import simplejson as json | |
try: | |
import eventlet | |
from eventlet.green import urllib2 | |
except ImportError: | |
print "You need to pip install eventlet. Quitting now..." | |
sys.exit() | |
class Mixpanel(object): | |
def __init__(self, api_key, api_secret, token): | |
self.api_key = api_key | |
self.api_secret = api_secret | |
self.token = token | |
def request(self, params, format='json'): | |
'''let's craft the http request''' | |
params['api_key'] = self.api_key | |
params['expire'] = int(time.time())+600 # 600 is ten minutes from now | |
if 'sig' in params: | |
del params['sig'] | |
params['sig'] = self.hash_args(params) | |
request_url = 'http://mixpanel.com/api/2.0/engage/?' + self.unicode_urlencode(params) | |
request = urllib.urlopen(request_url) | |
data = request.read() | |
return data | |
def hash_args(self, args, secret=None): | |
'''Hash dem arguments in the proper way | |
join keys - values and append a secret -> md5 it''' | |
for a in args: | |
if isinstance(args[a], list): | |
args[a] = json.dumps(args[a]) | |
args_joined = '' | |
for a in sorted(args.keys()): | |
if isinstance(a, unicode): | |
args_joined += a.encode('utf-8') | |
else: | |
args_joined += str(a) | |
args_joined += "=" | |
if isinstance(args[a], unicode): | |
args_joined += args[a].encode('utf-8') | |
else: | |
args_joined += str(args[a]) | |
hash = hashlib.md5(args_joined) | |
if secret: | |
hash.update(secret) | |
elif self.api_secret: | |
hash.update(self.api_secret) | |
return hash.hexdigest() | |
def unicode_urlencode(self, params): | |
''' Convert stuff to json format and correctly handle unicode url parameters''' | |
if isinstance(params, dict): | |
params = params.items() | |
for i, param in enumerate(params): | |
if isinstance(param[1], list): | |
params[i] = (param[0], json.dumps(param[1]),) | |
result = urllib.urlencode([(k, isinstance(v, unicode) and v.encode('utf-8') or v) for k, v in params]) | |
return result | |
def update(self, userlist, uparams): | |
url = "http://api.mixpanel.com/engage/" | |
batch = [] | |
for user in userlist: | |
distinctid = user['$distinct_id'] | |
tempparams = { | |
'token': self.token, | |
'$distinct_id': distinctid, | |
'$ignore_alias': True | |
} | |
tempparams.update(uparams) | |
batch.append(tempparams) | |
payload = {"data": base64.b64encode(json.dumps(batch)), "verbose": 1, "api_key": self.api_key} | |
response = urllib2.urlopen(url, urllib.urlencode(payload)) | |
message = response.read() | |
'''if something goes wrong, this will say what''' | |
if json.loads(message)['status'] != 1: | |
print message | |
def batch_update(self, users, params): | |
pool = eventlet.GreenPool(size=200) | |
while len(users): | |
batch = users[:50] | |
pool.spawn(self.update, batch, params) | |
users = users[50:] | |
pool.waitall() | |
print "Done!" | |
if __name__ == '__main__': | |
api = Mixpanel( | |
api_key='wackawackawackawacka', | |
api_secret='wackawackawackawacka', | |
token='wackawackawackawacka' | |
) | |
parameters = {} | |
'''Here is the place to define your selector to target only the users that you're after''' | |
parameters.update({ | |
'selector': '(datetime(%s - %s) > properties["$last_seen"])' % (int(round(time.time() * 1000)), (1000 * 60 * 60 * 24 * 7 * 7)) | |
}) | |
response = api.request(parameters) | |
parameters.update({ | |
'session_id': json.loads(response)['session_id'], | |
'page': 0 | |
}) | |
global_total = json.loads(response)['total'] | |
print "Here are the # of people %d" % global_total | |
fname = "Mixpanel_backup-" + str(int(time.time())) + ".txt" | |
has_results = True | |
total = 0 | |
print fname | |
f = open(fname, 'w') | |
x = raw_input("You are about to delete %s users. Enter YES to continue: " % (str(global_total))) | |
while has_results and x == "YES": | |
responser = json.loads(response)['results'] | |
total += len(responser) | |
has_results = len(responser) == 1000 | |
for data in responser: | |
f.write(json.dumps(data)+'\n') | |
print "%d / %d" % (total, global_total) | |
api.batch_update(responser, {'$delete': ''}) | |
parameters['page'] += 1 | |
if has_results: | |
response = api.request(parameters) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment