tallyho
Async-библиотека для Python и PostgreSQL. Она добавляет к брокеру задач то, чего в нём обычно нет: учёт группы задач (батчи, вложенные батчи, прогресс, финализация ровно один раз), задачи, которые порождают задачи, конвейеры этапов и хуки, которые пишут итог в ваши таблицы той же транзакцией.
Статус: pre-alpha, версия 1.0 ещё не выпущена. Документация собирается в сайт из docs/ и публикуется на GitHub Pages. Как библиотека устроена внутри, описано в docs/ARCHITECTURE.md.
Что это даёт
- Батч считает, сколько задач найдено, сделано, упало и сколько осталось. Один запрос отдаёт снимок всего дерева под-батчей вместе с оценкой времени до конца.
- Итог батча записывается в вашу таблицу в той же транзакции, в которой батч становится завершённым. Статус кампании и состояние батча не расходятся.
- Задачи порождают задачи, этапы конвейера работают параллельно, и следующий этап закрывается сам, когда закончились его источники.
- Группой можно управлять: отложенный старт, пауза, отмена, повтор упавших, ограничение параллелизма, политики ошибок.
- При падении воркера, брокера или сети задачи не теряются, и батч доходит до итога.
Исполнение задач, ретраи и расписания остаются за брокером, бизнес-статусы живут в ваших таблицах.
Установка
Нужны Python 3.11 или новее и PostgreSQL 14 или новее.
pip install "tallyho[asyncpg]" # или tallyho[psycopg]
pip install "tallyho[asyncpg,flexiq]" # с адаптером flexiq
Быстрый старт
Скрипт ниже работает со встроенным InlineBroker: он выполняет задачи в том же процессе,
поэтому для знакомства хватит PostgreSQL и одного файла.
# quickstart.py
import asyncio
from sqlalchemy.ext.asyncio import create_async_engine
from tallyho import Tallyho, item
from tallyho.testing import InlineBroker
engine = create_async_engine("postgresql+asyncpg://app:secret@localhost/app")
broker = InlineBroker() # выполняет задачи в этом же процессе; в продакшне здесь адаптер брокера
th = Tallyho(engine, schema="quickstart")
th.install(broker.adapter)
async def send_email(address: str) -> None:
if address.endswith("@bounce.test"):
item.error("hard_bounce") # ошибка без исключения и без ретраев
return
item.ok("sent") # итог задачи с меткой
async def main() -> None:
await th.migrate() # создать схему и таблицы
async with th.batch("newsletter") as batch:
await batch.map(send_email, ["ada@ok.test", "grace@ok.test", "gone@bounce.test"])
# выход из блока: батч закрыт, транзакция закоммичена
await broker.drain() # выполнить задачи; в продакшне это делают воркеры
view = await batch.handle.view()
print(view.state.name, view.progress.found, view.progress.ok, view.progress.error)
print(dict(view.labels))
await th.aclose()
await engine.dispose()
asyncio.run(main())
# COMPLETED_WITH_ERRORS 3 2 1
# {'sent': 2, 'hard_bounce': 1}
Что здесь произошло:
th.batch(kind)создал батч и записал три задачи одной транзакцией. С ключом,th.batch(kind, key=...), повторный вызов второй батч не создаст.- При выходе из
async withбатч закрылся, а транзакция закоммитилась; после этого задачи отправляются в брокер. - Каждая задача записала свой итог; после последней батч финализировался - ровно один раз.
handle.view()вернул состояние и счётчики.
Дальше
| Задача | Страница |
|---|---|
| Разобраться в терминах и гарантиях | Основные понятия |
| Посмотреть два приложения целиком на flexiq: проверка аккаунтов и экспорт почты | Разбор на примерах |
Поставить пакет, создать таблицы (migrate, Alembic, CLI) |
Установка и миграции |
Под-батчи, конвейеры fed_by, spawn, политики ошибок, пауза и отмена, прогресс, атрибуты и листинг |
Батчи |
Записать итог и прогресс в свои таблицы, retention и release() |
Хуки |
Тесты с InlineBroker и FakeClock |
Тестирование |
| Подключить брокер flexiq | Адаптер flexiq |
| Процессы и maintenance, остановка, autovacuum, pgbouncer, метрики | Процессы и maintenance |
| Что не входит в v1 | Ограничения v1 |
Для ИИ-ассистентов в корне лежит llms.txt: краткие правила работы с библиотекой и карта документации со ссылками на файлы репозитория.
Разработка
Нужен uv и (для интеграционных тестов) Docker.
uv sync --all-extras # окружение + все инструменты
uv run pre-commit install # хуки на commit и push
uv run poe check # всё, что проверяет CI (кроме интеграции)
uv run poe test-all # + интеграционные тесты с PostgreSQL
Сайт документации собирается командой uv run --group docs poe docs. Подробнее -
CONTRIBUTING.md.
Лицензия
MIT
Metadata
Release files for tallyho 0.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tallyho-0.0.1.tar.gz | 851.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tallyho-0.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.1 MB
Release files / tallyho-0.0.1.tar.gz
| Download URL | tallyho-0.0.1.tar.gz |
|---|---|
| Size | 851.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
67509002c99938050599134b86b104ec3d8c1f0f318d1889a2e423c1903d42c6
|
|
BLAKE2b-256 checksum How to use checksums |
78125154889c47eb5fe1e17a5f29b5a46432fbbb9b1ee4089808e7666fb0ae39
|
| 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 Oct 7, 2026.
Transparency logRelease files / tallyho-0.0.1-py3-none-any.whl
| Download URL | tallyho-0.0.1-py3-none-any.whl |
|---|---|
| Size | 264.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7e056699e55c19c9ad247e5de650c7b121afeab45b5de01824233895f8836c4c
|
|
BLAKE2b-256 checksum How to use checksums |
0a862e54ea2bb2d3bbf8db17a597b0c60a54bafa59352053b09c1ec07aeb4283
|
| 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 Oct 7, 2026.
Transparency log