This release is a pre-release and may not be stable for production use.
browser-pool
Пул браузеров для асинхронного Python. Он держит контексты аккаунтов, сессии, прокси и тёплые вкладки и восстанавливает их после сбоев. Работает поверх Playwright, pydoll или своего браузерного SDK.
Код, который знает сайт (вход, селекторы, операции), пишется отдельно и получает нативные объекты своего SDK без
обёрток: Page у Playwright, Tab у pydoll. browser-pool отвечает за остальное: в каком браузере и контексте открыта
страница, с каким прокси и сессией, что делать, когда браузер упал, прокси умер или сайт выкинул из аккаунта.
Альфа. API может меняться между минорными версиями, каждое изменение описано в CHANGELOG. Ставится с
--pre.
Какие проблемы снимает
Окна друг на друге
Запустили шесть аккаунтов, и шесть окон открылись в одной точке экрана: видно только последнее.
Windows(mode="per_context") раскладывает окна сеткой без перекрытий. У аккаунта одно окно, его задачи идут вкладками
в этом окне, а с Debug(label_windows=True) в заголовке написано, чьё оно. Debug(hold_on_error=60) оставляет
упавшую вкладку открытой, чтобы посмотреть, что было на странице. Подробнее: Отладка.
Самодельные семафоры
Отдайте пулу все задачи сразу. Браузеров, вкладок в браузере и вкладок у одного аккаунта будет не больше, чем
разрешено в конфиге, остальные задачи ждут в очереди с приоритетами. С any_of задача получает любой свободный
аккаунт, в первую очередь уже залогиненный. Подробнее: Параллельность.
Гонки при входе
На пять задач одного аккаунта приходится один вход: остальные ждут его и получают залогиненный контекст. Одновременно
идёт не больше concurrent_opens входов, а через один прокси входы идут по одному. Сессия сохраняется и переживает
падение браузера, а с FileStateStore и перезапуск процесса. С FileIdentityLock аккаунт не откроют дважды и
разные процессы. Подробнее: Вход.
Зависшие Chrome и своп
Когда не хватает памяти или CPU, пул перестаёт расти и закрывает простаивающее. Распухшие браузеры он перезапускает, дав их задачам доработать. После остановки не остаётся ни одного процесса Chrome, а браузеры упавшего процесса добивает следующий запуск. Подробнее: Ресурсы хоста.
Прокси
Список принимается в привычных форматах: host:port, user:pass@host:port и других. Аккаунт закреплён за своим прокси и после перезапуска, мёртвые прокси уходят на
паузу сами. Часовой пояс и локаль подставляются по стране выхода. Аккаунты держатся на дешёвых прокси, пока сайт их
пускает. Подробнее: Прокси.
Обработка ошибок
Вы говорите, что сломалось: вкладка, сессия, прокси, аккаунт или браузер. Пул чинит ровно это и повторяет задачу на
исправных ресурсах. После lease.commit() необратимое действие не повторится. Подробнее:
Сбои и повторы.
Не видно, что делает пул
Пул отдаёт снимок своего состояния без секретов, типизированные события и метрики Prometheus, а с упавшей вкладки снимает скриншот и HTML. Подробнее: Наблюдение.
Логику не проверить без браузера
FakeDriver заменяет браузер и выдаёт сбои по заказу теста. С виртуальным временем паузы и повторы проверяются за
миллисекунды. Подробнее: Тесты.
Установка
pip install --pre "browser-pool[playwright]" # Python 3.12+
playwright install chromium
Или browser-pool[pydoll], для него нужен установленный Chrome. У ядра зависимостей нет. Экстры: playwright,
pydoll, prometheus (метрики), resources (защита хоста по памяти и CPU, psutil), testing (плагин pytest).
Пример
from pathlib import Path
from browser_pool import BaseFlow, BrowserPool, Identity, PoolConfig, ProxyPolicy
from browser_pool.drivers.playwright import PlaywrightDriver
from browser_pool.proxies import ProxyList
from browser_pool.state import FileStateStore
class MailFlow(BaseFlow):
"""Как открыть сессию аккаунта: пул зовёт это один раз на контекст."""
async def open(self, ctx):
account = ctx.identity.payload
client = mail_sdk.Client(await ctx.new_page()) # ваш SDK сайта
if not await client.is_logged_in(): # сессию пул уже восстановил
await client.login(account.login, account.password)
return account.login
accounts = [
Identity(key=f"mail:{a.login}", payload=a, proxy=ProxyPolicy.sticky()) for a in load_accounts()
]
proxies = ProxyList.parse_lines(
Path("proxies.txt").read_text().splitlines()
) # закрепление — у identity
async with BrowserPool(
PlaywrightDriver(),
config=PoolConfig.accounts(),
flow=MailFlow(),
classifier=mail_errors_to_pool, # ошибки SDK сайта -> что сломалось
state_store=FileStateStore("sessions"), # вход переживает перезапуск процесса
proxy_source=proxies,
) as pool:
async def send(lease):
lease.commit() # дальше письмо могло уйти — эту попытку больше не повторять
await mail_sdk.Client(lease.page).send(message)
# Любой свободный аккаунт; упало до commit из-за вкладки, сессии, прокси или браузера — ещё раз.
await pool.run(send, any_of=accounts, retries=2)
Рабочие примеры лежат в examples/: SDK сайта отдельным слоем, который о пуле не знает, и
приложение, которое соединяет его с пулом.
Драйверы
| Драйвер | Экстра | Изоляция | Состояние сессии | Окна для отладки |
|---|---|---|---|---|
browser_pool.drivers.playwright.PlaywrightDriver |
playwright |
контекст на аккаунт, прокси на контексте | куки и localStorage | Chromium: на лету, окно на вкладку |
browser_pool.drivers.pydoll.PydollDriver |
pydoll (pydoll 2.27 и новее, проверены 2.27 и 3.0) |
контекст на аккаунт, прокси на контексте | куки; профиль на диске | на лету, окно на аккаунт |
Уже запущенные браузеры подключаются через RemoteCDP, профили антидетекта через AdsPowerProvider
(browser_pool.providers). PlaywrightDriver проверен на Chromium. Firefox и WebKit в нём не проверялись: у них нет
CDP, поэтому окна, перехват авторизации прокси и pid работают иначе или не работают.
Свой SDK подключается классом на основе browser_pool.driver.BaseDriver. Обязательны запуск, контекст, вкладка и их
закрытие, остальное по умолчанию отвечает «не умею». Класс объявляет свои возможности, и по ним пул сам выбирает
изоляцию (прокси на контексте, на браузере или у вендора), а синхронному SDK даёт по потоку на браузер.
Публичный API
Поддерживается то, что экспортирует browser_pool, и подпакеты browser_pool.drivers, .providers, .proxies,
.state, .events, .testing, а также контрактные модули driver, provider, flow, hooks, config, errors,
snapshot, geometry. Всё, что начинается с подчёркивания (browser_pool._core), внутреннее и меняется без
предупреждения. Границу проверяет tests/test_public_api.py.
Документация
Сайт собирается из каталога docs/ (uv run poe site); те же страницы читаются и здесь, в репозитории.
- Начало: начало работы (три запускаемых шага на настоящем браузере), основные понятия, первое приложение на шести аккаунтах.
- Задачи: вход, параллельность, прокси, сбои и повторы, ресурсы хоста, отладка окон, наблюдение, тесты.
- Свой код: SessionFlow, свой драйвер, провайдер браузеров.
- Устройство: устройство пула, виды сбоев, границы библиотеки.
- Справочник: конфиг, события, ошибки; справочник API по модулям есть на сайте.
- Примеры, CHANGELOG, разработка.
Лицензия
MIT.
Metadata
Release files for browser-pool 0.1.0a1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| browser_pool-0.1.0a1.tar.gz | 466.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| browser_pool-0.1.0a1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 730.4 kB
Release files / browser_pool-0.1.0a1.tar.gz
| Download URL | browser_pool-0.1.0a1.tar.gz |
|---|---|
| Size | 466.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b9fd0d2b061b7c8c88edde26031aaa1ae6323a1b0370138e6a93753711fd514b
|
|
BLAKE2b-256 checksum How to use checksums |
9e2dd30040f201d79dacc671d484cab703a8c4dbd1de96b68c2e7592c6ca8dec
|
| 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 / browser_pool-0.1.0a1-py3-none-any.whl
| Download URL | browser_pool-0.1.0a1-py3-none-any.whl |
|---|---|
| Size | 264.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4bb4ed3a406e74e5a9751af7057f104682798995237be2c42cf5d23b1ac1c56f
|
|
BLAKE2b-256 checksum How to use checksums |
c7a106341e45cd3fc0000e9e028997133b2040f1ca5e20df20734437aa57126e
|
| 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