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}

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

governor = Governor(
    scope=PostgresTickScope(session_scope=sessionmaker, scope="scrapers"),
    capacity_source=proxy_pool,     # сколько прокси живо
    registry=jobs,                  # кто и сколько просит
    windows=job_windows,            # куда применить окна
    state=PostgresStateStore(scope, scope="scrapers"),
    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 [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                # 243 теста: политики, контур, адаптеры, симуляция, интеграция
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.1.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.1.0
File Size Uploaded Provenance
capacity_governor-0.1.0.tar.gz 110.3 kB With provenance Details

Built distribution (wheel)

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

Total release size: 152.9 kB

Release files / capacity_governor-0.1.0.tar.gz

Download URL capacity_governor-0.1.0.tar.gz
Size 110.3 kB
Tags Source
SHA-256 checksum
How to use checksums
34fcc7abfaed5f5987f105f687a088975a07ee6324bdef584a2a4e03038dd225
BLAKE2b-256 checksum
How to use checksums
61c2c1c169cbab4b7d9090db5fb9d9f9587c50e3bf9841973fe939c10214de5f
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 19, 2026.

Transparency log

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

Download URL capacity_governor-0.1.0-py3-none-any.whl
Size 42.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
093899ff5d16d2ed4e3d6a6866f803f381dd22789719b781f50af2afd27294f9
BLAKE2b-256 checksum
How to use checksums
0ed3f1ce47764a8d3ea2c2254481c28a38657f084e9e5884c8ce74e27cad98c2
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 19, 2026.

Transparency log

Security for capacity-governor 0.1.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.1.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 19, 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.1.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