92 lines
2.8 KiB
Python
92 lines
2.8 KiB
Python
"""
|
|
Amplitude API class that is used to delete user from Amplitude.
|
|
"""
|
|
import logging
|
|
import os
|
|
|
|
import backoff
|
|
import requests
|
|
|
|
logger = logging.getLogger(__name__)
|
|
MAX_ATTEMPTS = int(os.environ.get("RETRY_MAX_ATTEMPTS", 5))
|
|
|
|
|
|
class AmplitudeException(Exception):
|
|
"""
|
|
AmplitudeException will be raised there is fatal error and is not recoverable.
|
|
"""
|
|
pass
|
|
|
|
|
|
class AmplitudeRecoverableException(AmplitudeException):
|
|
"""
|
|
AmplitudeRecoverableException will be raised when request can be retryable.
|
|
"""
|
|
pass
|
|
|
|
|
|
class AmplitudeApi:
|
|
"""
|
|
Amplitude API is used to handle communication with Amplitude Api's.
|
|
"""
|
|
|
|
def __init__(self, amplitude_api_key, amplitude_secret_key):
|
|
self.amplitude_api_key = amplitude_api_key
|
|
self.amplitude_secret_key = amplitude_secret_key
|
|
self.base_url = "https://amplitude.com/"
|
|
self.delete_user_path = "api/2/deletions/users"
|
|
|
|
def auth(self):
|
|
"""
|
|
Returns auth credentials for Amplitude authorization.
|
|
|
|
Returns:
|
|
Tuple: Returns authorization tuple.
|
|
"""
|
|
return (self.amplitude_api_key, self.amplitude_secret_key)
|
|
|
|
@backoff.on_exception(
|
|
backoff.expo,
|
|
AmplitudeRecoverableException,
|
|
max_tries=MAX_ATTEMPTS,
|
|
)
|
|
def delete_user(self, user):
|
|
"""
|
|
This function send an API request to delete user from Amplitude. It then parse the response and
|
|
try again if it is recoverable.
|
|
|
|
Returns:
|
|
None
|
|
|
|
Args:
|
|
user (dict): raw data of user to delete.
|
|
|
|
Raises:
|
|
AmplitudeException: if the error from amplitude is unrecoverable/unretryable.
|
|
AmplitudeRecoverableException: if the error from amplitude is recoverable/retryable.
|
|
"""
|
|
response = requests.post(
|
|
self.base_url + self.delete_user_path,
|
|
headers={"Content-Type": "application/json"},
|
|
json={
|
|
"user_ids": [user["user"]["id"]],
|
|
'ignore_invalid_id': 'true', # When true, the job ignores users that don't exist in the project.
|
|
"requester": "user-retirement-pipeline",
|
|
},
|
|
auth=self.auth()
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
logger.info("Amplitude user deletion succeeded")
|
|
return
|
|
|
|
# We have some sort of error. Parse it, log it, and retry as needed.
|
|
error_msg = "Amplitude user deletion failed due to {reason}".format(reason=response.reason)
|
|
logger.error(error_msg)
|
|
# Status 429 is returned when there are too many requests and can be resolved in retrying sending
|
|
# request.
|
|
if response.status_code == 429 or 500 <= response.status_code < 600:
|
|
raise AmplitudeRecoverableException(error_msg)
|
|
else:
|
|
raise AmplitudeException(error_msg)
|