4 Commits
Author SHA1 Message Date
retoorandClaude Sonnet 5 423170e1bb Fail fast with a clear error on event loop reuse instead of hanging
A Stealthii instance binds its lock, browser, and contexts to whichever
asyncio event loop is running the first time it is used. Using it again
from a different loop previously hung forever (the lock/semaphore/
Playwright transport are all bound to the dead first loop and never
wake the waiting coroutine). Detected in rsearch's test suite, where
pytest-asyncio's default per-test-function event loop broke the
module-level Stealthii singleton shared across tests.

Now raises StealthUnavailableError immediately with an actionable
message. README documents the constraint and the pytest-asyncio config
fix (asyncio_default_test_loop_scope = session).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0116i7dYLNZTXNR7Lqf439bV
2026-09-10 01:58:55 +02:00
retoorandClaude Sonnet 5 23cdad8966 Add PERFORMANCE.md and link it plus STEALTH_PATCHES.md from README
Documents measured single-request and concurrency (5x/20x) overhead of
the context.request fast path against aiohttp: ~15-20ms/request steady
state, no serialization bottleneck through the shared context up to at
least 20 concurrent requests, browser launch (~1s) paid once at
startup.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0116i7dYLNZTXNR7Lqf439bV
2026-09-09 14:27:44 +02:00
retoorandClaude Sonnet 5 86c3a95cb8 Add PUT/PATCH/DELETE/HEAD, full aiohttp/httpx param parity, screenshots,
async-with tab claiming, and full documentation

- get/post/put/patch/delete/head now accept the same request shape as
  aiohttp/httpx: data/json/files/cookies/auth/allow_redirects/
  follow_redirects/max_redirects, plus the existing session= for named
  cookie-persisting contexts.
- screenshot(url, path=None) captures a PNG, saved to disk or returned
  as base64.
- `async with stealth as page` claims a tab directly, task-safe for
  concurrent use on one shared instance (keyed off asyncio.current_task,
  not instance state).
- Strip all docstrings/comments from the source (author line excepted),
  per house style.
- README.md rewritten as the complete documentation: rationale, JA3/JA4
  comparison, dependencies, construction/laziness/lifetime, every method
  with examples, named sessions, configuration, error handling, testing.
- STEALTH_PATCHES.md: a literal, patch-by-patch account of every launch
  argument and JS patch applied, with rationale and verification method.
- 20 new tests: full HTTP-method coverage, cookies, auth, multipart,
  download, render, screenshot, named-session isolation, retry/error
  paths, and guaranteed page/context cleanup under exception.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0116i7dYLNZTXNR7Lqf439bV
2026-09-09 13:56:28 +02:00
retoorandClaude Sonnet 5 a3bb7639d2 Initial version of stealthii
An aiohttp/httpx-shaped async HTTP client backed by a single, persistent,
stealth-patched Chromium instance via Playwright. get/post/put/patch/
delete/head/download use context.request (real Chrome TLS/HTTP2
fingerprint, no tab needed); render()/screenshot()/page() escalate to
full JS-executing page rendering for targets that need a JS challenge
solved. Supports named sessions for cookie persistence/warm-up, and
`async with stealth as page` to claim a tab directly, task-safe for
concurrent use on one shared instance. Context/browser recycling bounds
cookie and on-disk cache growth in a long-lived process.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0116i7dYLNZTXNR7Lqf439bV
2026-09-09 13:49:07 +02:00