Skip to main content

Non-interactive challenge Interactive challenge

cloudflare-skip

Skip Cloudflare challenges: solve once in a real browser, then reuse the clearance with fast HTTP requests.

PyPI Python License

Quick start

pip install cloudflare-skip
cloudflare-skip https://cl-skip.tn3w.dev
from cloudflare_skip import get

response = get("https://cl-skip.tn3w.dev", params={"q": "x"}, timeout=10)
print(response.status_code, response.text)

get(url, **kwargs) returns a curl_cffi response; keyword arguments (params, headers, cookies, timeout, ...) go to curl_cffi. It raises ChallengeError if Cloudflare still challenges after a solve and TimeoutError if the browser cannot solve within 30s. The CLI prints the body, writes the status to stderr and exits 1 on 4xx/5xx.

Needs Chrome or Chromium and a display (headful; headless gets flagged).

How it works

  1. Request with curl_cffi (Chrome TLS fingerprint) and the cached clearance.
  2. cf-mitigated: challenge → a real browser (nodriver) opens the page.
  3. Interactive Turnstile: once its checkbox renders (detected through the frame's DOM, shadow roots included), Tab focuses it and Space ticks it.
  4. Once cf_clearance exists and the challenge page is gone, cookies + user agent are cached per host in ~/.cache/cloudflare_skip.json and replayed over HTTP.
Run Time
First, browser solve (non-interactive) ~2.9s
First, browser solve (interactive) ~4.3s
Cached, in-process ~0.02-0.1s

Notes

  • The API is synchronous; from async code use await asyncio.to_thread(get, url).

  • A clearance is bound to the user agent and IP of the solving browser: get always sends the browser's user agent, and a proxy passed in kwargs makes the replay fail with ChallengeError. The cache holds session cookies, so it is created with mode 600.

  • Turnstile rejected every CDP mouse click tried (bezier, wind and jitter paths, pressure 0.5, moves during the spinner, click before or after load). Keyboard passes.

  • An earlier cf_clearance is issued before the final redirect and gets rejected, so the solve only finishes when the challenge page itself is gone.

Development

uv run pytest
uv run scripts/record.py <name> [light|dark]   # re-record the header GIFs

site/ is the test page behind https://cl-skip.tn3w.dev (GitHub Pages, deployed by pages.yml), put behind a Cloudflare challenge rule.

scripts/record.py records Chrome via tab capture (getDisplayMedia) → ffmpeg frames → gifski. Needs ffmpeg and gifski.

Metadata

Release files for cloudflare-skip 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cloudflare-skip 1.0.0
File Size Uploaded
cloudflare_skip-1.0.0.tar.gz 9.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cloudflare-skip 1.0.0
File Interpreter ABI Platform
cloudflare_skip-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 19.5 kB

Release files / cloudflare_skip-1.0.0.tar.gz

Download URL cloudflare_skip-1.0.0.tar.gz
Size 9.6 kB
Tags Source
SHA-256 checksum
How to use checksums
94459549f998dfeb5bb1f2831b41b8fe216e66b45385ce7dce23cadf9365e4d8
BLAKE2b-256 checksum
How to use checksums
f36e1530593f447ca5d5f1f7defff512878ea707de59ce880bcd3fb01ffa3984
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release files / cloudflare_skip-1.0.0-py3-none-any.whl

Download URL cloudflare_skip-1.0.0-py3-none-any.whl
Size 9.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8a911c0b6d84a7d5327366ce62a9bc98cacd8620fb11135a6cf253bd64717c6b
BLAKE2b-256 checksum
How to use checksums
f1cf54ef9ed0416024a061da5082bca7b32235dcde42dc154b524e4c51bef51a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page