Metadata-Version: 2.5
Name: patchright-turnstile
Version: 0.1.0
Summary: Solve Cloudflare Turnstile in Patchright by handing the token off to the Peak API instead of clicking the widget.
Project-URL: Source, https://github.com/CircuitSavage/patchright-turnstile
Project-URL: Homepage, https://peak.fo/?utm_source=github&utm_medium=pypi&utm_campaign=packages&utm_content=patchright-turnstile
Project-URL: Documentation, https://peak.fo/docs/turnstile?utm_source=github&utm_medium=pypi&utm_campaign=packages&utm_content=patchright-turnstile
Author: Peak
License: MIT
License-File: LICENSE
Keywords: bypass,captcha,cloudflare,patchright,playwright,solver,turnstile
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.9
Provides-Extra: patchright
Requires-Dist: patchright>=1.40; extra == 'patchright'
Description-Content-Type: text/markdown

<div align="center">

# patchright-turnstile

**Solve Cloudflare Turnstile in a [Patchright](https://github.com/Kaliiiiiiiiii-Vinyzu/patchright-python) page.** Read the sitekey, get a token from Peak, put it back in the widget. One call, async or sync.

<p>
  <img src="https://img.shields.io/badge/python-3.9+-3776AB?style=for-the-badge&logo=python&logoColor=white" alt="Python 3.9+">
  <img src="https://img.shields.io/badge/patchright-async%20%2B%20sync-00A67E?style=for-the-badge" alt="Patchright">
  <img src="https://img.shields.io/badge/license-MIT-007EC7?style=for-the-badge" alt="MIT License">
</p>

</div>

---

Patchright is a patched Playwright that removes the CDP leaks (`Runtime.enable` and friends) detectors look for. That gets you through a lot of bot checks. It does not answer a Turnstile challenge, because the token comes from Cloudflare's risk engine and not from a click. This package hands the `(url, sitekey)` to a solver and writes the returned token back into the page. Your cookies, TLS and session stay in your own browser.

```python
from patchright_turnstile import solve_turnstile

token = await solve_turnstile(page, api_key="pk_your_api_key")
```

## Install

```bash
pip install patchright-turnstile patchright
patchright install chromium
```

The package itself has no runtime dependencies.

## Use it

```python
import asyncio, os
from patchright.async_api import async_playwright
from patchright_turnstile import solve_turnstile

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch_persistent_context(
            "./profile", channel="chrome", headless=False, no_viewport=True
        )
        page = browser.pages[0]
        await page.goto("https://site-with-turnstile.example/login")

        await solve_turnstile(page, os.environ["PEAK_API_KEY"])

        await page.click("button[type=submit]")
        await browser.close()

asyncio.run(main())
```

Sync API:

```python
from patchright_turnstile import solve_turnstile_sync

solve_turnstile_sync(page, os.environ["PEAK_API_KEY"])
```

`solve_turnstile` finds the sitekey (`data-sitekey` attribute or the `challenges.cloudflare.com` iframe), requests a token, fills every `cf-turnstile-response` field, and calls the widget's `data-callback` if the page set one.

## The isolated-context catch

Patchright runs `page.evaluate()` in an isolated JavaScript context by default. In that context `window.yourCallback` does not exist, so a plain Playwright injection script can fill the hidden input and still fail to fire the page's success handler. This package passes `isolated_context=False` for the injection step, so the callback runs in the page's own world. If you inject tokens yourself, do the same:

```python
await page.evaluate("window.onTurnstileOk('TOKEN')", isolated_context=False)
```

## Matching the exit IP

Turnstile scores the IP that submits the token. If your browser goes through a proxy, give the solver the same one:

```python
await solve_turnstile(page, api_key, proxy="http://user:pass@host:port")
```

Leave `proxy` off and the token is minted from a clean pool. That works on many sites; test yours.

## API

`await solve_turnstile(page, api_key=None, proxy=None, sitekey=None, timeout=180.0)` returns the token string.

- `api_key`: Peak key. Falls back to the `PEAK_API_KEY` environment variable.
- `sitekey`: skip DOM detection and use this one.
- `timeout`: seconds to wait for the solver.

`solve_turnstile_sync` takes the same arguments for Patchright's sync API. Failures raise `PeakError`.

## Getting a key

The solver behind this package is [Peak](https://peak.fo/?utm_source=github&utm_medium=readme&utm_campaign=packages&utm_content=patchright-turnstile). Turnstile solves come back in about a second, you pay only for the ones that succeed, and the free tier is enough to wire this up and test it. Peak also handles the Cloudflare 5-second challenge (`task_type: "cloudflare5stask"`); this package covers Turnstile.

<div align="center">

<a href="https://peak.fo/?utm_source=github&utm_medium=readme&utm_campaign=packages&utm_content=patchright-turnstile"><img src="https://img.shields.io/badge/Get_a_key-Peak-FF6B35?style=for-the-badge" alt="Peak"></a>
<br>
<sub><strong>$0.90 per 1,000 Turnstile solves</strong>, down to $0.35 at volume · pay only on success · 1,000 free solves · <a href="https://peak.fo/docs/turnstile?utm_source=github&utm_medium=readme&utm_campaign=packages&utm_content=patchright-turnstile">docs</a></sub>

</div>

## Related

Same pattern for other stacks: [playwright-turnstile](https://github.com/CircuitSavage/playwright-turnstile) · [selenium-turnstile](https://github.com/CircuitSavage/selenium-turnstile) · [nodriver-turnstile](https://github.com/CircuitSavage/nodriver-turnstile) · [camoufox-turnstile](https://github.com/CircuitSavage/camoufox-turnstile) · [botasaurus-turnstile](https://github.com/CircuitSavage/botasaurus-turnstile) · [pydoll-turnstile](https://github.com/CircuitSavage/pydoll-turnstile) · [browser-use-turnstile](https://github.com/CircuitSavage/browser-use-turnstile) · [crawlee-turnstile](https://github.com/CircuitSavage/crawlee-turnstile). Full list in [awesome-turnstile-solvers](https://github.com/CircuitSavage/awesome-turnstile-solvers).

## Notes

Use this on sites and accounts you're allowed to automate. Respect each target's Terms of Service and `robots.txt`. It is meant for automation, testing and public-data scraping, not credential stuffing or abuse. Not affiliated with Cloudflare or the Patchright project.

## License

MIT
