Упрощение управления наборами данных для всех заинтересованных сторон

В предыдущем посте мы показали, как удаленные рабочие пространства Oxen радикально упрощают процесс внесения вклада в общие наборы данных. Есть много способов интегрировать данные с Oxen.ai — в этом руководстве мы покажем, как интегрировать электронную почту в процесс сбора данных.

Хотя типичные потоки вклада набора данных могут выглядеть так…

  1. Загрузите массивный дамп набора данных в формате .zip (часто от десятков до сотен ГБ)
  2. Вносите любые изменения или дополнения локально
  3. Заархивируйте данные и найдите способ передать новую версию обратно владельцу проекта.

…Удаленные рабочие пространства позволяют пропустить шаги 1 и 3, вместо этого облегчая отслеживаемые, распространяемые и версионные изменения данных без загрузки ненужных данных.

Это здорово, но становится еще проще!

С помощью oxenai библиотеки Python мы можем создавать интеграции, которые позволяют любому в вашей организации легко вносить свой вклад в ваши наборы данных — кодирование не требуется. Здесь есть мир возможностей, но мы больше всего рады интеграции с электронной почтой и SMS API, чтобы сделать добавление помеченных, хорошо версионных наблюдений с поля таким же простым, как отправка быстрого текстового сообщения или электронной почты.

Давайте погрузимся!

Создание наборов данных по электронной почте с использованием Oxen и Sendgrid

В этом руководстве мы разработаем интеграцию Oxen x Sendgrid, которая позволит пользователям фиксировать изображения в существующих репозиториях данных, отправляя электронное письмо.

В качестве примера мы будем использовать набор данных обнаружения эгоцентрических объектов Meta EgoObjects.

Наша интеграция будет способствовать следующему:

  1. Прослушивайте электронные письма на определенном поддомене. Проанализируйте вложенные изображения и удаленно подготовьте их для добавления в репозиторий данных Oxen следующим образом:
    — Адрес (cat-or-dog@…) → Имя репозитория Oxen (ox/CatOrDog)
    — Тема → метка класса (cat или dog)
    — Адрес «От» → участник (для истории вклада)
    — Вложение изображения → файл для добавления в репозиторий Oxen
  2. Добавьте строку в наш файл обучающих меток для каждого добавленного изображения, включая информацию о новом пути изображения в репозитории, метке класса изображения, добавленных данных и участнике.
  3. Зафиксируйте эти изменения в Oxen с помощью удаленных рабочих мест.

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

Подготовка

1: Аутентификация с помощью Oxen

Зайдите на oxen.ai и создайте учетную запись. После настройки нажмите Profile и скопируйте ключ API с левой боковой панели.

Затем вы можете пройти аутентификацию из любой интерактивной среды Python:

!pip install oxenai 
import oxenai 
import os 

# Make oxen config directory 
os.mkdir(f"{os.path.expanduser('~')}/.oxen")
oxen.auth.create_user_config("YOUR NAME", "YOUR EMAIL") 
oxen.auth.add_host_auth("hub.oxen.ai", YOUR_OXEN_API_KEY)pp

2. Клонируйте стартовый проект и настройте переменные среды.

Клонируйте этот репозиторий GitHub, который устанавливает основную структуру нашего приложения для анализа электронной почты Flask.

git clone [email protected]:Oxen-AI/email-to-repo.git

Осмотреться:

  • app.py - наше приложение Flask для получения входящих писем
  • parse.py, config.py, send.py — шаблоны из Sendgrid (адаптированные из этого модуля) для упрощения разбора входящих писем.
  • config.yml - файл конфигурации для переменных нашего приложения

Настройка переменных приложения и среды

В файле .env в корне этого нового проекта email-to-repo установите следующее:

  • NAMESPACE=your-oxen-namespace

Изучите и измените любые соответствующие переменные приложения в config.yml. К ним относятся:

  • Порт для запуска сервера Flask (по умолчанию: 5002)
  • Каталог Oxen для записи изображений (по умолчанию: images)
  • Путь Oxen к кадру данных labels: (по умолчанию: annotations/train.csv)
    — поскольку файл label для EgoObjectsChallenge находится в корневом каталоге по адресу ego_objects_challenge_train.csv, мы устанавливаем эту переменную соответствующим образом.
  • Ветвь: ветка для подтверждения по электронной почте (по умолчанию: emails)

3. Запустите проект

Установите зависимости, затем запустите приложение.

pip install requirements.txt

python app.py

Для локального тестирования и прототипирования мы будем использовать ngrok для создания общедоступного IP-адреса, через который наш почтовый клиент (SendGrid) сможет получить доступ к нашему приложению для анализа электронной почты.

Поскольку приложение Flask в демонстрационном коде по умолчанию использует порт 5002, просто запустите:

ngrok http 5002

В случае успеха вы должны увидеть следующее:

Session Status                online                                                                                                                                                                                
Account                       <email>@oxen.ai (Plan: Free)                                                                                                                                                                
Update                        update available (version 3.3.0, Ctrl-U to update)                                                                                                                                    
Version                       3.2.2                                                                                                                                                                                 
Region                        United States (us)                                                                                                                                                                    
Latency                       24ms                                                                                                                                                                                  
Web Interface                 <http://127.0.0.1:4040>                                                                                                                                                                 
Forwarding                    **https://<some-big-long-url>.ngrok-free.app** -> <http://localhost:5002>

URL-адрес, выделенный жирным шрифтом выше (под Forwarding), теперь перенаправляется на порт 5002 на вашем локальном компьютере, где запущено ваше приложение Flask. Мы передадим этот адрес Sendgrid на следующем шаге, что позволит их веб-хуку Inbound Parse пересылать входящие электронные письма в ваше приложение.

4. Настройте веб-хук SendGrid Inbound Parse.

Эта интеграция использует SendGrid для отслеживания всей входящей электронной почты на определенном поддомене.

Инструкция тут — три быстрых совета по настройке:

  1. После настройки для домена трафик на любой адрес в этом домене будет направляться в ваше приложение Flask. Поэтому мы настоятельно рекомендуем использовать поддомен (мы выбрали dataset-builder.oxen.ai), а не добавлять его в корень (oxen.ai).
  2. В разделе «URL-адрес назначения» введите указанный выше адрес пересылки ngrok, а затем конечную точку, в которой вы будете прослушивать запрос POST (например: https://‹some-big-long-url›.ngrok-free.app/add-image)
  3. Установите флажок «Отправить Raw» в разделе «Дополнительные параметры».

После правильной настройки этот веб-хук будет пересылать все входящие электронные письма на ‹поддомен›.‹ваш-домен›.com в виде запросов POST на ваш недавно запущенный сервер Flask.

5. Зафиксируйте данные, отправив электронное письмо

После запуска сервера и правильной настройки SendGrid мы готовы начать вносить свой вклад!

Используя репозиторий данных обнаружения объектов EgoObjectsChallenge, мы удаленно зафиксируем образ нашей кофеварки со следующим письмом:

Через несколько секунд мы можем проверить историю коммитов в OxenHub:

Та-да! 🎉 Не только файл был добавлен в наш каталог изображений, но и к нашему файлу меток была добавлена ​​​​строка, содержащая проанализированные и вычисленные метаданные о нашем недавно добавленном изображении, включая его размеры, путь к файлу и класс.

Итак, как это работает?

Отправка электронного письма на любой адрес в указанном нами поддомене запускает веб-хук входящего анализа, который отправляет запрос на наш маршрут /add-image.

После получения мы сначала используем вспомогательные модули Sendgrid, чтобы преобразовать его в формат ключ-значение.

# Parse email into sendgrid Parse object
parse = Parse(config, request)

Затем мы перебираем вложения в этом объекте электронной почты, сохраняя все изображения во временный локальный каталог.

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

for attachment in parsed_email.attachments():
        if attachment['type'] in ['image/jpeg', 'image/png']:
            mdata = base64.b64decode(attachment['contents'])
            target_fname = config.temp_image_folder + "/" + str(shortuuid.uuid()) + '.' + attachment['type'].split('/')[1]
            with open(target_fname, 'wb') as f:
                f.write(mdata)
            fnames.append(target_fname)

Когда наши изображения сохранены и готовы к загрузке, мы используем объект python Oxen RemoteRepo, чтобы легко подготовить наши файлы изображений и связанные с ними метаданные.

Сначала проанализируйте имя репозитория, метку класса и участника из объекта электронной почты:

params = {}
params['repo'] = parsed_email.key_values()['to'].split('@')[0]
params['label'] = parsed_email.key_values()['subject'].lower()
params['contributor'] = parsed_email.key_values()['from']

Инициализируйте соединение с удаленным репозиторием волов и проверьте целевую ветку:

repo = RemoteRepo(f"{os.getenv('NAMESPACE')}/{params['repo']}", config.remote_host)
repo.checkout(config.branch)

Для каждого файла изображения:

  1. Соберите словарь метаданных, соответствующий схеме метки в удаленном файле аннотаций (файл, ширина, высота, основная_категория).
  2. Добавьте файл изображения в удаленную рабочую область
  3. Добавьте строку метаданных в метку DataFrame.
for file in files:
	  metadata = { # 1
	      "path": f"{config.image_directory}/{file.split('/')[-1]}",
	      "label": params['label'],
	      "contributor": params['contributor'],
	      "added_at": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
	  }
	  repo.add(file, config.image_directory) # 2
	  repo.add_df_row(config.label_path, metadata) # 3

Когда закончите, зафиксируйте данные в репо!

repo.commit(f"Add {len(files)} images of class {params['label']} via email from {params['contributor']}")

Подведение итогов

Удаленные рабочие пространства Oxen и библиотека python позволяют легко и легко вносить вклад в некоторые очень тяжелые наборы данных. Здесь есть потенциал для широкого спектра интеграций, помимо электронной почты, от управления репо на основе SMS до сбора отзывов людей в режиме реального времени о взаимодействиях с чат-ботами.

Нам бы очень хотелось увидеть, что вы создадите с помощью этих инструментов! Свяжитесь с нами по адресу [email protected], подпишитесь на нас в Twitter @oxendrove, погрузитесь глубже в документацию или Подпишитесь на Oxen сегодня.

Если вам нравится то, что мы делаем, не стесняйтесь дать нам звезду на GitHub ⭐ — за каждую звезду Бык получает крылья!