Async Python library for Pyrus API — Aiogram-style, HTTPX-powered
Project description
aiopyrus
Асинхронная Python-библиотека для Pyrus API. Стиль — как у aiogram. Под капотом — HTTPX.
Главная фишка — TaskContext
Работайте с задачами по именам полей из интерфейса Pyrus — без знания field_id, choice_id, person_id.
ctx = await client.task_context(12345678)
status = ctx["Статус задачи"] # multiple_choice → str
executor = ctx["Исполнитель"] # person → "Имя Фамилия"
ctx.set("Статус задачи", "В работе") # имя варианта → choice_id автоматически
ctx.set("Исполнитель", "Данил Колбасенко") # имя → person_id автоматически
await ctx.answer("Принято в работу")
Установка
pip install aiopyrus
Python 3.10+
Быстрый старт
import asyncio
from aiopyrus import UserClient
async def main():
async with UserClient(login="user@example.com", security_key="KEY") as client:
profile = await client.get_profile()
print(f"Привет, {profile.first_name}!")
ctx = await client.task_context(12345678)
print(ctx.get("Статус задачи", "не задан"))
asyncio.run(main())
TaskContext — справочник методов
| Метод | Описание |
|---|---|
ctx["Поле"] |
Чтение (KeyError если нет) |
ctx.get("Поле", default) |
Чтение с дефолтом |
ctx.raw("Поле") |
Сырой FormField объект |
ctx.find("%паттерн%") |
Поиск по wildcard (как SQL LIKE) |
ctx.set("Поле", value) |
Ленивая запись (чейнится) |
ctx.discard() |
Отмена накопленных set() |
ctx.pending_count() |
Сколько set() ждут отправки |
await ctx.answer("текст") |
Комментарий + сброс всех set() |
await ctx.approve("текст") |
Утвердить шаг согласования |
await ctx.reject("текст") |
Отклонить шаг согласования |
await ctx.finish("текст") |
Завершить задачу |
await ctx.reassign("Имя") |
Переназначить (имя → person_id) |
await ctx.log_time(90, "текст") |
Списать время (минуты) |
await ctx.reply(comment_id, "текст") |
Ответить на комментарий (тред) |
Бот на вебхуках
import asyncio
from aiopyrus import PyrusBot, Dispatcher, Router, FormFilter, StepFilter
from aiopyrus.utils.context import TaskContext
bot = PyrusBot(login="bot@example", security_key="SECRET")
dp = Dispatcher()
router = Router()
@router.task_received(FormFilter(321), StepFilter(2))
async def on_invoice(ctx: TaskContext):
amount = float(ctx.get("Сумма", "0"))
if amount > 100_000:
await ctx.reject("Сумма превышает лимит.")
else:
ctx.set("Статус", "Одобрено")
await ctx.approve("Одобрено автоматически.")
dp.include_router(router)
asyncio.run(dp.start_webhook(bot, host="0.0.0.0", port=8080, path="/pyrus"))
Бот на polling (без публичного сервера)
asyncio.run(
dp.start_polling(
bot,
form_id=321,
steps=2,
interval=30.0, # секунды между запросами
skip_old=True, # не обрабатывать существующие задачи
)
)
Работает за файрволом, не требует публичный URL.
Фильтры
from aiopyrus import FormFilter, StepFilter, FieldValueFilter, EventFilter, F
# Классические
@router.task_received(FormFilter(321), StepFilter(2))
# По значению поля
@router.task_received(FieldValueFilter(field_name="Тип", value="Баг"))
# Magic F
@router.task_received(F.form_id.in_([321, 322]), F.text.contains("срочно"))
# Композиция: &, |, ~
@router.task_received(FormFilter(321) & StepFilter(2) & ~FieldValueFilter(field_name="Статус", value="Закрыт"))
# Временные (для polling)
from aiopyrus.bot.filters import ModifiedAfterFilter, CreatedAfterFilter
@router.task_received(ModifiedAfterFilter()) # только задачи, изменённые после старта бота
Middleware
from aiopyrus import BaseMiddleware
class LoggingMiddleware(BaseMiddleware):
async def __call__(self, handler, payload, bot, data):
print(f"Task {payload.task_id}")
return await handler(payload, bot, data)
dp.middleware(LoggingMiddleware())
Данные организации
async with UserClient(login=LOGIN, security_key=KEY) as client:
# Реестр с фильтрами
tasks = await client.get_register(321, steps=[1, 2], due_filter="overdue")
# Параллельный поиск по нескольким формам
all_tasks = await client.search_tasks({321: [1, 2], 322: None})
# Каталоги
catalogs = await client.get_catalogs()
cat = await client.get_catalog(999)
item = cat.find_item("Москва")
# Участники
person = await client.find_member("Данил Колбасенко")
members = await client.get_members()
# Роли
roles = await client.get_roles()
# Файлы
uploaded = await client.upload_file("/path/to/file.pdf")
content = await client.download_file("guid")
# Объявления
announcements = await client.get_announcements()
Rate limiting
bot = PyrusBot(
login="bot@example",
security_key="SECRET",
requests_per_minute=30,
requests_per_10min=4000,
)
Встроенный rate limiter с экспоненциальным backoff. Лимиты Pyrus API: 5000 запросов / 10 мин.
On-premise
client = UserClient(
login="user@corp.ru",
security_key="KEY",
base_url="https://pyrus.mycompany.ru",
)
Proxy
client = UserClient(
login="user@example.com",
security_key="KEY",
proxy="http://proxy.corp:8080",
)
Примеры
В папке examples/ — 5 файлов от простого к сложному:
| Файл | Тема |
|---|---|
01_quickstart.py |
Подключение, профиль, inbox, TaskContext |
02_task_context.py |
Все методы чтения/записи, согласование, трекинг |
03_bot_webhook.py |
Бот на вебхуках, роутеры, фильтры, middleware |
04_bot_polling.py |
Polling-режим, skip_old, lifecycle hooks |
05_data_management.py |
Реестры, каталоги, участники, роли, файлы |
Лицензия
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aiopyrus-0.1.1.tar.gz.
File metadata
- Download URL: aiopyrus-0.1.1.tar.gz
- Upload date:
- Size: 56.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
01067b9ccde8891c85a1d26acdec8e8a4d47888b0713a259d9f41a4df1d28e02
|
|
| MD5 |
75aea64105ce9abbb580faa2f89894c3
|
|
| BLAKE2b-256 |
b89e8a7095b48b9a7564385f673ce9f89d7e819f81eba50ba124ebd05feeef17
|
File details
Details for the file aiopyrus-0.1.1-py3-none-any.whl.
File metadata
- Download URL: aiopyrus-0.1.1-py3-none-any.whl
- Upload date:
- Size: 56.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08872279ec97c5a1a686de4dcf09405063c4b01fd38cccf3c91a08ab94d699aa
|
|
| MD5 |
de416e7d164d08bee1e83191f978c42d
|
|
| BLAKE2b-256 |
716cca78e161f3dabcccfc0c07d611f08696a5b90fbdceb9bcd01d78006013ba
|