Миграция между альфами#
Eazy SDK в альфе переименовывает без deprecated-алиасов: старое имя исчезает, ImportError
или AttributeError показывает, что именно нужно поменять. Эта страница служит единственной
подсказкой. Каждая строка таблицы проверяется тестом: «стало» импортируется, «было» отсутствует.
Один пакет вместо десяти (0.2.0a8)#
Ядро и все интеграции поставляются одним пакетом eazy-sdk-core. Имена импорта не изменились:
eazy_sdk, eazy_sdk_html, eazy_sdk_browser и остальные остаются прежними. Меняется только
команда установки.
Было |
Стало |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Дополнение ставит сторонние библиотеки интеграции. Её код уже лежит в пакете, поэтому без
дополнения импорт интеграции завершится ImportError с именем недостающей библиотеки.
Куки сессии: один способ (0.2.0a11)#
Куку, которую поставил сайт, библиотека несёт сама: корень SDK объявляет Cookies(...), а набор
кук принадлежит Identity. Все прежние способы отправить такую куку удалены.
Было |
Стало |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Что поменять в коде:
Сессия на куках. Вместо
session_cookie("sid", ...)объявите на корнеcookies = Cookies(required=("sid",))и обычнуюsession_scheme(Model). Модель может не размещать ничего, если вся сессия живёт в куках.Поля для кук в шагах входа. Удалите
FromCookieв ответе иCookie[str]в следующем запросе, если они только переносили куку сайта.FromCookieостаётся для значения, которое нужно как данные.Браузерная сессия для HTTP. Вместо
browser_cookie_auth(state, scheme, "sid")передайтеIdentity(cookies=CookieState(state.cookies)).Запись куки.
StoredCookie.domainпишется без ведущей точки. Куку для домена с поддоменами задаётhost_only=False; точка в домене приводит кValueError.Своё хранилище сессий.
SessionStore.saveполучил необязательный аргументcookies. Хранилищу токенной сессии менять нечего; хранилищу сайта с куками аргумент нужен.База
eazy_sdk_sqlmodel. Таблица сессий получила колонку. Для уже созданной базы выполнитеALTER TABLE sessions ADD COLUMN cookie_state JSON.Сохранённые браузерные сессии прежнего формата не читаются: по ним выполняется вход.
Переход с 0.2.0a5 на 0.3.0#
Корень SDK стал отдельным типом. SyncApi и AsyncApi являются роутерами: операции и атрибуты сервиса
(base_url, errors, security, signing, crypto, wire, signed, allow). Композиция,
владение клиентами и привязки живут в SyncRoot/AsyncRoot; api_group(...) объявляется только
на корне. Подробности: Мультисервисный SDK.
Было |
Стало |
Комментарий |
|---|---|---|
|
|
Фабрика переехала на корень; она же создаёт и закрывает свой клиент. |
|
|
То же для async. |
|
|
Второго способа собрать корень нет: |
|
|
То же для async. |
|
|
Роутер ничем не владеет; закрывает ресурсы корень. |
|
|
То же для async. |
|
|
Дефолты роутера стали обычными атрибутами класса и наследуются по MRO. |
Аутентификация уехала из транспорта в session scope. Identity объявляет auth-схемы, ключи
подписи, DI и observer; он передаётся корню (ShopSdk(client, identity=…)) или отдельному роутеру
(UsersApi(client, identity=…)). Один Identity обслуживает все сервисы корня как при общем
клиенте, так и при отдельном клиенте у каждого сервиса.
Было |
Стало |
Комментарий |
|---|---|---|
|
|
Кортеж настроенных |
|
|
Алгоритм подписи входит в контракт API; ключ остаётся секретом вызывающей стороны. |
|
|
DI зависит от окружения вызова, а не от пула соединений. |
|
|
Наблюдатель следует за вызывающей стороной. |
|
|
Фабрику scoped SDK регистрирует тот, кому передан |
Корень eazy_sdk экспортирует 39 имён вместо 55: то, что нужно автору SDK в первый час. Всё
остальное импортируется из своего модуля. Это не сокрытие, а отказ от второго имени для одной
вещи.
Было |
Стало |
Комментарий |
|---|---|---|
|
|
Вместе с |
|
|
Вместе с |
|
|
Вместе с |
|
|
Вместе с |
|
|
|
|
|
|
|
|
Вместе с |
|
|
Вместе с |
|
|
Порт переехал к единственному читателю; слоя ради разрыва импорта больше нет. |
Синхронный клиент больше не создаёт event loop: тот же конвейер шагается на вызывающем потоке.
Client теперь можно вызывать из кода, где loop уже работает; взамен колбэк, который сам уходит
в сеть через await, поднимает SynchronousSuspensionError вместо того, чтобы молча крутиться в
приватном loop.
Было |
Стало |
Комментарий |
|---|---|---|
|
|
Ошибка сменила причину: не «loop уже работает», а «этот колбэк действительно приостанавливается». |
ClientConfig перестал быть плоским списком из пятнадцати полей: остались три группы по владельцу
плюс host-scoped crypto (его судьба решается в фазе 48). guards= понижается фабрикой
Security.of(...), а не мутацией frozen-объекта в __post_init__.
Было |
Стало |
Комментарий |
|---|---|---|
|
|
Вместе с |
|
|
Валидация бюджетов переехала в группу. |
|
|
|
|
|
Пустой |
|
|
Публичного поля, которое всегда пусто, больше нет. |
|
|
|
|
|
Библиотека моделей относится к реализации SDK и объявляется на корне. |
|
|
|
Слово «wire» теперь означает ровно одно понятие: представление запроса на проводе. Всё, что влияет на
байты, объявляется одним Wire на операции (и наследуется от роутера и миксина сервиса); всё, что
не влияет, задаётся одним Serialization на корне. Подпись указывается только по месту: адресных правил
sign(scope=…) больше нет, потому что опечатка в hosts= оставляла запрос молча неподписанным.
Подробности: Представление запроса.
Было |
Стало |
Комментарий |
|---|---|---|
|
|
|
|
|
Подпись объявляет операция или роутер параметром |
|
|
Переопределение задаётся объявлением на более специфичном роутере. |
|
|
Тип шифрованного представления; у HTTP-операции это |
|
|
Одно имя используется для одного понятия и в HTTP, и в WebSocket; |
Новое без замены: eazy_sdk.serialization.Serialization(json=…, documents=(…,)) задаёт JSON-бэкенд и парсер
документов объявляются на корне, а бэкенд, не способный выполнить контракт операции, отвергается
при компиляции, а не молча меняет байты.
Понятие конверта уехало из транспорта: Envelope, ProtocolMessage, CorrelationKey,
ChannelKey, ControlKind и InboundMessageKind живут в eazy_sdk.protocols и описывают
протокол прикладного уровня, а не WebSocket. WsProtocol объединяет Envelope с тем, что есть
только у соединения. Подробности: Протоколы и конверты.
Было |
Стало |
Комментарий |
|---|---|---|
|
|
Вместе с |
|
|
Вместе с |
Новое без замены: eazy_sdk.protocols.JsonRpc и @api.rpc("method") позволяют описать сервис,
у которого имя метода лежит в теле, так же, как REST; rpc_result, rpc_error(code, model) и
rpc_error_default(model) строят обычные Success/Error, второй модели ошибок не появляется.
Реализация WsProtocol получает метод read(envelope), куда переезжает прежняя логика
inspect(frame) после декодирования кадра.
Новое без замены: eazy_sdk.bind и eazy_sdk.Binding задают привязку роутера или его миксина
к другому клиенту и/или адресу при сборке (bindings=(...)).
Операция стала классом. Поля класса являются полями запроса, а __http__ содержит всё, что операция объявляет,
а op(...) публикует её на роутере. Декоратор остался короткой формой того же самого: он
синтезирует такой же frozen-класс. Причина заключается не в стиле: у TypedDict нет значений по умолчанию и
нет default_factory, а у класса есть, и сам запрос становится значением, которое можно построить,
изменить и отправить. Подробности: Запросы и Запрос как значение.
Было |
Стало |
Причина |
|---|---|---|
|
класс |
defaults и |
|
|
один способ вместо трёх |
|
return-аннотация операции либо |
семья выводится из модели |
|
|
короткая форма |
|
|
корневые имена стали алиасами |
|
|
то же для остальных маркеров |
|
|
то же |
|
|
проекция описывает представление, а не байтовый контракт |
|
|
одно объявление полей |
|
|
бюджет корня; вместе с |
|
|
вместе с |
|
|
модель объявлена один раз |
|
|
без наследования от библиотеки |
|
|
одно имя для одного понятия |
|
|
несколько документных бэкендов, выбор по медиа |
|
|
плумбинг рантайма ушёл из публичной поверхности |
|
|
то же |
|
|
то же, вместе с |
|
|
вместе с |
|
|
читает компилятор, не автор SDK |
|
|
результат компиляции, не объявление |
|
по-прежнему работает; доступен класс |
классы и для WebSocket |
|
|
сводка вместо тела ответа и заголовков |
Новое без замены: Omittable[T] = UNSET служит единственным способом не отправить поле;
unwrap = "/data" на сервисе снимает конверт один раз; ClientConfig(errors={host: {...}}) задаёт ошибки, которыми
хост отвечает любому SDK; RpcOperation/Rpc в eazy_sdk.protocols и WsCall/WsSubscribe/
WsSend/Ws в eazy_sdk.websocket предоставляют те же классы для других протоколов;
eazy-sdk-adaptix предоставляет центральный Retort как адаптер моделей.
Переход с 0.2.0a4 на 0.2.0a5#
Было |
Стало |
Комментарий |
|---|---|---|
|
|
Рантайм-ошибка «челлендж распознан, но не разобран». Детекторная |
|
|
Proxy объявляет handler ( |
|
|
Codegen-хелпер получил своё имя; |
|
|
То же для схемы. Сгенерированные модули нужно перегенерировать. |
extra |
зависимость |
|
Новые параметры без брейков: proxy= у Client.httpx/requests/curl_cffi и
AsyncClient.httpx/curl_cffi, SolveContext.remaining().
Переход с 0.2.0a3 на 0.2.0a4#
Фасад и клиенты#
Было |
Стало |
Комментарий |
|---|---|---|
|
|
Корневой фасад слит с API-классом: |
|
|
То же для async. |
|
|
Сырые verb-методы ( |
|
|
То же для async. |
|
|
Guard’ы и presets ставятся через |
|
|
Advanced-политики и solver-биндинги входят в одну группу |
|
|
Единый суффикс |
|
|
|
|
|
|
|
|
Базой всех исключений служит |
Protection#
Было |
Стало |
Комментарий |
|---|---|---|
|
|
Один реестр биндингов. |
|
|
Один протокол солвера. |
|
|
Фабрика |
Простой путь теперь использует класс Guard из eazy_sdk.protection и Security.of(...).
Вынесенные пакеты#
Было |
Стало |
Комментарий |
|---|---|---|
|
|
Плагин |
|
|
|
|
|
|
|
|
Плагин |
|
|
|
|
|
Ядро ( |
Storage-хуки переименованы из middleware в observers: StorageObserver, LoggingObserver,
EventRecordingObserver, параметр observers=.