Python
Асинхронный типизированный клиент для Pachca API. Построен на httpx с поддержкой type hints и dataclass-моделей. Требуется Python 3.10+.
Быстрый старт
Установка
Создание клиента
Клиенту нужен токен бота или персональный токен. Какой выбрать и кто может его выпустить, описано в разделе Какой токен выбрать.
Первый запрос
await внутри async def.Инициализация
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
token | str | — | Bearer-токен для авторизации |
base_url | str | https://api.pachca.com/api/shared/v1 | Базовый URL API |
Клиент использует httpx.AsyncClient — после завершения работы закройте его:
Все методы
| Метод | Метод API |
|---|---|
client.oauth.revoke_token() | POSTОтзыв токена |
client.oauth.exchange_token() | POSTОбмен кода на токен |
client.oauth.get_token_info() | GETИнформация о токене |
client.chats.create_chat() | POSTНовый чат |
client.chats.request_export() | POSTЭкспорт сообщений |
client.chats.list_chats() | GETСписок чатов |
client.chats.download_export() | GETСкачать архив экспорта |
client.chats.get_chat() | GETИнформация о чате |
client.chats.list_company_chats() | GETСписок чатов пространства |
client.chats.update_chat() | PUTРедактирование чата |
client.chats.archive_chat() | PUTАрхивация чата |
client.chats.update_chat_avatar() | PUTЗагрузка аватара чата |
client.chats.unarchive_chat() | PUTРазархивация чата |
client.chats.mark_chat_unread() | PUTОтметка чата непрочитанным |
client.chats.delete_chat_avatar() | DELETEУдаление аватара чата |
client.profile.get_profile() | GETСвой профиль |
client.profile.get_status() | GETСвой статус |
client.profile.update_profile_avatar() | PUTЗагрузка своего аватара |
client.profile.update_status() | PUTНовый свой статус |
client.profile.delete_profile_avatar() | DELETEУдаление своего аватара |
client.profile.delete_status() | DELETEУдаление своего статуса |
client.users.create_user() | POSTНовый сотрудник |
client.users.list_users() | GETСписок сотрудников |
client.users.get_user() | GETИнформация о сотруднике |
client.users.get_user_status() | GETСтатус сотрудника |
client.users.update_user() | PUTРедактирование сотрудника |
client.users.update_user_avatar() | PUTЗагрузка аватара сотрудника |
client.users.update_user_status() | PUTНовый статус сотрудника |
client.users.delete_user() | DELETEУдаление сотрудника |
client.users.delete_user_avatar() | DELETEУдаление аватара сотрудника |
client.users.delete_user_status() | DELETEУдаление статуса сотрудника |
client.group_tags.create_tag() | POSTНовый тег |
client.group_tags.list_tags() | GETСписок тегов |
client.group_tags.get_tag() | GETИнформация о теге |
client.group_tags.get_tag_users() | GETСписок сотрудников тега |
client.group_tags.update_tag() | PUTРедактирование тега |
client.group_tags.delete_tag() | DELETEУдаление тега |
client.members.add_tags() | POSTДобавление тегов |
client.members.add_members() | POSTДобавление участников |
client.members.list_members() | GETСписок участников чата |
client.members.update_member_role() | PUTРедактирование роли участника |
client.members.remove_tag() | DELETEИсключение тега из чата |
client.members.leave_chat() | DELETEВыход из чата |
client.members.remove_member() | DELETEИсключение участника |
client.threads.create_thread() | POSTНовый тред |
client.threads.create_standalone_thread() | POSTНовый самостоятельный тред |
client.threads.list_threads() | GETСписок тредов |
client.threads.get_thread() | GETИнформация о треде |
client.messages.create_message() | POSTНовое сообщение |
client.messages.unfurl() | POSTUnfurl (разворачивание ссылок) |
client.messages.pin_message() | POSTЗакрепление сообщения |
client.messages.list_chat_messages() | GETСписок сообщений чата |
client.messages.get_message() | GETИнформация о сообщении |
client.messages.update_message() | PUTРедактирование сообщения |
client.messages.delete_message() | DELETEУдаление сообщения |
client.messages.unpin_message() | DELETEОткрепление сообщения |
client.read_members.list_read_members() | GETСписок прочитавших сообщение |
client.reactions.add_reaction() | POSTДобавление реакции |
client.reactions.list_reactions() | GETСписок реакций |
client.reactions.remove_reaction() | DELETEУдаление реакции |
client.important_messages.add_message_to_important() | POSTДобавление сообщения в важные |
client.important_messages.list_important_messages() | GETСписок важных сообщений |
client.important_messages.remove_message_from_important() | DELETEУдаление сообщения из важных |
client.search.search_chats() | GETПоиск чатов |
client.search.search_messages() | GETПоиск сообщений |
client.search.search_users() | GETПоиск сотрудников |
client.tasks.create_task() | POSTНовое напоминание |
client.tasks.list_tasks() | GETСписок напоминаний |
client.tasks.get_task() | GETИнформация о напоминании |
client.tasks.update_task() | PUTРедактирование напоминания |
client.tasks.delete_task() | DELETEУдаление напоминания |
client.drafts.create_draft() | POSTНовый черновик |
client.drafts.list_drafts() | GETСписок черновиков |
client.drafts.get_draft() | GETИнформация о черновике |
client.drafts.update_draft() | PUTРедактирование черновика |
client.drafts.delete_draft() | DELETEУдаление черновика |
client.views.open_view() | POSTОткрытие представления |
client.views.submit_view_response() | POSTОтвет на отправку формы |
client.bots.self_recreate_bot_token() | POSTРотация собственного токена бота |
client.bots.create_bot() | POSTНовый бот |
client.bots.recreate_bot_token() | POSTРотация токена бота |
client.bots.rotate_bot_client_secret() | POSTРотация секрета клиента |
client.bots.create_bot_token() | POSTНовый токен бота |
client.bots.reissue_bot_token() | POSTПеревыпуск токена бота |
client.bots.list_bots() | GETСписок ботов |
client.bots.get_bot() | GETИнформация о боте |
client.bots.get_bot_scopes() | GETКаталог прав бота |
client.bots.list_bot_tokens() | GETСписок токенов бота |
client.bots.list_company_bots() | GETСписок ботов пространства |
client.bots.get_webhook_events() | GETИстория событий |
client.bots.get_webhook_events_stream() | GETПоток событий |
client.bots.self_update_bot_webhook() | PUTСаморегистрация вебхука бота |
client.bots.update_bot() | PUTРедактирование бота |
client.bots.update_bot_avatar() | PUTЗагрузка аватара бота |
client.bots.update_bot_token() | PUTИзменение токена бота |
client.bots.delete_bot() | DELETEУдаление бота |
client.bots.delete_bot_avatar() | DELETEУдаление аватара бота |
client.bots.delete_bot_token() | DELETEУдаление токена бота |
client.bots.delete_webhook_event() | DELETEУдаление события истории |
client.security.get_audit_events() | GETЖурнал аудита событий |
client.custom_properties.list_properties() | GETСписок дополнительных полей |
client.files.upload_file() | POSTЗагрузка файла |
client.files.get_upload_params() | POSTПолучение подписи, ключа и других параметров |
client.files.download_file() | GETСкачивание файла |
Запросы
Все методы — асинхронные (async def) и возвращают корутины.
GET с параметрами:
POST с телом запроса:
Простой вызов по ID:
Значение null
Необязательное поле, которое не задано, в запрос не попадает, поэтому метод обновления меняет только то, что вы передали. Некоторые поля API принимают null: например, null в oauth_client выключает у бота авторизацию от имени сотрудника, а в webhook.kind удаляет входящий вебхук. Чтобы отправить null, назовите поле в null_fields той же модели запроса так, как оно называется в Python:
null_fields есть у моделей запроса с такими полями, а в комментарии к нему перечислены имена, которые в нём можно указать. С другим именем SDK выбрасывает ValueError и запрос не отправляет.
Пагинация
Поля пагинации называются как в API: meta.paginate.next_page, prev_page, has_next и has_prev, а у методов поиска ещё meta.total. Какие поля приходят у каждого метода и как понять, что страницы закончились, описано в разделе Пагинация.
Ручная пагинация
В модели поле has_next необязательное. Если оно None, цикл идёт дальше и останавливается на пустой странице. Так же обходят страницы методы *_all().
Автопагинация
Для каждого метода с пагинацией есть *_all() вариант:
Доступные методы автопагинации:
| Метод | Возвращает |
|---|---|
security.get_audit_events_all() | list[AuditEvent] |
bots.list_bots_all() | list[BotResponse] |
bots.list_bot_tokens_all() | list[BotAccessToken] |
bots.list_company_bots_all() | list[CompanyBotResponse] |
bots.get_webhook_events_all() | list[WebhookEvent] |
chats.list_chats_all() | list[Chat] |
chats.list_company_chats_all() | list[Chat] |
drafts.list_drafts_all() | list[Draft] |
group_tags.list_tags_all() | list[GroupTag] |
group_tags.get_tag_users_all() | list[User] |
important_messages.list_important_messages_all() | list[Message] |
members.list_members_all() | list[User] |
messages.list_chat_messages_all() | list[Message] |
reactions.list_reactions_all() | list[Reaction] |
search.search_chats_all() | list[Chat] |
search.search_messages_all() | list[Message] |
search.search_users_all() | list[User] |
tasks.list_tasks_all() | list[Task] |
threads.list_threads_all() | list[Thread] |
users.list_users_all() | list[User] |
Обработка ошибок
SDK выбрасывает два типа исключений:
ApiError
Возникает при ошибках 400, 403, 404, 409, 410, 422 с массивом errors в теле:
Поля ApiErrorItem:
| Поле | Тип | Описание |
|---|---|---|
key | str | Поле, вызвавшее ошибку |
value | Any | None | Переданное значение |
message | str | Текст ошибки |
code | ValidationErrorCode | Код валидации |
payload | dict[str, Any] | None | Дополнительные данные |
Код статуса ответа — в поле status_code. Если ответ с ошибкой пришёл без тела или не в JSON, SDK тоже выбрасывает ApiError: с кодом статуса и пустым errors. Так бывает с ответом 404 без тела от метода GETПоток событий, когда история событий выключена, и со страницей прокси при 502.
OAuthError
Возникает при ошибке авторизации: 401, а также 403 с кодом insufficient_scope или role_forbidden и отказе при обмене кода на токен. Код — в поле error, список кодов — в разделе Ошибки авторизации:
Поле error — перечисление OAuthErrorCode: его сравнивают с элементом, например OAuthErrorCode.INSUFFICIENT_SCOPE, или со строкой.
Повторные запросы
Паузы между попытками, к каждой SDK добавляет случайную величину до 25%:
- 429 с заголовком
Retry-After: срок из заголовка - 429 без заголовка: 1 сек, 2 сек, 4 сек
- 5xx: 1 сек, 2 сек, 3 сек
Сетевую ошибку без ответа сервера SDK не повторяет: исключение httpx приходит сразу. Повторы делает RetryTransport, обёртка над транспортом httpx.
Общие правила повторов — в разделе Повторные запросы.
Типы
Все модели — Python dataclass'ы с type hints:
Поле-перечисление в ответе приходит элементом своего перечисления, в том числе со значением, которого SDK ещё не знает: у такого элемента в value исходная строка, а is_known равно False. Так же работает и вызов вроде OAuthScope("x"): проверить, знает ли SDK значение, помогает is_known.
Тело вебхука
Тела событий вебхука описаны моделями MessageWebhookPayload, ReactionWebhookPayload, ButtonWebhookPayload, ViewSubmitWebhookPayload, ChatMemberWebhookPayload, CompanyMemberWebhookPayload, LinkSharedWebhookPayload и VideoCallWebhookPayload. Тип WebhookPayloadUnion объединяет их, а модель по полям type и event выбирает функция deserialize:
Подпись проверяйте по исходному телу до разбора, как в разделе Безопасность. Те же модели отдают методы poll_webhook_events и poll_webhook_payloads, которые забирают события из истории: пример — в разделе Пример поллинга.
Зависимости
| Пакет | Версия | Назначение |
|---|---|---|
httpx | >=0.23.0, <0.29.0 | Асинхронный HTTP-клиент |
Примеры
Отправка сообщения:
Список сотрудников:
Создание напоминания: