waix-python — WhatsApp API для Python
Клиент WAIX для Python 3.10 и новее. Работает на стандартной библиотеке, содержит аннотации типов. Запросы синхронные: в асинхронном веб-приложении вызывайте SDK через рабочий поток.
Установка
python -m pip install "waix-python @ git+https://github.com/ivanpukhov/waix-python.git@v0.2.0"
Перед первым запросом
Подключите номер в WAIX, получите Connection ID и серверный ключ с правом messages:write. Пример использует одобренный шаблон order_ready на русском языке с одной переменной в теле.
Отправка шаблона
import os
import uuid
from waix import Waix, WaixError
waix = Waix(os.environ['WAIX_API_KEY'])
# Создайте и сохраните UUID вместе с событием заказа до отправки.
event_id = str(uuid.uuid4())
result = waix.messages.send({
'connection_id': os.environ['WAIX_CONNECTION_ID'],
'to': '+77071234567', 'type': 'template',
'template': {
'name': 'order_ready', 'language': {'code': 'ru'},
'components': [{'type': 'body', 'parameters': [{'type': 'text', 'text': '42'}]}],
},
}, event_id)
print(result['data']['id'], result['data']['status'])
OTP: отправка и проверка
otp = Waix(os.environ['WAIX_OTP_PROJECT_KEY'])
sent = otp.otp.send({'to': '+77071234567', 'ttl': 300}, event_id)
# Сохраните sent['data']['id'] в серверной сессии пользователя.
status = otp.otp.status(sent['data']['id'])
# supplied_code — код, введённый пользователем в той же сессии.
verified = otp.otp.verify(sent['data']['id'], supplied_code)
Ошибки, файлы и параметры клиента
Перехватывайте WaixError. Поля: status (0 при сетевой ошибке), code, request_id, retry_after, body. Таймаут задаётся в секундах:
waix = Waix(os.environ['WAIX_API_KEY'], timeout=30, base_url='https://waix.kz/api/v1')
Проверка TLS-сертификатов включена. Если локальный Python не находит доверенный сертификат, настройте хранилище CA операционной системы или Python; не отключайте проверку TLS.
Загрузка файла: waix.media.upload(connection_id, 'invoice.pdf', content_type='application/pdf', type='document'). Файл читается в память; предел SDK — 100 МБ, дополнительно действуют ограничения API для типа файла.
Пагинация: waix.messages.list(limit=50, before=cursor, before_id=cursor_id).
Проверка вебхука: verify_webhook(raw_body, timestamp_header, signature_header, secret); функция импортируется из waix.
Разработка
PYTHONPATH=src python -m unittest discover -s tests
python -m pip install build
python -m build
Тесты используют локальный HTTP-сервер и не отправляют сообщения клиентам.
Какие методы есть
| Раздел | Возможности |
|---|---|
| Сообщения | Отправка, список с пагинацией, просмотр, явный повтор |
| Подключения | Список номеров, чтение и изменение профиля компании |
| Шаблоны | Список, просмотр, создание, изменение, удаление, предварительный просмотр |
| Медиа | Загрузка файла, список, получение URL, удаление |
| Вебхуки | Чтение и изменение настроек, тест, удаление, смена секрета |
| OTP | Отправка кода, проверка, статус запроса |
Все запросы идут на https://waix.kz/api/v1. SDK возвращает полный JSON-ответ: data, а также pagination, если она есть. Для остальных операций API v1 можно использовать метод request с относительным путём. Не передавайте в него адрес, полученный от непроверенного пользователя.
Некоторым операциям нужны права управления и ключ компании. Ключ отдельного OTP-проекта не даёт доступа к настройкам вебхука компании. Список прав и полей: спецификация API.
Повторные запросы и доставка
Создайте UUID один раз при записи события в своей базе. Передайте его как ключ идемпотентности. При потере ответа повторяйте запрос с тем же UUID и теми же параметрами: новый ключ означает новое сообщение.
HTTP 202 означает, что сообщение поставлено в очередь. Доставку проверяйте по вебхуку, журналу WAIX или методу просмотра сообщения. У SDK нет автоматических повторов и переходов по HTTP redirect. Для 429 учитывайте Retry-After; ошибки 400, 401, 403 требуют исправления параметров или доступа. Сообщение со статусом outcome_unknown нельзя повторять вслепую.
Проверка подписи вебхука
Передавайте в функцию проверки исходные байты тела HTTP-запроса до разбора JSON, заголовки X-Waix-Timestamp, X-Waix-Signature и секрет вебхука. Подпись: HMAC-SHA256 от timestamp + "." + rawBody, с префиксом v1=. Сравнение выполняется за постоянное время; допустимое отклонение времени по умолчанию — 300 секунд.
Отклоняйте неверную подпись. Повторные события определяйте по X-Waix-Delivery: верная подпись сама по себе не защищает от повторной доставки в пределах допустимого времени. Сначала надёжно сохраните событие, затем ответьте кодом 2xx.
Ключи, OTP и данные клиентов
- Храните ключи на сервере. Не включайте их в код сайта, мобильного приложения или общий файл сценария. Выдавайте только нужные права.
- Для первого сообщения клиенту обычно нужен одобренный шаблон. Произвольный текст разрешён в рамках действующего окна обслуживания Meta. Проверяйте согласие клиента и учитывайте отказ от сообщений.
- OTP использует отдельный ключ проекта. Начните с sandbox: он возвращает
test_codeи не отправляет сообщение WhatsApp. Тестовый код нельзя показывать человеку, чью личность вы проверяете. - Сохраните ID OTP-запроса в серверной сессии пользователя. Проверять код должна именно эта сессия. Выдавайте доступ только после успешной проверки; ограничивайте попытки по аккаунту и IP.
- Для рабочих OTP нужны доступный тариф и одобренный отправитель. Проверьте их состояние в кабинете WAIX до включения реальной отправки.
- SDK не записывает ключи, сообщения и коды в лог. Если добавляете свои логи, скрывайте эти данные и сохраняйте
request_idдля диагностики.
Документация и поддержка
Документация WAIX · Поддержка · Тарифы.
SDK работает с API v1 WAIX. Это не клиент Meta Graph API. Версии SDK следуют SemVer. Лицензия — MIT.
Поведение версии 0.2.0
SDK не повторяет запрос за вас. HTTP-ошибка от прокси остаётся HTTP-ошибкой, даже если вместо JSON пришёл HTML: сохраняются статус, request ID и Retry-After. Перенаправления запрещены. Некорректный успешный ответ вызывает INVALID_RESPONSE; ответ больше установленного лимита — RESPONSE_TOO_LARGE. Лимит по умолчанию — 2 МиБ, его можно увеличить до 16 МиБ.
| Ситуация | Что делать |
|---|---|
400 / 422 |
Исправить поля, формат телефона, шаблон или код OTP. |
401 / 403 |
Проверить ключ, права и принадлежность подключения/OTP-проекта. |
409 |
Проверить конфликт ключа идемпотентности: под одним ключом нельзя менять тело. |
429 |
Отложить запрос на срок из Retry-After, сохранив прежний ключ и тело. |
5xx, TIMEOUT, TRANSPORT_ERROR |
Результат отправки может быть неизвестен. Сначала проверить сохранённый ID; если ID не получен, повторять прежний запрос с прежним ключом через ограниченную очередь повторов. |
INVALID_RESPONSE / RESPONSE_TOO_LARGE |
Проверить прокси, адрес API и размер страницы. Не создавать новую отправку. |
OTP_INVALID |
Код неверен, истёк или уже использован. Не выдавать сессию приложения. |
body исключения доступен для диагностики, но может содержать данные клиента. В журнал записывайте только безопасные метаданные из примера ниже. Не сериализуйте целиком ответ sandbox OTP.
Обновление с 0.1.x
Имена существующих методов сохранены. У otp.verify код должен быть строкой из шести цифр: '012345', а не число. Значения query — только строки, конечные числа и boolean; сложные объекты нужно разобрать на параметры. Ошибки HTML от прокси теперь имеют API_ERROR, а перенаправления — REDIRECT_DISALLOWED. При обработке ошибок ориентируйтесь также на HTTP-статус.
Пагинация и диагностика
waix = Waix(os.environ['WAIX_API_KEY'], timeout=30, max_response_bytes=2097152)
for message in waix.messages.iterate(connection_id=connection_id, limit=100, max_pages=100):
save_status(message['id'], message['status'])
Генератор запрашивает страницы по мере чтения, сохраняет фильтры и передаёт оба курсора. Повторный курсор вызывает INVALID_PAGINATION; достижение max_pages — PAGINATION_LIMIT. По умолчанию предел — 1000 страниц. break останавливает загрузку следующих страниц.
try:
result = waix.messages.get(saved_message_id)
except WaixError as error:
logger.warning('WAIX request failed', extra=error.to_dict())
delay_seconds = error.retry_delay() # секунды или None
# Решение о повторе принимает ваша очередь.
Python-клиент синхронный. timeout задаёт таймаут сетевых операций urllib, а не общий дедлайн задания. В асинхронном сервере запускайте клиент в отдельном потоке или очереди; не блокируйте event loop. Файл multipart загружается в память; для больших файлов выделите отдельный worker.
Release files for waix-python 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| waix_python-0.2.0.tar.gz | 21.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| waix_python-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.9 kB
Release files / waix_python-0.2.0.tar.gz
| Download URL | waix_python-0.2.0.tar.gz |
|---|---|
| Size | 21.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f52fdc9c7f3dadd4e937bf10b089377f4460d690ed2a21ad8aaed037a69461c9
|
|
BLAKE2b-256 checksum How to use checksums |
daf99d5844f00240f7e865d4eaedccc320e7f478d104436db2f471032b66c755
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.
Transparency logRelease files / waix_python-0.2.0-py3-none-any.whl
| Download URL | waix_python-0.2.0-py3-none-any.whl |
|---|---|
| Size | 12.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f63f48187236d32041a823f3daed87a215f8f82e758f9e2ca706578ef8475176
|
|
BLAKE2b-256 checksum How to use checksums |
8ce7324d7e73589621f78897f1e65a31888dad21347a8fbd45ecbf7cabccd06f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.
Transparency log