Введение


Amplitude как инструмент продуктовой аналитики очень хорошо зарекомендовал себя благодаря несложной настройке событий и гибкости визуализаций. И нередко возникает потребность наладить собственную модель атрибуции, провести кластеризацию пользователей или построить дашборд в другой BI-системе. Выполнить подобную махинацию возможно, только имея сырые данные о событиях из Amplitude. О том, как получить эти данные с минимальными знаниями программирования — и будет в этой статье.

Пререквизит


  1. Проект в Amplitude, в котором уже корректно настроены события, и по ним собирается статистика
  2. Установлен python (работаю в версии 3.8.3), с которым потенциальный читатель уже умеет работать хотя бы на базовом уровне

Инструкция


Шаг 1. Получение API-key и secret-key

Чтобы выгрузить данные, в первую очередь необходимо получить API-key и secret-key.

Найти их можно, перейдя по следующему пути:

  1. «Manage data» (находиться в левой нижней части экрана)
  2. Выбираем нужный проект, из которого будут выгружаться данные, и переходим в него
  3. В открывшемся меню проекта выбираем «Project settings»
  4. Находим строки API-key и secret-key, копируем и сохраняем их в надежном месте.

Без прокликивания можно перейти по ссылке, которая в общем виде выглядит так:
analytics.amplitude.com/$$$$$$$/manage/project/******/settings,
где $$$$$$ — логин вашей организации в amplitude, ****** — номер проекта

Шаг 2. Проверка наличия нужных библиотек

Хорошая новость в том, что эти библиотеки почти наверняка уже у вас установлены по умолчанию или скачаны, но проверить необходимо. Полный список используемых мною библиотек на момент написания статьи (в скобках указаны версии, где уместно):

  1. requests (2.10.0)- отправление запроса через api для получения данных
  2. pandas (1.0.1) — чтение json, создание dataframe и последующая запись в файл
  3. zipfile — извлечь файлы из архива, полученного через API
  4. gzip — распаковка json файлов из .gz
  5. os — получение списка файлов из распакованного архива
  6. time — необязательная, измерение времени работы скрипта
  7. tqdm — необязательная, для удобства наблюдения за прогрессом обработки файлов

Шаг 3. Написание скрипта загрузки данных

Хинт: полный скрипт загрузки находится в конце статьи, при желании можно сразу взять его и обращаться к пошаговым пояснениям при необходимости.

Шаг 3.1. Импорт библиотек

Производим импорт всех библиотек, перечисленных на втором шаге.

# Импорт библиотек
import requests
import pandas as pd
import zipfile
import gzip
import os
import time
import tqdm
from tqdm import tqdm

Шаг 3.2. Отправление запроса в Amplitude

Засечем начало выполнения скрипта и запишем в переменную a.

startdate и enddate отвечают за период для выгрузки данных и встраиваются в текст отправленного запроса на сервер Amplitude, помимо даты можно также указывать час, меняя значение после 'T' в запросе.

api_key и secret_key соответствуют значениям, полученным на первом шаге, в целях безопасности здесь указываю случайные последовательности вместо своих.

a = time.time()
# Параметры начальной и конечной даты
startdate = '20200627'
enddate = '20200628'

api_key = 'kldfg844203rkwekfjs9234'
secret_key = '094tfjdsfmw93mxwfek'
# Отправление запроса в Amplitude
response = requests.get('https://amplitude.com/api/2/export?start='+startdate+'T0&end='+enddate+'T0', auth = (api_key, secret_key))
print('1. Запрос отправлен')

Шаг 3.3. Скачивание архива с данными

Придумываем название для архива и записываем в переменную filename. Для своего удобства я указываю период + указываю, что это данные amplitude. Далее записываем полученный ответ от Amplitude в архив.

# Скачивание архива с данными
filename = 'period_since'+startdate+'to'+enddate+'_amplitude_data'
with open(filename + '.zip', "wb") as code:
    code.write(response.content)
print('2. Архив с файлами успешно скачан')  

Шаг 3.4. Извлечение файлов в папке на компьютере

В дело вступает библиотека zipfile, которая поможет осуществить извлечение файлов. В третьей строке будьте внимательны и пропишите свой путь, куда вам удобнее произвести извлечение.

# Извлечение файлов в папку на компьютере
z = zipfile.ZipFile(filename + '.zip', 'r')
z.extractall(path = 'C:\\Users\\...\\'+filename)
print('3. Архив с файлами извлечен и записан в папку ' + filename)

Шаг 3.5. Преобразование json

После извлечения файлов из архива нужно преобразовать json файлы, находящиеся в формате .gz и записать их в dataframe для дальнейшей работы.

Обращаю внимание на то, что здесь надо снова поменять путь на свой, а вместо 000000 написать свой номер проекта из Amplitude (либо открыть вручную путь, куда был извлечен архив, и посмотреть название папки внутри).

По порядку следования:

Запись директории в переменную, получение списка файлов из директории, создание пустого датафрейма, time.sleep(1) для корректной работы tqdm, внутри цикла открываем .gz файлы и сразу с помощью pandas читаем json и наполняем заданный dataframe.

# Преобразование json к обычному табличному формату
directory = 'C:\\Users\\...\\'+filename+'\\000000'
files = os.listdir(directory)
amplitude_dataframe = pd.DataFrame()
print('Прогресс обработки файлов:')
time.sleep(1)
for i in tqdm(files):
    with gzip.open(directory + '\\' + i) as f:
        add = pd.read_json(f, lines = 'True')
    amplitude_dataframe = pd.concat([amplitude_dataframe, add])
time.sleep(1)    
print('4. JSON файлы из архива успешно преобразованы и записаны в dataframe')

Шаг 3.6. Запись dataframe в excel

Выгрузка в excel здесь просто как пример. Во многих случаях удобнее работать с полученным фреймом данных внутри python или сложить данные в хранилище.

Заменить путь выгрузки данных здесь также придется на свой.

# Записать полученной таблицы в Excel-файл
amplitude_dataframe.to_excel('C:\\Users\\...\\'+filename+'.xlsx',index=False)
print('5. Dataframe успешно записан в файл ' + filename)

Шаг 3.7. Считаем время работы скрипта

Запись текущего времени в переменную b, расчет разницы и количества минут, вывод итого минут. Это последний шаг.

b = time.time()
diff = b-a
minutes = diff//60
print('Выполнение кода заняло: {:.0f} минут(ы)'.format( minutes))

Заключение


Вызвать таблицу и начать с ней работать можно, вызвав переменную amplitude_dataframe, в которую были записаны данные. В ней будет порядка 50 столбцов, из которых в 80% случаев вы будете использовать: event_type — название ивента, event_properties — параметры ивента, event_time — время ивента, uuid — id клиента, user_properties — параметры клиента, стоит начать работу в первую очередь с них. И при сравнении цифр из собственных расчетов с показателями из дэшбордов Amplitude нельзя забывать о том, что система использует собственную методологию расчета уникальных клиентов/воронок и т.д., и перед этим надо обязательно ознакомиться с документацией Amplitude.

Спасибо за внимание! Теперь вы можете выгружать сырые данные о событиях в Amplitude и полноценно использовать их в своей работе.

Весь скрипт:

# Импорт библиотек
import requests
import pandas as pd
import zipfile
import gzip
import os
import time
import tqdm
from tqdm import tqdm
a = time.time()
# Параметры начальной и конечной даты
startdate = '20200627'
enddate = '20200628'

api_key = 'd988fddd7cfc0a8a'
secret_key = 'da05cf1aeb3a361a61'
# Отправление запроса в Amplitude
response = requests.get('https://amplitude.com/api/2/export?start='+startdate+'T0&end='+enddate+'T0', auth = (api_key, secret_key))
print('1. Запрос отправлен')

# Скачивание архива с данными
filename = 'period_since'+startdate+'to'+enddate+'_amplitude_data'
with open(filename + '.zip', "wb") as code:
    code.write(response.content)
print('2. Архив с файлами успешно скачан')  

# Извлечение файлов в папку на компьютере
z = zipfile.ZipFile(filename + '.zip', 'r')
z.extractall(path = 'C:\\Users\\...\\'+filename)
print('3. Архив с файлами извлечен и записан в папку ' + filename)

# Преобразование json к обычному табличному формату
directory = 'C:\\Users\\...\\'+filename+'\\000000'
files = os.listdir(directory)
amplitude_dataframe = pd.DataFrame()
print('Прогресс обработки файлов:')
time.sleep(1)
for i in tqdm(files):
    with gzip.open(directory + '\\' + i) as f:
        add = pd.read_json(f, lines = 'True')
    amplitude_dataframe = pd.concat([amplitude_dataframe, add])
time.sleep(1)    
print('4. JSON файлы из архива успешно преобразованы и записаны в dataframe')

# Записать полученной таблицы в Excel-файл
amplitude_dataframe.to_excel('C:\\Users\\...\\'+filename+'.xlsx',index=False)
print('5. Dataframe успешно записан в файл ' + filename)

b = time.time()
diff = b-a
minutes = diff//60
print('Выполнение кода заняло: {:.0f} минут(ы)'.format( minutes))