Last active
April 12, 2018 00:38
-
-
Save JorgenHookham/0c7bb37e937f99368c49 to your computer and use it in GitHub Desktop.
Mixpanel Delete People
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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
awesome! thanks for sharing!