Skip to content

Дефектоскопия — справочник API

Назначение сервиса

Сервис принимает изображение, ставит задачу в очередь и позже возвращает результат классификации.

Для новой интеграции используйте: - POST /predict — чтобы создать задачу; - GET /result/{task_id} — чтобы получить статус и итог; - webhook_url — только как дополнительный обратный вызов, а не как замену повторных запросов.

Базовые адреса

Среда URL Когда использовать
Промышленная https://defects.techcon-ml.ru основной адрес для интеграции
Тестовая https://defects.dev.techcon-ml.ru отдельные тесты среды
Локальная http://localhost:8000 локальная разработка

OpenAPI JSON: <base_url>/openapi.json

Основная ReDoc-поверхность: <base_url>/docs

Вторичная Swagger UI-поверхность: <base_url>/swagger

Совместимый дополнительный ReDoc-путь: <base_url>/redoc

Иерархия источников истины

Если нужен быстрый рабочий сценарий, используйте эту страницу. Если нужен точный состав полей и схем, сверяйтесь в таком порядке: 1. рабочее поведение промышленного сервиса; 2. openapi.json, live ReDoc на /docs, Swagger UI на /swagger и совместимый ReDoc-путь /redoc этого сервиса; 3. эта страница; 4. общее руководство по интеграции.

Этот портал публикует производную копию принятого сервисного контракта. Если текст на портале расходится с тем, что сейчас отвечает production или показывает live /docs / /swagger, ориентируйтесь на live сервис.

Практическая оговорка: ReDoc-поверхности /docs и /redoc описывают JSON-контракт сервиса, а публичный путь /metrics остаётся отдельным служебным endpoint для Prometheus и может не отображаться в OpenAPI.

Коротко для интегратора

  1. POST /predict сразу возвращает 202 Accepted и task_id.
  2. GET /result/{task_id} — основной способ получить состояние и итог задачи.
  3. webhook_url добавляет необязательный обратный вызов только после конечного состояния.
  4. Даже при наличии обратного вызова повторные запросы через GET /result/{task_id} остаются обязательным резервным способом дочитать результат.
  5. estimated_wait_seconds=90 — только ориентир для первого повторного запроса, а не обещание времени готовности.
  6. После первого ожидания повторяйте GET /result/{task_id} с паузой порядка 30–60 секунд на задачу, а не каждые 2–5 секунд.
  7. Сервис не обещает queue position, точный ETA готовности результата или момент старта GPU.

Аутентификация

Заголовок:

Authorization: Bearer <токен>

Режимы: - DEFECTOSCOPY_BEARER_TOKENS — основной вариант, список токенов через запятую; - DEFECTOSCOPY_BEARER_TOKEN — совместимый одиночный токен.

Если обе переменные пусты, авторизация отключена.

Матрица доступа

Эндпоинт Метод Нужен токен
/health GET Нет
/classes/defects GET Да
/classes/surfaces GET Да
/predict POST Да
/result/{task_id} GET Да
/metrics GET Нет
/docs, /swagger, /redoc, /openapi.json GET Нет

Карта эндпоинтов

Метод Путь Назначение
GET /health Проверка готовности сервиса
GET /classes/defects Список классов дефектов
GET /classes/surfaces Список классов поверхностей
POST /predict Постановка задачи на классификацию
GET /result/{task_id} Статус и итог задачи
GET /metrics Метрики Prometheus

GET /health

Публичная проверка состояния.

Успех 200:

{
  "ok": true,
  "data": {
    "model_loaded": true,
    "worker_id": "tc-gpu-t4-01",
    "model_version": "v10",
    "gpu": {
      "name": "Tesla T4",
      "vram_used_mb": 1234,
      "vram_total_mb": 15360
    }
  }
}

Если модель ещё не готова: - HTTP 503 - error.code = "MODEL_NOT_READY"

GET /classes/defects

Возвращает плоский список названий дефектов из текущей модели.

Пример ответа 200:

{
  "ok": true,
  "data": ["царапина", "трещина"]
}

GET /classes/surfaces

Возвращает список допустимых поверхностей.

Пример ответа 200:

{
  "ok": true,
  "data": ["металл", "бетон"]
}

POST /predict

Ставит задачу на классификацию изображения.

Ограничения входа

Поле Правило
image_url только https://
хост image_url storage.yandexcloud.net или storage.yc.yandex.net
priority realtime или batch
webhook_url https://; http:// допустим только для localhost / 127.0.0.1 / ::1

Тело запроса

{
  "image_url": "https://storage.yandexcloud.net/techconimg/zT1RP8i7vfpj",
  "priority": "batch",
  "webhook_url": "https://integrator.example.com/hooks/defectoscopy"
}

Успешный ответ 202 Accepted

{
  "ok": true,
  "data": {
    "task_id": "def-7a2d8f5d0f31",
    "status": "queued",
    "status_url": "/result/def-7a2d8f5d0f31",
    "estimated_wait_seconds": 90
  }
}

Что означает estimated_wait_seconds

  • это ориентир для первого повторного запроса;
  • это не обещание времени полного завершения;
  • это не таймер обратного вызова;
  • после первого опроса безопасная рабочая пауза обычно остаётся в диапазоне 30–60 секунд на задачу.

Возможные ошибки

  • 401 UNAUTHORIZED
  • 422 VALIDATION_ERROR
  • 429 RATE_LIMIT_EXCEEDED
  • 503 QUEUE_UNAVAILABLE

GET /result/{task_id}

Основной путь для чтения состояния и итога задачи.

Состояния задачи

data.status HTTP Значение
queued 202 задача принята и ждёт обработки
processing 202 задача обрабатывается
done 200 классификация завершена успешно
failed 200 обработка завершилась ошибкой

Ответ 202 Accepted

{
  "ok": true,
  "data": {
    "task_id": "def-7a2d8f5d0f31",
    "status": "processing",
    "message": "Задача обрабатывается",
    "webhook": {
      "configured": true,
      "state": "pending",
      "attempts": 0
    }
  }
}

Поле message предназначено для человека. Для логики интеграции и повторных запросов опирайтесь на data.status, HTTP-код и наличие итоговых полей.

Ответ 200 OK для done

{
  "ok": true,
  "data": {
    "task_id": "def-7a2d8f5d0f31",
    "status": "done",
    "result": {
      "surface": "металл",
      "masters": [
        {"name": "механические", "conf": 0.82}
      ],
      "defects": [
        {"name": "царапина", "conf": 0.75}
      ]
    },
    "processing_time_ms": 1234,
    "completed_at": "1745271700",
    "webhook": {
      "configured": true,
      "state": "delivered",
      "attempts": 1,
      "delivery_id": "1b00b33fbad3496eb17ab0fd800d55a7",
      "last_attempt_at": "1745271700",
      "delivered_at": "1745271700",
      "response_status_code": 200
    }
  }
}

Ответ 200 OK для failed

{
  "ok": true,
  "data": {
    "task_id": "def-7a2d8f5d0f31",
    "status": "failed",
    "error": "Не удалось обработать изображение"
  }
}

Блок data.webhook

Если задача создавалась с webhook_url, ответ на повторный запрос может содержать блок data.webhook.

Что можно считать активной опорой для интеграции: - блок появляется только у задач с webhook_url; - во время ожидания он может показывать state=pending; - после успешной доставки он может показывать state=delivered, delivery_id и response_status_code.

Что не нужно поднимать в обязательную бизнес-логику без отдельного согласования: - полный перечень возможных значений state; - точное число повторов и интервалы между ними; - служебные поля, которые не нужны для чтения итогового результата.

Как делать повторные запросы

  • первый GET /result/{task_id} делайте не раньше значения estimated_wait_seconds;
  • пока задача в queued или processing, повторяйте GET /result/{task_id} с паузой порядка 30–60 секунд на задачу;
  • если сервис только что поднялся или нагрузка выросла, увеличивайте паузу, а не частоту повторов;
  • не прекращайте повторные запросы только потому, что обратный вызов уже пришёл;
  • прекращайте повторные запросы после итогового ответа done|failed или после 404 TASK_NOT_FOUND, если окно хранения уже закончилось.

Обратный вызов через webhook_url

Что обещает сервис

  • обратный вызов включается только для задач, созданных с webhook_url;
  • обратный вызов отправляется только после записи итогового результата;
  • обратный вызов использует заголовки X-Techcon-Event, X-Techcon-Task-ID, X-Techcon-Delivery-ID;
  • тело обратного вызова повторяет итоговый формат GET /result/{task_id};
  • повторные запросы остаются каноническим способом дочитать итог независимо от состояния обратного вызова.

Заголовки обратного вызова

Заголовок Значение
Content-Type application/json
X-Techcon-Event defectoscopy.result.terminal
X-Techcon-Task-ID исходный task_id
X-Techcon-Delivery-ID идентификатор одной доставки

Тело обратного вызова

Тело совпадает с итоговым ответом GET /result/{task_id}: - для done содержит result, processing_time_ms, completed_at; - для failed содержит error.

Тексты в message и error человекочитаемы. Для машинной логики интеграции опирайтесь на status, HTTP-код и error.code, а не на формулировку этих полей.

Ограничения и ошибки

Подтверждённые ограничения

Параметр Значение
TTL результата 86400 секунд
estimated_wait_seconds 90
Лимит запросов RATE_LIMIT_PER_MINUTE, по умолчанию 1000
Redis обязателен для /predict и /result/{task_id}

Коды ошибок

HTTP Код Где Значение
401 UNAUTHORIZED защищённые эндпоинты токен отсутствует или неверен
404 TASK_NOT_FOUND /result/{task_id} task_id неизвестен или результат уже удалён по TTL
422 VALIDATION_ERROR /predict неверные параметры запроса
429 RATE_LIMIT_EXCEEDED /predict, /result/{task_id} превышен лимит запросов
503 QUEUE_UNAVAILABLE /predict, /result/{task_id} очередь недоступна
503 MODEL_NOT_READY /health, /classes/* модель ещё не загружена
500 INTERNAL_ERROR глобально внутренняя ошибка

Что сверять через live /docs

Через ReDoc на /docs удобно проверять: - полный список эндпоинтов; - схемы запросов и ответов; - точные названия полей; - runtime-примеры для текущего контракта.

Для интегратора эта страница остаётся более удобным кратким объяснением сценария, а live ReDoc на /docs — точной спецификацией полей и схем.