patchright-turnstile
Solve Cloudflare Turnstile in a Patchright page. Read the sitekey, get a token from Peak, put it back in the widget. One call, async or sync.
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.
from patchright_turnstile import solve_turnstile
token = await solve_turnstile(page, api_key="pk_your_api_key")
Install
pip install patchright-turnstile patchright
patchright install chromium
The package itself has no runtime dependencies.
Use it
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:
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:
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:
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 thePEAK_API_KEYenvironment 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. 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.
$0.90 per 1,000 Turnstile solves, down to $0.35 at volume · pay only on success · 1,000 free solves · docs
Related
Same pattern for other stacks: playwright-turnstile · selenium-turnstile · nodriver-turnstile · camoufox-turnstile · botasaurus-turnstile · pydoll-turnstile · browser-use-turnstile · crawlee-turnstile. Full list in 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
Metadata
Release files for patchright-turnstile 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| patchright_turnstile-0.1.0.tar.gz | 9.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| patchright_turnstile-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.0 kB
Release files / patchright_turnstile-0.1.0.tar.gz
| Download URL | patchright_turnstile-0.1.0.tar.gz |
|---|---|
| Size | 9.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2d0e45f72f0e81d59b1bbb9c63e4c12093435191876239f6c487a8116e89d565
|
|
BLAKE2b-256 checksum How to use checksums |
f2e44c953859ee4ff2da9a80280dbd38faab8c61132127c037444830c36df850
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.0
|
Release files / patchright_turnstile-0.1.0-py3-none-any.whl
| Download URL | patchright_turnstile-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ccbef1dbd70d2abd761ce898550193c7aa62081c6873f81a963a6bac6c1206ef
|
|
BLAKE2b-256 checksum How to use checksums |
7645e402d41da2e65c1310100e6671c6e9eedd2b3c29271b2ef3ef2577d1ef91
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.0
|
Security for patchright-turnstile 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.