Контракт первичен: источник истины — main.tsp, из него компилируются
документы OpenAPI в openapi/, из них
@hey-api/openapi-python
генерирует pydantic-модели в app/types/handlers/. Генератор молодой
(0.0.x), и часть работы, которую в TypeScript-версии он делает сам, здесь
пока сделана руками. Ниже — что именно и на что это заменится.
У TypeScript-версии есть серверный плагин: он вешает маршруты по спеке и
типизирует обработчики полным набором операций контракта. У
python-генератора такого плагина пока нет, поэтому регистрация написана
в app/glue.py: он читает контракт, связывает операции с обработчиками
по идентификатору и берёт оттуда же код успеха, описание и авторизацию.
Свойства при этом те же, что дал бы плагин: забытая операция роняет приложение на старте, лишняя — тоже, а авторизацию негде забыть, потому что обработчик про неё не знает.
Чего этот регистратор не даёт: обработчики не типизированы набором операций, то есть неверная сигнатура ловится не проверкой типов, а прогоном.
Когда появится серверный плагин: app/glue.py удаляется целиком, а
регистрация берётся из сгенерированного.
TypeScript-версия шлёт корректные запросы сгенерированным клиентом:
контракт, который клиент не даёт выразить, тест выразить и не может.
Python-генератор SDK пока печатает заглушки: метод объявлен без
параметров, а в путь не подставляется {user_id}. Поэтому тесты ходят
через httpx.
Когда SDK доделают: корректные запросы переезжают на него, а через
httpx остаются те, что контракт нарушают намеренно.
Генератор печатает любое необязательное поле контракта как
Optional[...], поэтому модель принимает null там, где контракт его не
разрешает. Для колонок NOT NULL это 500 на запросе, который схема
пропустила.
Разница берётся из самого контракта в app/lib/changes.py: список
обнуляемых полей читается из документа, и null в остальных отбивается
как ошибка запроса.
Когда генератор научится различать: changes() сводится к
model_dump(exclude_unset=True).
@secret в контракте превращается в format: password и writeOnly, но
в модели это str, а не SecretStr: значение попадает в повторение
объекта при отладке.
Когда генератор начнёт печатать SecretStr: правка сведётся к
перегенерации.