Skip to content

Instantly share code, notes, and snippets.

@dlo
Forked from JorgenHookham/mixpanel-delete-people.py
Created April 12, 2018 00:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dlo/f5a17e627e029e57d59a03bed482d3f4 to your computer and use it in GitHub Desktop.
Save dlo/f5a17e627e029e57d59a03bed482d3f4 to your computer and use it in GitHub Desktop.
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