Як брати рядки в роботу

Як через API BDO UA Translate вибрати рядки для перекладу: фільтри патча й стану, курсорна пагінація, групи полів і чому службові рядки не приходять.

Робота береться одним запитом GET /rows з фільтрами й курсором. Найчастіший випадок · «нові рядки активного патча, у яких ще немає перекладу»:

curl -s -G -H "X-API-Key: $BDO_API_KEY" \
  --data-urlencode 'patch=active' \
  --data-urlencode 'missing=both' \
  --data-urlencode 'limit=20' \
  --data-urlencode 'fields=classification,tokens,constraints,glossary' \
  https://bdo-ua.com.ua/api/agent/v1/rows

Фільтри, які вирішують усе

Фільтр Що дає
patch=active лише те, що приніс поточний патч гри
missing=both | machine | manual чого саме бракує рядку
state=none,machine,manual,fresh,stale,pending стан перекладу
domain, semantic_type звузити до предметів, квестів, назв тощо
machine_provenance=legacy рядки, де ШІ-шар зробив старий прогін бота
exclude_proposed=1 пропустити те, що вже чекає на модерацію
updated_since що змінилося з певного часу

Невідоме значення фільтра дає 400 invalid_request з переліком допустимих · свідомо, а не тихе ігнорування. Проігнорований фільтр змусив би агента годинами перекладати не те.

Пагінація курсором, а не сторінками

meta.next_cursor передається в cursor наступного запиту. meta.has_more каже, чи є продовження. Загальна кількість під фільтром рахується лише на явний include_total=1: це окремий COUNT по каталогу з понад мільйона рядків, і платити за нього на кожній сторінці не треба.

Просіть лише потрібні поля

fields · це економія контексту моделі й трафіку:

Група Що дає
core (завжди) identity_hash, source_text, source_hash, ordinal, untranslatable
layers ручний і машинний шар: текст, статус, свіжість, провайдер і модель
tokens що саме треба зберегти в перекладі, з кількістю входжень
constraints межі довжини й прапорець неперекладності
glossary терміни цього рядка з відповідниками
patch тип зміни, попереднє джерело, рішення по рядку

reference і glossary · найдорожчі; без них відповідь істотно менша.

Чому службових рядків немає у вибірці

За замовчуванням діє translatable=1, і рядки, у яких немає що перекладати, не приходять узагалі: суцільні системні вставки, <null>, рядки без жодної літери, клавіатурні мітки й порожній оригінал. Спроба записати переклад у такий рядок за прямим identity_hash теж отримає відмову non_translatable.

Гра зіставляє такі рядки дослівно · запис туди ламає її непомітно.

Канонічний ключ рядка

Скрізь використовуйте identity_hash, а не id. Ідентифікатори бази різняться між середовищами, і скрипт, написаний проти id, одного дня зачепить чужий рядок. Перевірено на практиці, тому всі маршрути приймають саме хеш.

Далі: звідки брати контекст і назви.