Skip to main content

SIGNAL API

PyPI - Version Telegram chat

Официальная документация API: swagger, OpenAPI-схема.

Два пакета в одном репозитории

Пакет Что это Установка Каталог
sgnl-api Асинхронная Python-обёртка над всем SIGNAL Integration API pip install -U sgnl-api sgnl_api/
sgnl-mcp MCP-сервер: даёт LLM-агенту контролируемый доступ к SIGNAL — чтение без ограничений, запись только с подтверждением, удаление недоступно uvx sgnl-mcp или Docker mcp/

sgnl-mcp построен поверх sgnl-api и зависит от него; sgnl-api ничего не знает про MCP и не тянет его зависимости. Пакеты выпускаются на PyPI независимо. Настройка MCP-сервера, подключение к Claude и запуск в Docker — в mcp/README.md.

sgnl-api — обёртка над API

Установка

pip install -U sgnl-api

Пример

import asyncio
import os
from sgnl_api import DocsApi
from dotenv import load_dotenv

load_dotenv()
CLIENT_ID = os.getenv("CLIENT_ID")
SECRET_ID = os.getenv("SECRET_ID")


async def main():

    async with await DocsApi.create(
        client_id=CLIENT_ID,
        client_secret=SECRET_ID,
        scopes=["project:list"],  # ровно те scope, что включены в интеграции
    ) as docs:
        projects = await docs.project.get_list()
        for project in projects:
            print(project)


if __name__ == "__main__":
    asyncio.run(main())

Клиент можно использовать и без async with — тогда после завершения работы стоит вызвать await docs.aclose(), чтобы закрыть пул соединений.

Scopes

scopes — обязательный параметр: список прав, с которыми запрашивается токен. Он должен совпадать с галочками в интеграции SIGNAL («Редактировать интеграцию»):

  • если в списке есть scope, которого нет в интеграции, SIGNAL не выдаёт токен и не говорит, какого именно не хватает. Клиент выясняет это сам (несколько пробных запросов токена на половинах списка) и бросает SgnlScopeError с текстом not enabled for the integration: docs:issue:list и полем missing_scopes; scope без лицензии попадают в unlicensed_scopes;
  • лишние галочки в интеграции не мешают: запрашивать можно любое подмножество;
  • какой scope нужен методу, написано в его описании (Required scopes: project:list) и в спецификации API.
# только чтение проектов и папок
scopes = ["project:list", "project:read", "docs:folder:list", "docs:item:list"]

Запрашивайте только то, что нужно скрипту: токен без *:create, *:update и *:delete ничего не изменит в SIGNAL, даже если в коде ошибка.

Почему SIGNAL не выдал токен, видно по классу исключения: SgnlScopeError — запрошен scope, которого нет в интеграции; SgnlCredentialError — неверный client_id или client_secret (после «Обновить ключ доступа» старый secret не работает); SgnlLicenseError — у компании нет лицензии на модуль одного из scope.

Обработка ошибок

При ошибке API методы бросают исключение, а не возвращают dict с ключом error — проверять каждый ответ вручную не нужно.

from sgnl_api import DocsApi, SgnlApiError, SgnlNotFoundError

try:
    project = await docs.project.info(project_id)
except SgnlNotFoundError:
    ...
except SgnlApiError as e:
    print(e.status_code, e.message)

Иерархия исключений: SgnlApiError (базовое) → SgnlRequestError (сетевые ошибки/таймауты), SgnlAuthenticationError (401 и отказ в токене; подклассы SgnlScopeError, SgnlCredentialError, SgnlLicenseError), SgnlBadRequestError (400), SgnlForbiddenError (403), SgnlNotFoundError (404), SgnlQuotaExceededError (450), SgnlRateLimitError (429), SgnlServerError (5xx).

Лимиты запросов (429)

API ограничивает частоту запросов (около 10 запросов в секунду на client_id, 50 с пополнением 4 в секунду на компанию). При ответе 429 клиент сам ждёт интервал из заголовка Retry-After (не больше 30 с за раз) и повторяет запрос — по умолчанию до 3 раз. Если лимит не отпустил, бросается SgnlRateLimitError с полем retry_after.

api = await DocsApi.create(client_id=..., client_secret=..., scopes=[...], max_retries=5)  # 0 — отключить повторы

Если токен отозван раньше срока, на ответ 401 клиент один раз получает новый токен и повторяет запрос.

Загрузка файла

Документ из локального файла создаётся в три шага. Файл передаётся в хранилище потоком, поэтому большие файлы (API допускает до 5 ГиБ) не загружаются в память целиком.

uploaded = await docs.file.upload(project_id, "drawings/A-101.pdf")      # {"object_id", "mime_type", "size"}
version_id = await docs.version.create(object_id=uploaded["object_id"], project_id=project_id, name="A-101.pdf")
item_id = await docs.item.create_file("A-101.pdf", folder_id, version_id)  # новый документ
# или новая версия существующего документа:
await docs.item.add_version(item_id, version_id)

Свой HTTP-клиент

В DocsApi.create можно передать свой httpx.AsyncClient — например, с транспортом, который фильтрует или ограничивает запросы (так устроен sgnl-mcp). Такой клиент aclose() не закрывает: его закрывает владелец.

async with httpx.AsyncClient(transport=my_transport, timeout=30) as http:
    docs = await DocsApi.create(client_id=..., client_secret=..., scopes=[...], http_client=http)

Проверка покрытия API

Скрипт сравнивает спецификацию с методами обёртки и показывает новые, удалённые и изменённые эндпоинты:

uv run scripts/check_api_coverage.py                       # скачать спецификацию с api.sgnl.pro
uv run scripts/check_api_coverage.py openapi/schema.yml    # или сохранённую копию из репозитория

Код возврата 1 означает, что обёртка вызывает эндпоинт, которого больше нет, или не передаёт обязательное поле. Копия спецификации в openapi/schema.yml используется и тестами sgnl-mcp: при обновлении API её нужно заменить.

Разработка

Репозиторий — uv workspace из двух пакетов (sgnl-api в корне и sgnl-mcp в mcp/):

uv sync --all-packages                     # оба пакета и dev-зависимости
uv run pytest                              # тесты SDK
uv run --package sgnl-mcp pytest mcp/tests # тесты MCP-сервера
uv build --all-packages                    # sdist и wheel обоих пакетов в dist/
docker build -f mcp/Dockerfile -t sgnl-mcp . # образ MCP-сервера

Методы

Обертка покрывает весь официальный API (swagger). Методы сгруппированы по ресурсам ровно как в спецификации (по тегам).

item

Метод Описание Возвращает
item.get_list Список файлов в директории list[dict]
item.count Количество файлов в директории int
item.search Поиск вложенных элементов в директории list[dict]
item.create_file Создает новый файл с версией UUID
item.create_link Создает элемент-ссылку на URL UUID
item.get_link Получает ссылку для загрузки файла dict
item.get_item_version Возвращает версию элемента по UUID dict
item.add_version Добавляет новую версию к существующему файлу None
item.update Обновляет элемент (имя/ссылку) None
item.update_version Обновляет комментарий версии элемента None
item.delete Перемещает элемент в корзину None
item.move Перемещает элемент в другую папку None

folder

Метод Описание Возвращает
folder.get_list Список дочерних папок list[dict]
folder.create Создает новую папку UUID
folder.update Обновляет имя и/или цвет папки None
folder.rename Переименовывает папку None
folder.delete Перемещает папку в корзину None
folder.get_project_tree Дерево папок проекта с правами пользователя dict

project / project_user / project_user_custom_role

Метод Описание Возвращает
project.root_folder Информация о корневой папке проекта dict
project.root_folder_id UUID корневой папки проекта UUID
project.get_storage_id UUID хранилища, назначенного проекту UUID
project.get_list Список проектов list[dict]
project.info Информация о проекте dict
project.users Список пользователей проекта list[dict]
project.roles Список ролей проекта list[dict]
project.users_permissions Права пользователя в проекте list[str]
project.update Обновляет основную информацию проекта None
project_user.add Добавляет пользователей в проекты None
project_user.delete Удаляет пользователей из проектов None
project_user_custom_role.set Назначает кастомные роли пользователю в проекте None

company / company_user / company_user_custom_role

Метод Описание Возвращает
company.users_list Список пользователей компании list[dict]
company.roles_list Список ролей компании list[dict]
company_user.get_id_by_telegram_id UUID пользователя по Telegram id UUID
company_user.add Приглашает/добавляет пользователей в компанию list[dict]
company_user.delete Удаляет пользователей из компании None
company_user_custom_role.set Назначает кастомные роли пользователю в компании None

version

Метод Описание Возвращает
version.get_list Список версий файла list[dict]
version.count Количество версий файла int
version.find_batch Версии для пакета элементов list[dict]
version.create Создает новую версию объекта UUID

file (Object)

Метод Описание Возвращает
file.get_object_upload Получает тикет на загрузку объекта dict
file.commit_uploading Завершает загрузку объекта None
file.upload Загружает файл потоком (тикет, передача в хранилище, commit) dict (object_id, mime_type, size)

attribute / attribute_type / attribute_value

Метод Описание Возвращает
attribute.get_list Список атрибутов по фильтру list[dict]
attribute_type.get_list Список типов атрибутов по фильтру list[dict]
attribute_type.create Создает тип атрибута UUID
attribute_type.update Обновляет типы атрибутов (до 50) None
attribute_type_list_items.create Добавляет значения в атрибут-список None
attribute_type_list_items.update Обновляет значения атрибута-списка None
attribute_value.list_issues Значения атрибутов замечаний list[dict]
attribute_value.list_items Значения атрибутов элементов list[dict]
attribute_value.list_folders Значения атрибутов папок list[dict]
attribute_value.set Устанавливает значения атрибутов None

issue и связанные (issue_type, issue_accesses, issue_comment, issue_attachment, issue_events, issue_project_settings)

Метод Описание Возвращает
issue.get_list Список замечаний по фильтру list[dict]
issue.create Создает замечание UUID
issue.update Пакетное обновление замечаний (до 25 шт.) None
issue.count Количество замечаний по фильтру int
issue.item_issues_count Количество замечаний по элементам list[dict]
issue_type.get_list Список типов замечаний list[dict]
issue_accesses.get_list Правила доступа к замечаниям list[dict]
issue_comment.get_list Список комментариев замечания list[dict]
issue_comment.create Создает комментарий UUID
issue_comment.count Количество комментариев int
issue_attachment.get_list Список вложений замечания list[dict]
issue_attachment.download_object Тикет на загрузку вложения dict
issue_events.get_list История событий замечания list[dict]
issue_events.count Количество событий int
issue_project_settings.get Настройки замечаний проекта dict

review и связанные (review_group, review_item, review_type, review_process)

Метод Описание Возвращает
review.get_list Список согласований проекта list[dict]
review.update Обновляет основную информацию согласования None
review.count Количество согласований int
review.get_versions Версии согласований по id list[dict]
review.find_item_version_ids_by_review_version_ids Версии элементов по версиям согласования dict
review.create Создает согласование UUID
review.set_comment Устанавливает/очищает комментарий последней версии None
review.set_type Меняет тип согласования None
review_type.get_names Названия типов согласования проекта list[dict]
review_process.start Запускает процесс согласования None
review_group.get_list Список групп согласований list[dict]
review_item.get_statuses Статусы согласования для версий элементов list[dict]
review_item.add Добавляет версию элемента в согласование None
review_item.remove Удаляет версию элемента из согласования None

share / storage

Метод Описание Возвращает
share.get_list Список ссылок общего доступа по фильтру list[dict]
share.create Создает ссылку общего доступа UUID
share.update Обновляет ссылку общего доступа None
share.delete Помечает ссылку удаленной/восстановленной None
share.count Количество ссылок по фильтру int
storage.get_list Список хранилищ документов list[dict]
Метод Описание Возвращает
cades_signature.get_list Список подписей CAdES версии list[dict]
cades_signature.create Создает подпись CAdES None
embedded_signature.get_list Список встроенных подписей элемента list[dict]
embedded_signature.create Создает встроенную подпись None
mchd.company_documents UUID доверенностей компании list[UUID]
mchd.attached_documents Доверенности, привязанные к подписи list[dict]
mchd.download Тикет на загрузку доверенности dict
card_public_link.regenerate Перегенерирует публичную ссылку карточки дашборда dict

documents_transfer / documents_transfer_item / documents_transfer_type / documents_transfer_acceptance / acceptance_certificate

Метод Описание Возвращает
documents_transfer.get_list Список передач документов по фильтру list[dict]
documents_transfer.get Данные передачи документов по id dict
documents_transfer.count Количество передач по фильтру int
documents_transfer.accesses Правила доступа для типов передач list[dict]
documents_transfer.create Создает передачу документов UUID
documents_transfer_item.get_list Список элементов передачи list[dict]
documents_transfer_item.count Количество элементов передачи int
documents_transfer_item.download Тикет на загрузку элемента передачи dict
documents_transfer_item.add Добавляет версии элементов в передачу None
documents_transfer_type.get_list Список типов передач документов list[dict]
acceptance_certificate.download Тикет на загрузку акта приема-передачи dict
acceptance_certificate.attach Прикрепляет акт приема-передачи к передаче UUID
documents_transfer_acceptance.send Отправляет подготовленную передачу получателю None

permissions / application_user

Метод Описание Возвращает
permissions.upsert_batch Устанавливает права пользователей/ролей на папку None
permissions.get_tree Дерево папок проекта с правами dict
permissions.delete Удаляет конкретное право None
application_user.upsert Назначает роли пользователям в приложениях None
application_user.delete Отзывает доступ пользователей в приложениях None

forge / tangl / folder_items_naming_pattern

Метод Описание Возвращает
forge.convert Запускает конвертацию модели через Forge None
forge.get_viewers_data Токен и URN для Forge Viewer dict
tangl.convert Запускает конвертацию модели через Tangl None
folder_items_naming_pattern.find Шаблоны именования файлов папки dict

формы (project_form, project_form_type, project_form_field_type, form_type, form_type_group, form_field_type)

Метод Описание Возвращает
project_form.get_list Список форм проекта (фильтр + сортировка) dict
project_form.count Количество форм по фильтру int
project_form.get Форма по id dict
project_form.get_summary Сводка по формам list[dict]
project_form.create_batch Создает формы пачкой (до 200) list[UUID]
project_form.update Обновляет поля формы None
project_form.complete Завершает форму None
project_form.find_form_source Формы-источники для поля dict
project_form.get_values_for_template_item Значения для шаблона dict
project_form.get_download_url_by_template_item Ссылка на скачивание по шаблону dict
project_form_type.get_list Типы форм проекта list[dict]
project_form_field_type.get_list Типы полей формы проекта dict
form_type.get_list Типы форм list[dict]
form_type_group.get_list Группы типов форм list[dict]
form_field_type.get_list Типы полей форм list[dict]

дашборды (board, card, card_group)

Метод Описание Возвращает
board.get_list Дашборды проекта list[dict]
card_group.get_list Группы карточек дашборда (тег Group в API) list[dict]
card.get_list Карточки дашборда list[dict]
card.get Карточка с содержимым dict

бронирования и слоты (booking, slot)

Метод Описание Возвращает
booking.get_list Бронирования компании (курсорная пагинация) list[dict]
booking.create_batch Создает бронирования пачкой (до 200) list[dict]
booking.delete_batch Удаляет бронирования None
slot.get_list Слоты компании (курсорная пагинация) list[dict]
slot.create_batch Создает слоты пачкой (до 200) list[dict]
slot.delete_batch Удаляет слоты None

user_log

Метод Описание Возвращает
user_log.get_list Журнал действий пользователей list[dict]

Для методов, принимающих filter/find/values/items как dict, структура соответствует одноимённой схеме в спецификации API — ключи передаются в camelCase, как в JSON-теле запроса (например {"projectId": "...", "issueIds": [...]}).

Metadata

Release files for sgnl-api 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sgnl-api 0.5.0
File Size Uploaded Provenance Actions
sgnl_api-0.5.0.tar.gz 46.7 kB Without provenance Details for sgnl_api-0.5.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for sgnl-api 0.5.0
File Interpreter ABI Platform Actions
sgnl_api-0.5.0-py3-none-any.whl Python 3 none any Details for sgnl_api-0.5.0-py3-none-any.whl

Total release size: 106.2 kB

Release files / sgnl_api-0.5.0.tar.gz

Download URL sgnl_api-0.5.0.tar.gz
Size 46.7 kB
Tags Source
SHA-256 checksum
How to use checksums
cdce8d81921e3a419b06006db1ab018df0aef3ea1695ebde65be5b86e985458c
BLAKE2b-256 checksum
How to use checksums
83a093bcc59972d9758e42d5c117e50a558b82d2249cf1be4698806cbe177533
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / sgnl_api-0.5.0-py3-none-any.whl

Download URL sgnl_api-0.5.0-py3-none-any.whl
Size 59.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f6c563eaf14eda5490db822de68f1ba649c9616531d171c86944eb6c44708f04
BLAKE2b-256 checksum
How to use checksums
04887aa1cde554be732966a4e826a6f86debead521ba1c23751abefb71084780
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for sgnl-api 0.5.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page