Skip to main content

Capacity Governor

CI PyPI Python License

Capacity Governor — асинхронная Python-библиотека, которая решает, кому сколько дефицитного ресурса дать прямо сейчас и когда этот ресурс пополнять. Основной читатель — разработчик Python 3.11+, у которого несколько потребителей делят пул ограниченных ресурсов и мешают друг другу.

Библиотека не хранит ресурсы и не выполняет работу. Она считает окно каждого потребителя — сколько работы ему разрешено держать в полёте — и отдаёт это число вашему коду, который его применяет.

Когда она нужна

Возьмите её, если узнаёте свою ситуацию:

  • один пул делят несколько заданий, и крупное забивает его целиком, а мелкие ждут;
  • ресурс кончается в середине работы, и очередь копит ошибки вместо того, чтобы ждать;
  • вы развели потребителей по жёстким лимитам в конфиге, и теперь половина лимитов простаивает, пока другая упирается в потолок;
  • пополнение (регистрация аккаунтов, закупка ключей) запускается то поздно, то дважды;
  • приоритет сделан через sleep и ручные правки конфига во время инцидента.

Ресурс при этом может быть каким угодно: аккаунты платформ, прокси, слоты браузеров и GPU, ключи внешних API с квотой, номера для SMS, предоплаченные кредиты. Библиотеке важно не что это, а как оно расходуется.

Она не нужна, если ресурс один на одного потребителя, если лимит статичен и никого не стесняет, или если очередь и так простаивает — делить там нечего.

Установка

uv add capacity-governor

Ядро не имеет зависимостей вообще. Адаптер к PostgreSQL ставится отдельно:

uv add "capacity-governor[postgres]"

Как это выглядит

Двенадцать прокси на три задания скрапинга, одно из которых вдвое важнее:

from capacity import ConsumerState, MaxMinFair

policy = MaxMinFair()
allocation = policy.allocate(
    capacity=12,
    consumers=[
        ConsumerState("urgent-scrape", demand=500, weight=2),
        ConsumerState("daily-scrape", demand=500),
        ConsumerState("backfill", demand=500),
    ],
    deficits={},
)

allocation.grants  # {'urgent-scrape': 6, 'daily-scrape': 3, 'backfill': 3}

Политика — чистая функция: те же аргументы дают тот же ответ, базы и времени она не знает. Её можно вызвать прямо в своём планировщике, а можно обернуть в контур, который сам пересчитывает окна по расписанию:

scope = PostgresTickScope(session_scope=sessionmaker, scope="scrapers")
governor = Governor(
    scope=scope,
    capacity_source=proxy_pool,     # сколько прокси живо
    registry=jobs,                  # кто и сколько просит
    windows=job_windows,            # куда применить окна
    state=PostgresStateStore(scope),
    policy=MaxMinFair(min_hold_ticks=5),
    clock=clock,
    stabilizer=Stabilizer(),
)
await governor.run(every=timedelta(seconds=5), stop=shutdown)

Контур берёт лидерство на каждый такт, пишет только изменившиеся окна и переживает перезапуск: очередь и удержания лежат в базе, а не в памяти процесса.

Сценарии

Четыре разбора под разные виды ресурса — с кодом, который запускается без базы:

Сценарий Про что Код
Прокси между скраперами веса, освобождение доли, падение ёмкости examples/proxy_pool.py
Слоты GPU между командами гарантированный минимум и потолок examples/gpu_slots.py
Отправители рассылки последовательный расход, переключение examples/mailing_senders.py
Квота внешнего API когда докупать и сколько examples/api_quota.py
python -m examples.proxy_pool

Что внутри

Политики распределения отвечают на вопрос «кому сколько сейчас»:

  • MaxMinFair — общий пул между несколькими потребителями: веса, гарантированный минимум, потолок, честная ротация, когда ресурса меньше, чем просят;
  • Sequential — выделенный пул с последовательным расходом, где чередование ресурсов вредно;
  • StaticCeiling — статичный потолок для ресурсов, которым пересчёт не нужен.

Политика пополнения отвечает на вопрос «когда заводить ещё»:

  • ReorderPoint — планка «упало ниже — дозаказать до цели», правило «не хватает под уже поставленную работу», бюджет заказов за окно и учёт того, что уже едет.

Контур применяет политику сам: раз в несколько секунд читает ёмкость и спрос, гасит дрожание окон, пишет только изменения, заказывает пополнение и отдаёт метрики такта. Оператор вмешивается командами pin, unpin, pause, resume.

Подробнее — docs/architecture.md.

Интеграции

Порты — обычные Protocol, поэтому подключить можно что угодно. Готовые адаптеры:

Адаптер Что даёт Extras
capacity_adapters.memory всё в памяти: примеры, тесты, прототипы —
capacity_adapters.postgres лидерство на advisory-локе, состояние, pin/pause [postgres]
capacity_adapters.tallyho спрос и окна одним запросом, заказ пополнения [tallyho]
capacity_adapters.identity_hub ёмкость пула аккаунтов через Identity Hub [identity-hub]

Адаптеры к Tallyho и Identity Hub написаны против их публичных сигнатур и сами эти пакеты не импортируют — их можно читать и тестировать, не устанавливая ни один из них.

Разработка

python -m venv .venv && .venv/bin/pip install -e ".[dev,postgres]" asyncpg
pytest -q                # 273 теста: политики, контур, адаптеры, симуляция, интеграция
python -m sim            # прогоны симуляции: как ведут себя параметры под нагрузкой
ruff check . && mypy src tests sim

Интеграционные прогоны требуют PostgreSQL и без него пропускаются:

docker run -d --name capacity-governor-test-pg \
    -e POSTGRES_PASSWORD=capacity -e POSTGRES_USER=capacity \
    -e POSTGRES_DB=capacity -p 55444:5432 postgres:16-alpine

CAPACITY_TEST_DSN задаёт подключение. Порядок выпуска — в docs/releasing.md, изменения — в CHANGELOG.md.

Лицензия

MIT — см. LICENSE.

Metadata

Release files for capacity-governor 0.2.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 capacity-governor 0.2.0
File Size Uploaded Provenance
capacity_governor-0.2.0.tar.gz 132.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for capacity-governor 0.2.0
File Interpreter ABI Platform
capacity_governor-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 179.5 kB

Release files / capacity_governor-0.2.0.tar.gz

Download URL capacity_governor-0.2.0.tar.gz
Size 132.5 kB
Tags Source
SHA-256 checksum
How to use checksums
b885a6d7918e8626eb6fefdef35fe64404657bfbb57f01bcc3f0727586b26de8
BLAKE2b-256 checksum
How to use checksums
4126ef4b2994620fddd0bf6205c784c99be1c0fd46dc7b0d2d423a66b9a61a1b
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 20, 2026.

Transparency log

Release files / capacity_governor-0.2.0-py3-none-any.whl

Download URL capacity_governor-0.2.0-py3-none-any.whl
Size 47.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6f780a1ab268a0b707612e68ba42052c4185639fac7aec90518bec08b3fed756
BLAKE2b-256 checksum
How to use checksums
76a9900c65b2b213c0beb8315874ec8d77b0495e7cb353cd01778f093a2842b0
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 20, 2026.

Transparency log

Security for capacity-governor 0.2.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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for capacity_governor-0.2.0.tar.gz

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 20, 2026.

Transparency log

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.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

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