Metadata-Version: 2.4
Name: s-browserkit
Version: 0.0.3
Summary: Браузерный слой для Python-автоматизации: стелс-сессии, антибот-запросы и capture трафика через единый фасад возможностей, а не имя движка.
Author: Dmitry
License: MIT
License-File: LICENSE
Keywords: antibot,automation,browser,cdp,http,playwright,stealth
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27
Requires-Dist: s-corekit>=0.0.2
Provides-Extra: antibot
Requires-Dist: curl-cffi>=0.7; extra == 'antibot'
Provides-Extra: browser
Requires-Dist: playwright>=1.40; extra == 'browser'
Provides-Extra: camoufox
Requires-Dist: camoufox>=0.4; extra == 'camoufox'
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.8; extra == 'dev'
Provides-Extra: nodriver
Requires-Dist: nodriver>=0.50; extra == 'nodriver'
Description-Content-Type: text/markdown

# s-browserkit — браузерный слой китов

Живой браузер, антибот и стелс — одним китом, который ставится **отдельно**.
Чистой API-интеграции (белый REST/GraphQL) он не нужен и больше не навязывается:
`librarykit` без `browserkit` полностью работоспособен.

```
        clikit          adapterkit          ветки-оболочки
             \             /
              \           /
               librarykit                   ОРКЕСТРАТОР (сессии, лимиты, фабрики)
                /        \
        browserkit        …                 СЛОЙ-КИТ (браузер и антибот)
                \        /
                 corekit                    ОСНОВАНИЕ (значения и чистые правила)
```

## Главное: просят ВОЗМОЖНОСТЬ, а не движок

```python
import browserkit

backend = browserkit.open_browser(
    browserkit.Capability.STEALTH_SESSION,   # ЦЕЛЬ, а не «camoufox»
    profile_dir=profile,
)
http = browserkit.make_requester(browserkit.Capability.STEALTH_REQUEST)
```

Соответствие «цель → движок» живёт ровно в одной таблице внутри кита
(`browserkit/capabilities.py`). Anti-detect движок начал палиться — правится одна
строка, **ни один навык не меняется**, потому что ни один навык движок не назвал.

Возможности:

| Capability | Что нужно потребителю |
|---|---|
| `STEALTH_SESSION` | поднять браузер там, где обычный палится antibot'ом |
| `VISIBLE_LOGIN`   | видимое окно: пароль/2FA человек вводит руками |
| `PERSISTENT_WORK` | обычная автоматизация в персистентном профиле |
| `STEALTH_REQUEST` | один HTTP-запрос с браузерным TLS-отпечатком, БЕЗ браузера |
| `IN_PAGE_REQUEST` | запрос изнутри живой страницы (её cookies/TLS/заголовки) |
| `TRAFFIC_CAPTURE` | нормализованный сетевой трафик страницы (реверс скрытого API) |

Диагностика — «чем закрыта каждая цель прямо сейчас»:

Сразу после `pip install s-browserkit` (без единого extra) все цели пусты — это и
есть нормальный ответ, а не поломка:

```python
>>> import browserkit
>>> browserkit.describe_capabilities()
{'stealth_session': None, 'visible_login': None, 'persistent_work': None,
 'stealth_request': None, 'in_page_request': None, 'traffic_capture': None}
```

`None` означает «не установлен ни один исполнитель». Попытка воспользоваться такой
целью даёт внятную ошибку с рецептом установки, а не голый `ModuleNotFoundError`:

```python
>>> browserkit.make_requester(browserkit.Capability.STEALTH_REQUEST)
Traceback (most recent call last):
  ...
browserkit.CapabilityUnavailable: Возможность 'stealth_request' недоступна:
ни один исполнитель не установлен. Поставь один из: `pip install 's-browserkit[antibot]'`.
```

После `pip install 's-browserkit[antibot]'` та же строка вернёт готовый
исполнитель (`CurlCffiTransport`), а `describe_capabilities()['stealth_request']`
станет `'tls_impersonate'` — имя ИСПОЛНИТЕЛЯ цели, не пакета. Какие исполнители
стоят в очереди за каждой целью, видно заранее:

```python
>>> browserkit.capability_plan(browserkit.Capability.STEALTH_SESSION)
('camoufox', 'nodriver', 'cdp')
```

Побеждает первый установленный; порядок переопределяется `set_capability_plan()`.

## Состав

* `browserkit.browser` — лаунчеры (системный Chromium по CDP, персистентный
  контекст), anti-detect / undetected бэкенды, `capture_tap` (нормализованный
  event-tap над любым движком), `state` (storage-state, тёплый вход, детекторы
  протухания), геометрия окна, брони портов;
* `browserkit.antibot` — исполнители HTTP-запроса, ходящие «как браузер»;
* `browserkit.profile_health` — предстартовая проверка профиля и карантин;
* `browserkit.proc` — запуск подпроцессов без всплывающих консолей;
* `browserkit.ports` — Protocol'ы, которых киту не хватает снаружи.

## Установка

```bash
pip install s-browserkit                 # без движков: фасад, антибот-контракты, здоровье профиля
pip install 's-browserkit[browser]'      # + Playwright (CDP-attach, персистентный контекст)
pip install 's-browserkit[camoufox]'     # + anti-detect Firefox   (затем `camoufox fetch`)
pip install 's-browserkit[nodriver]'     # + undetected Chromium
pip install 's-browserkit[antibot]'      # + TLS/JA3-импersonate без браузера
```

`import browserkit` не поднимает браузер и не импортирует ни одного движка:
подпакеты резолвятся лениво (PEP 562), вендоры — ещё позже, внутри бэкендов.

## Совместимость

Прежние пути (`librarykit.browser.*`, `librarykit.antibot.*`,
`librarykit.profile_health`) продолжают работать: там оставлены **алиасы на те же
модули** (`sys.modules`), а не копии. Поэтому `monkeypatch`, `isinstance` и
`is`-сравнения ведут себя ровно как до переноса.

## Тесты

```bash
uv run --no-sync pytest -q          # либо .venv\Scripts\python.exe -m pytest -q
```
