ТранскрибаторТранскрибатор
Практическая инструкция

JSON Schema для расшифровки: как проверить обязательные поля и типы реплик

Проверка массива реплик через jsonschema: обязательные поля, дополнительные ключи и числовое время. Отдельные правила ID, границ и ограничения проверки.

Транскрибатор
ЗАПИСЬПЛАН РАБОТЫСогласуйте контрактрепликиПроверьте схему и данныеПроверьте отдельныеограниченияПроверить результатОТ СЛОВ К РЕЗУЛЬТАТУ
Работа с реальной записьюНаглядный учебный примерШаблон для копирования
1Согласуйте контрактреплики2Проверьте схему иданные3Проверьте отдельныеограничения
Синтаксис файла, контракт структуры и содержательная проверка отвечают на разные вопросы.

Согласуйте контракт перед проверкой

Когда одна программа передаёт расшифровку другой, ошибка может возникнуть из-за отсутствующего поля или неожиданного типа. Схема делает ожидания явными. Сначала определите, какие значения действительно должны быть в каждой реплике и как они измеряются.

В учебном контракте файл содержит массив объектов: replica_id и speaker — строки, start и end — неотрицательные секунды, text — строка. Это формат примера, а не обещание формата экспорта сервиса. Если ваши данные устроены иначе, сначала разработайте соответствующий контракт.

Текстовую основу можно получить через Транскрибатор. Структурированный массив формируется и проверяется отдельно; не приписывайте продукту показанную схему или автоматическое подтверждение временных границ.

Разделите синтаксис и структуру

Сначала json.load должен прочитать корректный JSON. Неправильная запятая или незакрытая строка — ошибка синтаксиса. Затем JSON Schema проверяет уже прочитанные значения. Строка "12.5" остаётся строкой и не проходит требование number, хотя внешне похожа на число.

required требует наличие поля, properties описывает его тип, additionalProperties=False отклоняет неизвестные ключи. Одного перечисления properties недостаточно, чтобы сделать поля обязательными. Отсутствие поля и пустая строка также являются разными состояниями.

В примере minLength=1 отклоняет пустую строку, но допускает строку из пробелов. Поэтому отдельный код ниже проверяет текст и speaker через strip(). Не называйте такую схему полной проверкой содержимого.

Запустите валидатор и прочитайте путь ошибки

Понадобятся Python и пакет jsonschema из обычного реестра: python -m pip install jsonschema. Сохраните replicas.json и скрипт рядом. Используется Draft202012Validator; проверка check_schema помогает обнаружить некорректную саму схему.

iter_errors возвращает ошибки, а absolute_path показывает место в данных. Путь [2, "start"] относится к третьей реплике и полю start. Сообщение об отсутствующем обязательном поле относится к объекту, в котором оно должно находиться.

Не исправляйте ошибку автоматической подстановкой неизвестного значения. Если speaker отсутствует, строка "Неизвестный" может быть допустимой договорённостью только после её согласования, а не способом скрыть пропуск. Сначала выясните происхождение ошибки.

Проверьте то, что схема не выражает в примере

В показанном контракте end и start проверяются как числа по отдельности. Правило end >= start выполняется обычным кодом после структурной проверки. Уникальность replica_id также проверяется отдельно: uniqueItems для массива сравнивает целые объекты и не заменяет уникальность одного поля.

JSON не содержит NaN или Infinity. Python допускает их расширенный разбор по умолчанию; пример явно отклоняет такие константы через parse_constant. Не применяйте арифметику к неизвестным или бесконечным значениям как к таймкодам.

Это ещё не контроль порядка, перекрытий, соответствия длине аудио или правильности говорящего. Для работы с временными интервалами полезен разбор интервалов речи. Правила времени должны быть согласованы с источником и назначением результата.

Сохраните результат и версию контракта

Учебная проверка должна включать корректную реплику и ошибки: отсутствующий text, строковое start, лишний ключ, повторный ID и конец раньше начала. Не проверяйте только один правильный объект, если цель — выявление конкретных нарушений.

Сохраните версию схемы, входной файл и список замечаний. После изменения контракта выполните проверку снова. Исправление данных не должно молча менять смысл текста или временную шкалу.

При дальнейшей сверке версий таблицы полезно сравнение по стабильному ID. Структурная проверка и контроль изменений дополняют друг друга, но правильность произнесённых слов по-прежнему устанавливается по записи.

Учебный пример

Учебный пример нарушений контракта

Условные поля показывают различие ошибок структуры и дополнительных правил.

ЗначениеЧто нарушеноПроверка
start: "12.5"Строка вместо числаJSON Schema
Нет textОбязательное полеJSON Schema
end: 4, start: 5Граница интервалаОтдельный код
Две разные реплики с ID r01Уникальность ключаОтдельный код
ФайлКорректный JSONРазбор синтаксисаКонтрактПоля и типыJSON SchemaСмыслВремя, ID, речьДополнительные правила
Прохождение одного уровня не означает прохождение остальных.

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

Валидатор учебного массива реплик

Рабочая заготовкаВыделите и скопируйте
import json
from jsonschema import Draft202012Validator

schema = {
    "type": "array",
    "items": {
        "type": "object",
        "required": ["replica_id", "speaker", "start", "end", "text"],
        "additionalProperties": False,
        "properties": {
            "replica_id": {"type": "string", "minLength": 1},
            "speaker": {"type": "string", "minLength": 1},
            "start": {"type": "number", "minimum": 0},
            "end": {"type": "number", "minimum": 0},
            "text": {"type": "string", "minLength": 1}
        }
    }
}
def reject_constant(value):
    raise ValueError("Недопустимая JSON-константа: " + value)
with open("replicas.json", encoding="utf-8") as f:
    data = json.load(f, parse_constant=reject_constant)
Draft202012Validator.check_schema(schema)
errors = list(Draft202012Validator(schema).iter_errors(data))
for error in errors:
    print(list(error.absolute_path), error.message)
if errors:
    raise SystemExit("Структура не прошла проверку")
seen = set()
for index, row in enumerate(data):
    if row["replica_id"] in seen:
        raise ValueError("Повторный ID: " + str(index))
    seen.add(row["replica_id"])
    if not row["text"].strip() or not row["speaker"].strip():
        raise ValueError("Только пробелы: " + str(index))
    if row["end"] < row["start"]:
        raise ValueError("Конец раньше начала: " + str(index))
print("Структура и дополнительные правила проверены:", len(data))

Частые вопросы

properties делает поле обязательным?

Нет. Для обязательного наличия используется required.

Схема исправляет данные?

Нет. Она сообщает о несоответствии контракту.

uniqueItems достаточно для уникального ID?

Нет. Оно сравнивает целые элементы, а не одно поле каждого объекта.

Прошедшая проверка гарантирует точную речь?

Нет. Текст, говорящие и границы проверяются по записи отдельно.