feature!: параметр user_agent убран, UA всегда родной; docs/Usage.md

- user_agent в запросе → 422 с подсказкой брать UA из ответа: UA, отличный от реального
  Chrome, расходится с userAgentData и движком, Cloudflare такой браузер не пропускает
  (замер: родной 3/3, Chrome 147 и Windows — 0) (#87)
- профиль хранит только отпечаток (экран, DPR), UA не подменяется (#89)
- docs/Usage.md: практики для клиентов API — тот же UA и прокси, что у браузера, сессии,
  cookies, ошибки и повторы, таймауты, пример на httpx
- README, docs/API.md, docs/Introduction.md; тесты под новый контракт

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
protokeyandClaude Opus 5.5 committed 2026-10-13 18:19:08 +04:00
1 parent 0ae5b0c83f
commit fe509c25c3
11 files changed
+202 -125

No files matched your search

+7 -8
View File
@@ -54,7 +54,6 @@ def client(monkeypatch, tmp_path):
monkeypatch.setattr(main, "AsyncStealthySession", FakeSession)
monkeypatch.setattr(main, "USER_DATA_ROOT", tmp_path)
monkeypatch.setattr(main, "_slots", asyncio.Semaphore(2))
monkeypatch.setattr(profile, "chrome_major", lambda: "155")
return TestClient(main.app)
@@ -168,18 +167,18 @@ def test_bad_session_cookie_gets_new_session(client, monkeypatch, tmp_path, bad)
assert [p.name for p in tmp_path.iterdir()] == [sid]
def test_user_agent_set_once_per_profile(client, monkeypatch):
monkeypatch.setattr(actions, "execute", fake_execute([]))
post(client, user_agent="First/1")
post(client, user_agent="Second/2")
assert [c["useragent"] for c in FakeSession.calls] == ["First/1", "First/1"]
def test_user_agent_param_rejected(client):
resp = post(client, user_agent="First/1")
assert resp.status_code == 422
assert "take user_agent from the response" in resp.text
assert FakeSession.calls == []
def test_generated_fingerprint_passed_to_browser(client, monkeypatch):
def test_fingerprint_passed_to_browser_and_ua_untouched(client, monkeypatch):
monkeypatch.setattr(actions, "execute", fake_execute([]))
post(client)
kwargs = FakeSession.calls[0]
assert kwargs["useragent"] == profile.UA_TEMPLATE.format(major="155")
assert "useragent" not in kwargs
assert set(kwargs["additional_args"]) == {"screen", "device_scale_factor"}