s-browserkit 0.0.2__tar.gz → 0.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- s_browserkit-0.0.4/CHANGELOG.md +126 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/PKG-INFO +29 -6
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/README.md +27 -4
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/__init__.py +1 -1
- s_browserkit-0.0.4/browserkit/browser_guard.py +776 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/ports.py +6 -2
- s_browserkit-0.0.4/browserkit/testing.py +104 -0
- s_browserkit-0.0.4/docs/BROWSER_GUARD.md +194 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/pyproject.toml +9 -2
- s_browserkit-0.0.4/tests/test_browser_guard.py +468 -0
- s_browserkit-0.0.4/tests/test_browser_guard_plugin.py +165 -0
- s_browserkit-0.0.2/CHANGELOG.md +0 -52
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/.gitignore +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/LICENSE +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/antibot/__init__.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/antibot/_helpers.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/antibot/cdp.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/antibot/curl_cffi.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/antibot/page_evaluate.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/antibot/warmup_minter.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/browser/__init__.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/browser/_cdp_state.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/browser/_engine.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/browser/camoufox.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/browser/capture_tap.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/browser/geometry.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/browser/launchers.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/browser/nodriver.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/browser/persistent.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/browser/state.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/capabilities.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/proc.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/browserkit/profile_health.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/docs/README.md +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/docs/prove_librarykit_without_browserkit.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/tests/test_capabilities.py +0 -0
- {s_browserkit-0.0.2 → s_browserkit-0.0.4}/tests/test_layering.py +0 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Changelog — s-browserkit
|
|
2
|
+
|
|
3
|
+
Формат: [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/), версии — SemVer.
|
|
4
|
+
|
|
5
|
+
## [0.0.4] — 2026-08-08
|
|
6
|
+
|
|
7
|
+
### Added — `browserkit.browser_guard`: запрет браузера в рабочем пути
|
|
8
|
+
|
|
9
|
+
Страж канона транспорта переехал сюда из `s-librarykit` — В КИТ-ВЛАДЕЛЕЦ ДВЕРЕЙ.
|
|
10
|
+
Это не перекладывание файла: раньше он был слеп ровно там, где заведён.
|
|
11
|
+
|
|
12
|
+
ПО УЛИКЕ. Двери движка живут здесь — пять точек запуска
|
|
13
|
+
(`browser/{launchers,nodriver,camoufox,persistent}.py` + CDP-attach) и фасад
|
|
14
|
+
`capabilities.open_browser`. Пока страж лежал в оркестраторе:
|
|
15
|
+
|
|
16
|
+
- навык, поставивший ТОЛЬКО `s-browserkit` (после разнесения китов это норма),
|
|
17
|
+
стража не получал вовсе;
|
|
18
|
+
- `librarykit` патчил `browserkit`, **не объявляя его зависимостью**. Замерено в
|
|
19
|
+
окружении без браузерного кита: `install_browser_guard()` возвращал ручку с 5
|
|
20
|
+
перехваченными дверями и 18 «пропущенными» — все десять дверей `browserkit`
|
|
21
|
+
уходили в тишину, а прогон навыка оставался ЗЕЛЁНЫМ, ничего не охраняя.
|
|
22
|
+
|
|
23
|
+
Что приехало:
|
|
24
|
+
|
|
25
|
+
- перехват на ДВЕРЯХ ДВИЖКА (`DEFAULT_DOORS`), а не на именах функций навыка:
|
|
26
|
+
переименование и алиас импорта его не обходят — ссылки сверяются по ТОЖДЕСТВУ
|
|
27
|
+
объекта, поэтому под перехватом оказываются и подмодули
|
|
28
|
+
(`browserkit.browser.persistent.PersistentChromiumBackend`), и корень кита
|
|
29
|
+
(`browserkit.open_browser`);
|
|
30
|
+
- разрешение как свойство КОНТЕКСТА вызова (`allow_browser` /
|
|
31
|
+
`browser_is_allowed` / `require_browser_permission`), дефолт «нельзя»;
|
|
32
|
+
- подключение к прогону навыка одной строкой —
|
|
33
|
+
`from browserkit.testing import forbid_real_browser`;
|
|
34
|
+
- статический AST-сканер `scan_source` / `find_browser_launches` — вторая
|
|
35
|
+
половина запрета (видит непокрытый тестами код).
|
|
36
|
+
|
|
37
|
+
### Added — ★ страж не может «подключиться и ослепнуть»
|
|
38
|
+
|
|
39
|
+
Главное, ради чего был переезд. Двери разделены по владельцу (`DoorKind`), и от
|
|
40
|
+
владельца зависит цена их отсутствия:
|
|
41
|
+
|
|
42
|
+
- **свои** (`OWN`, `browserkit.*`) — контракт: едут в одном дистрибутиве со
|
|
43
|
+
стражем. Пропажа своей двери означает разъезд списка с китом, поэтому
|
|
44
|
+
установка падает `BrowserGuardBlind` и снимает уже поставленные патчи
|
|
45
|
+
(полу-стража не остаётся). Отключающего флага нет;
|
|
46
|
+
- **вендорские** (`VENDOR`) и **соседнего кита** (`FOREIGN`, `librarykit.*`) —
|
|
47
|
+
best-effort. Отсутствие ПАКЕТА (`guard.absent`) безвредно: через него браузер
|
|
48
|
+
не поднять. Отсутствие ДВЕРИ при установленном пакете (`guard.blind`) — уже
|
|
49
|
+
слепота: предупреждение `BrowserGuardWarning` и строка в отчёте;
|
|
50
|
+
- `install_browser_guard(require=("librarykit",))` — потребовать чужие двери
|
|
51
|
+
явно: нет пакета или дверь переименована → `BrowserGuardBlind`;
|
|
52
|
+
- `BrowserGuard.describe()` / `.absent` / `.blind` / `.is_blind` /
|
|
53
|
+
`.guarded_packages()` — отчёт «что держу, чего нет, где слеп».
|
|
54
|
+
|
|
55
|
+
Двери `librarykit.*` — НЕ зависимость (импорта оркестратора в ките нет), а
|
|
56
|
+
ранняя ловушка: `librarykit.factory` всё равно упирается в бэкенды этого кита,
|
|
57
|
+
поэтому своих дверей достаточно.
|
|
58
|
+
|
|
59
|
+
ЧЕГО СТРАЖ НЕ ДЕРЖИТ — сказано вслух, а не умолчано. Дверь, уложенная в
|
|
60
|
+
контейнер (`РЕЕСТР = {"camoufox": CamoufoxBackend}`, список, атрибут класса) ДО
|
|
61
|
+
`install_browser_guard()`, перехват обходит: замена уже розданных ссылок идёт по
|
|
62
|
+
`__dict__` модулей, рекурсии по контейнерам нет намеренно. Прямой вызов и алиас
|
|
63
|
+
импорта — держатся. Форма закреплена `xfail(strict=True)` в
|
|
64
|
+
`tests/test_browser_guard.py`: как только обход закроют, XPASS уронит прогон и
|
|
65
|
+
заставит переписать раздел «Граница применимости», а не оставит её протухать в
|
|
66
|
+
доке.
|
|
67
|
+
|
|
68
|
+
Документация — `docs/BROWSER_GUARD.md`. Старые адреса
|
|
69
|
+
(`librarykit.browser_guard`, `librarykit.testing`) остались алиасами САМИХ
|
|
70
|
+
модулей — одной строкой, без второй реализации.
|
|
71
|
+
|
|
72
|
+
## [0.0.3] — 2026-08-04
|
|
73
|
+
|
|
74
|
+
### Changed
|
|
75
|
+
|
|
76
|
+
- Нижняя граница на киты основания поднята до `0.0.2` — версии,
|
|
77
|
+
в архиве которой больше нет конфигурации CI.
|
|
78
|
+
|
|
79
|
+
## [0.0.2] — 2026-08-04
|
|
80
|
+
|
|
81
|
+
### Fixed
|
|
82
|
+
|
|
83
|
+
- Конфигурация CI больше не попадает в опубликованный архив исходников:
|
|
84
|
+
в 0.0.1 туда уезжал `.gitlab-ci.yml` с именем приватной группы GitLab.
|
|
85
|
+
Секретов там нет (публикация идёт через OIDC), но внутренней структуре
|
|
86
|
+
в публичном пакете не место.
|
|
87
|
+
|
|
88
|
+
## [0.0.1] — 2026-08-03
|
|
89
|
+
|
|
90
|
+
Выделение браузерного слоя из `s-librarykit`. Кода не написано
|
|
91
|
+
заново — он ПЕРЕЕХАЛ; по старым путям остались алиасы на те же модули.
|
|
92
|
+
|
|
93
|
+
### Добавлено
|
|
94
|
+
|
|
95
|
+
* **Фасад возможностей** `browserkit.capabilities` — потребитель просит ЦЕЛЬ
|
|
96
|
+
(`Capability.STEALTH_SESSION` / `VISIBLE_LOGIN` / `PERSISTENT_WORK` /
|
|
97
|
+
`STEALTH_REQUEST` / `IN_PAGE_REQUEST` / `TRAFFIC_CAPTURE`), а не движок.
|
|
98
|
+
Соответствие «цель → движок» живёт в одной таблице `_DEFAULT_PLAN` внутри кита;
|
|
99
|
+
выбор — лестница кандидатов (первый установленный выигрывает), отсутствие всех
|
|
100
|
+
→ `CapabilityUnavailable` с рецептом установки.
|
|
101
|
+
* `browserkit.ports` — `Transport` / `SyncTransport` / `BrowserEngineRole`:
|
|
102
|
+
контракты, которые киту нужны снаружи. Структурно совпадают с контрактами
|
|
103
|
+
сетевого слоя (проверено тестом), поэтому транспорты взаимозаменяемы.
|
|
104
|
+
* Ленивый корень (PEP 562): `import browserkit` не тянет ни подпакеты-реализации,
|
|
105
|
+
ни движки — можно спрашивать «умеешь ли ты стелс?», не платя импортом.
|
|
106
|
+
|
|
107
|
+
### Переехало из librarykit (без изменения поведения)
|
|
108
|
+
|
|
109
|
+
* `browser/` — `_engine`, `geometry`, `launchers`, `persistent`, `camoufox`,
|
|
110
|
+
`nodriver`, `capture_tap`, `state`, `_cdp_state`;
|
|
111
|
+
* `antibot/` — `curl_cffi`, `cdp`, `page_evaluate`, `warmup_minter`, `_helpers`;
|
|
112
|
+
* `profile_health.py` — предстартовая проверка профиля и карантин;
|
|
113
|
+
* `proc.py` — запуск подпроцессов без всплывающих консолей.
|
|
114
|
+
|
|
115
|
+
### Известный долг
|
|
116
|
+
|
|
117
|
+
* `browserkit/proc.py` — ДУБЛЬ `librarykit/proc.py`. Настоящий дом слоя — основание
|
|
118
|
+
(`corekit`), перенос отложен, чтобы не драться за файл с параллельным выделением
|
|
119
|
+
`netkit`/`authkit-client`. Дрейф копий ловится тестом
|
|
120
|
+
`tests/test_layering.py::test_proc_layer_has_not_drifted_from_the_orchestrator`.
|
|
121
|
+
* `browserkit/ports.py` — своя копия Protocol'ов транспорта; станет реэкспортом из
|
|
122
|
+
`netkit.contract`, когда сетевой кит будет опубликован.
|
|
123
|
+
* `librarykit/ephemeral.py` (минт без дискового профиля) ОСТАЛСЯ в оркестраторе:
|
|
124
|
+
он тянет `librarykit.session_fingerprint` (инвариант «один egress + один
|
|
125
|
+
профиль»), чей дом — session-слой, а не браузерный. Браузер он поднимает лениво,
|
|
126
|
+
через этот кит, поэтому слои не нарушены.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: s-browserkit
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: Браузерный слой для Python-автоматизации: стелс-сессии, антибот-запросы и capture трафика через единый фасад возможностей, а не имя движка.
|
|
5
5
|
Author: Dmitry
|
|
6
6
|
License: MIT
|
|
@@ -17,7 +17,7 @@ Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
|
|
|
17
17
|
Classifier: Topic :: Software Development :: Libraries
|
|
18
18
|
Requires-Python: >=3.11
|
|
19
19
|
Requires-Dist: httpx>=0.27
|
|
20
|
-
Requires-Dist: s-corekit>=0.0.
|
|
20
|
+
Requires-Dist: s-corekit>=0.0.2
|
|
21
21
|
Provides-Extra: antibot
|
|
22
22
|
Requires-Dist: curl-cffi>=0.7; extra == 'antibot'
|
|
23
23
|
Provides-Extra: browser
|
|
@@ -120,7 +120,28 @@ browserkit.CapabilityUnavailable: Возможность 'stealth_request' не
|
|
|
120
120
|
* `browserkit.antibot` — исполнители HTTP-запроса, ходящие «как браузер»;
|
|
121
121
|
* `browserkit.profile_health` — предстартовая проверка профиля и карантин;
|
|
122
122
|
* `browserkit.proc` — запуск подпроцессов без всплывающих консолей;
|
|
123
|
-
* `browserkit.ports` — Protocol'ы, которых киту не хватает
|
|
123
|
+
* `browserkit.ports` — Protocol'ы, которых киту не хватает снаружи;
|
|
124
|
+
* `browserkit.browser_guard` + `browserkit.testing` — **запрет браузера в рабочем
|
|
125
|
+
пути** (см. ниже).
|
|
126
|
+
|
|
127
|
+
## Запрет браузера в рабочем пути
|
|
128
|
+
|
|
129
|
+
Канон транспорта: браузер поднимается только чтобы сминтить сессию, работа идёт
|
|
130
|
+
прямыми запросами. Кит делает это **конструкцией** — перехватом на собственных
|
|
131
|
+
дверях запуска. Подключение к прогону навыка — одна строка:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
# tests/conftest.py навыка
|
|
135
|
+
from browserkit.testing import forbid_real_browser # noqa: F401
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Страж живёт здесь, а не в оркестраторе, ровно потому, что двери — здесь: страж и
|
|
139
|
+
двери едут в одном дистрибутиве, поэтому «импорт прошёл» = «двери на месте». Он
|
|
140
|
+
обязан честно сказать, если стеречь не может: пропажа СВОЕЙ двери валит
|
|
141
|
+
установку (`BrowserGuardBlind`), а «пакета нет» отделено от «пакет есть, двери
|
|
142
|
+
нет» (`guard.absent` / `guard.blind` / `guard.describe()`).
|
|
143
|
+
|
|
144
|
+
Подробности, боевая установка и границы применимости — `docs/BROWSER_GUARD.md`.
|
|
124
145
|
|
|
125
146
|
## Установка
|
|
126
147
|
|
|
@@ -138,9 +159,11 @@ pip install 's-browserkit[antibot]' # + TLS/JA3-импersonate без бр
|
|
|
138
159
|
## Совместимость
|
|
139
160
|
|
|
140
161
|
Прежние пути (`librarykit.browser.*`, `librarykit.antibot.*`,
|
|
141
|
-
`librarykit.profile_health`)
|
|
142
|
-
модули** (`sys.modules`), а
|
|
143
|
-
`is`-сравнения ведут себя ровно
|
|
162
|
+
`librarykit.profile_health`, `librarykit.browser_guard`, `librarykit.testing`)
|
|
163
|
+
продолжают работать: там оставлены **алиасы на те же модули** (`sys.modules`), а
|
|
164
|
+
не копии. Поэтому `monkeypatch`, `isinstance` и `is`-сравнения ведут себя ровно
|
|
165
|
+
как до переноса, а второй реализации стража, которая через месяц разъедется с
|
|
166
|
+
первой, не существует.
|
|
144
167
|
|
|
145
168
|
## Тесты
|
|
146
169
|
|
|
@@ -86,7 +86,28 @@ browserkit.CapabilityUnavailable: Возможность 'stealth_request' не
|
|
|
86
86
|
* `browserkit.antibot` — исполнители HTTP-запроса, ходящие «как браузер»;
|
|
87
87
|
* `browserkit.profile_health` — предстартовая проверка профиля и карантин;
|
|
88
88
|
* `browserkit.proc` — запуск подпроцессов без всплывающих консолей;
|
|
89
|
-
* `browserkit.ports` — Protocol'ы, которых киту не хватает
|
|
89
|
+
* `browserkit.ports` — Protocol'ы, которых киту не хватает снаружи;
|
|
90
|
+
* `browserkit.browser_guard` + `browserkit.testing` — **запрет браузера в рабочем
|
|
91
|
+
пути** (см. ниже).
|
|
92
|
+
|
|
93
|
+
## Запрет браузера в рабочем пути
|
|
94
|
+
|
|
95
|
+
Канон транспорта: браузер поднимается только чтобы сминтить сессию, работа идёт
|
|
96
|
+
прямыми запросами. Кит делает это **конструкцией** — перехватом на собственных
|
|
97
|
+
дверях запуска. Подключение к прогону навыка — одна строка:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
# tests/conftest.py навыка
|
|
101
|
+
from browserkit.testing import forbid_real_browser # noqa: F401
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Страж живёт здесь, а не в оркестраторе, ровно потому, что двери — здесь: страж и
|
|
105
|
+
двери едут в одном дистрибутиве, поэтому «импорт прошёл» = «двери на месте». Он
|
|
106
|
+
обязан честно сказать, если стеречь не может: пропажа СВОЕЙ двери валит
|
|
107
|
+
установку (`BrowserGuardBlind`), а «пакета нет» отделено от «пакет есть, двери
|
|
108
|
+
нет» (`guard.absent` / `guard.blind` / `guard.describe()`).
|
|
109
|
+
|
|
110
|
+
Подробности, боевая установка и границы применимости — `docs/BROWSER_GUARD.md`.
|
|
90
111
|
|
|
91
112
|
## Установка
|
|
92
113
|
|
|
@@ -104,9 +125,11 @@ pip install 's-browserkit[antibot]' # + TLS/JA3-импersonate без бр
|
|
|
104
125
|
## Совместимость
|
|
105
126
|
|
|
106
127
|
Прежние пути (`librarykit.browser.*`, `librarykit.antibot.*`,
|
|
107
|
-
`librarykit.profile_health`)
|
|
108
|
-
модули** (`sys.modules`), а
|
|
109
|
-
`is`-сравнения ведут себя ровно
|
|
128
|
+
`librarykit.profile_health`, `librarykit.browser_guard`, `librarykit.testing`)
|
|
129
|
+
продолжают работать: там оставлены **алиасы на те же модули** (`sys.modules`), а
|
|
130
|
+
не копии. Поэтому `monkeypatch`, `isinstance` и `is`-сравнения ведут себя ровно
|
|
131
|
+
как до переноса, а второй реализации стража, которая через месяц разъедется с
|
|
132
|
+
первой, не существует.
|
|
110
133
|
|
|
111
134
|
## Тесты
|
|
112
135
|
|