RU Марка и модель SDK и виджеты

Клиентские библиотеки и виджеты

У сервиса две ручки: нормализация — привести марку и модель к записи каталога, и подсказки — дополнить ввод по мере набора. Библиотеки для Python, C#, Ruby, PHP, Elixir и JavaScript закрывают обе. Отдельно — React-компоненты, если поиск нужен прямо в интерфейсе.

Виджеты

Работают против API этого стенда, данные настоящие. Подключается один файл mm-widgets.js: React лежит внутри него, ставить ничего не надо.

Обе ручки вместе

MakeModelDemo — подсказки на вводе, а после выбора карточка записи: значение каждого поля и откуда оно взялось. Наберите «камр» или «тайота камри».

Размер каталога

CatalogStats — счётчики из /v1/public/stats.

Только подсказки

SuggestInput — поле ввода без карточки, если распознавание вы делаете у себя. Управляется с клавиатуры: стрелки, Enter, Escape; скринридер слышит, сколько вариантов нашлось.

Выберите вариант — здесь появится его идентификатор.

как подключить на своей странице
<script src="https://ЭТОТ-СТЕНД/ui/sdk/mm-widgets.js" defer></script>

<div data-mm-widget="demo"
     data-mm-base-url=""
     data-mm-targets="broker"
     data-mm-paths='{"resolve":["/demo-api/resolve","/v1/resolve"],
                     "decode":["/demo-api/decode","/v1/decode"]}'></div>

Установка и первый запрос

Ниже один и тот же пример на всех языках: отправить «Тайота / камри» и получить запись каталога.

sdk/python · pip install ./sdk/python
from make_model_sdk import MakeModelClient, QualityCode

with MakeModelClient("https://ЭТОТ-СТЕНД", api_key="…") as client:
    res = client.resolve("Тайота", "камри", target="broker")

    res.quality_code            # "NO_MAPPING_FOR_TARGET"
    res.primary_id              # "N-TOYOTA-CAMRY"
    res.field_value("mark")     # "Toyota"
    res.is_ok                   # нашлась ли запись
    res.outbound_for("broker")  # OutboundValue | None

    # Свободный текст, стратегия по каждому полю
    res = client.resolve_request({
        "query": "тайота камри 2.5 автомат",
        "want": {"mark": "exact", "modification": "confidence"},
        "targets": ["broker"],
    })

    # Запись уже выбрана — decode вместо повторного распознавания
    card = client.decode("N-TOYOTA-CAMRY", fields=["mark", "model"])

    client.suggest("камр", limit=7)   # list[SuggestItem]
    client.stats()                    # размеры каталога

Две ручки

Названия методов в библиотеках пишутся по правилам своего языка (resolve_pair, ResolvePairAsync, resolvePair), но зовут они одни и те же эндпоинты.

РучкаМетодHTTPЧто делает
Нормализация resolve POST /v1/resolve Приводит произвольный ввод к записи каталога и возвращает поля с указанием источника каждого значения. Принимает inputs, query, vin, pts, want, targets.
decode POST /v1/decode То же, когда запись уже выбрана — например, пользователь ткнул в подсказку. Распознавать заново не нужно, поля перечисляются в fields.
Подсказки suggest GET /v1/suggest Дополняет ввод по мере набора. Только чтение, ничего не меняет. limit — от 1 до 20.

Есть ещё stats (GET /v1/public/stats) — сколько в каталоге марок, моделей и алиасов. Это служебная сводка для витрин, к распознаванию отношения не имеет.

  • «Не нашли» — это не ошибка. NO_MATCH, NO_MAPPING_FOR_TARGET и OK_GREY приходят с кодом HTTP 200, в поле result. Ошибка HTTP значит, что не в порядке запрос или сам сервис.
  • В inputs и want шесть ключей: mark, model, modification, body_type, year, segment. Остальные дают 422 — чаще всего так ловится brand вместо mark.
  • Повторы запроса. Библиотеки сами повторяют запрос трижды, если сервис ответил 5xx или оборвалось соединение; пауза между попытками растёт с 0,2 секунды. На 4xx повторов нет: если запрос составлен неверно, второй раз он не станет верным.
  • Токен нужен не всем методам. /v1/resolve и /v1/decode закрыты, /v1/suggest и /v1/public/stats открыты. На этом стенде токен подставляет nginx на путях /demo-api/* — поэтому в коде страницы его нет.
  • Ответ воспроизводим. Тот же запрос при той же ruleset_version даёт тот же результат. Эту версию и catalog_epoch сервис возвращает каждый раз — их стоит писать в лог рядом с ответом.