Skip to content

Клиент Moysklad API

Базовый URL: https://api.moysklad.ru/api/remap/1.2/ Vendor API: https://apps-api.moysklad.ru/api/vendor/1.0/

Синхронный клиент

Низкоуровневый (src/moysklad/base.py)

  • HTTP-обёртки: _get, _post, _put, _delete через requests.
  • Авторизация: Bearer token (из Install.access_token) или Basic Auth (login/password).
  • Заголовок X-Lognex-Accept-Region для узбекской локации.
  • Обработка ошибок: MoyskladException, MoyskladUnauthorized, MoyskladTokenExpiredException, MoyskladDocumentNotFoundException, MoyskladFewDocumentsFoundException.
  • Утилиты: retry_with_backoff (экспоненциальная задержка, особенно для 429), chain_get (безопасный доступ к dict), chunks (разбиение на пачки по 1000), get_meta/get_href (генерация meta-объектов МойСклад).
  • Глобальный exception handler в backend.py и gui.py отлавливает MoyskladTokenExpiredException / MoyskladUnauthorized и возвращает пользователю сообщение «Переустановите приложение!».

High-level (src/moysklad/entities/base.py)

Обёртки над base.py для CRUD документов: get_document, create_document, update_document, delete_document, get_rows, append_rows, get_documents. Интегрирован с Celery (@app.task).

Асинхронный клиент

src/moysklad/async_/base.py

Класс AsyncMoyskladClient на базе aiohttp.ClientSession. Реализует те же операции (get_documents, create_document, update_document, delete_document, append_rows, get_rows, get_or_create_contract), но полностью асинхронно. Умеет автоматически "докидывать" позиции (>1000 шт.) чанками.

Используется в GUI-страницах и сервисах, где нужен async/await.

Входящие запросы МойСклад: проверка JWT

МойСклад подписывает запросы к эндпоинтам решений JWT HS256 секретом решения (app.secret_key). Проверка — src/endpoints/vendor_auth.py:

  • запросы жизненного цикла (PUT установка, GET статус, DELETE удаление) — вызов из хендлеров src/endpoints/vendor.py;
  • нажатия кнопок (POST .../apps/{appId}/{accountId}/button, любые решения) — middleware src/endpoints/button/jwt_check.py.

Проверяются подпись, сроки (не дольше 300 с, допуск 60 с) и одноразовость jti (Redis, ключ vendor-jwt-replay:{app}:{jti}, помечается после успешного ответа). Результат — строка лога vendor jwt: <результат> <lifecycle|button> <метод> app_uuid=… и метрика Logfire vendor_jwt_checks (result, kind, app_uuid, from_dev_id, enforce).

Переменная По умолчанию Что делает
VENDOR_JWT_ENFORCE выключена отказ для запросов жизненного цикла: 401 на невалидную подпись, 503 при недоступности проверки
VENDOR_JWT_ENFORCE_BUTTONS выключена то же для нажатий кнопок, независимо от первой

Пока переменная выключена, запросы не отклоняются никогда (в том числе при сбое БД/Redis и по таймауту 3 с) — только пишется результат. Включать после того, как в логе по всем решениям этого вида только ok: задать переменную в apps.env и поочерёдно пересоздать backend0 и backend1. Откат — убрать переменную и так же пересоздать.