Skip to main content

Cloudflare bypass tool using Playwright for curl requests

Project description

CurlWright

CurlWright

Execute curl requests through a real Playwright browser when anti-bot protection gets in the way

PyPI Version Python Versions License CI Status Coverage

GitHub Stars GitHub Issues Buy Me a Coffee


Overview

CurlWright is a Python tool that takes a curl command, opens a real Chromium browser through Playwright, resolves Cloudflare and similar browser-side friction, and returns the final HTTP response in a form that still feels close to curl-driven workflows.

It is useful when a plain HTTP client is not enough because the target requires browser execution, JavaScript, cookies, challenge handling, or a persisted trusted session.

Key Features

Feature Description
Browser-backed curl execution Parse a curl command and execute it through Playwright
Cloudflare challenge handling Detect and progress browser-side verification flows
Turnstile support Includes dedicated handling for Turnstile-style flows
Trusted session reuse Persist per-domain trust state and cookies between runs
JSON and SARIF outputs Machine-readable output for automation and CI/security tooling
Headless and server mode Works in local desktop mode or with --no-gui in CI/VPS environments
Python library mode Use as a CLI or from Python code
Clean layered architecture Explicit domain, application, infrastructure, and interfaces layers

Supported curl Inputs

Methods       -X/--request, -I/--head, -G/--get
Headers       -H/--header
Body          -d/--data, --data-raw, --data-binary, --data-urlencode
Cookies       -b/--cookie
Auth          -u/--user
Network       -x/--proxy, -L/--location, -k/--insecure, --max-time
Input Forms   Direct command (-c) or file (-f)

Installation

From PyPI (Recommended)

pip install curlwright
python -m playwright install chromium

From Source

git clone https://github.com/seifreed/Curlwright.git
cd Curlwright
python3 -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
pip install -e ".[dev]"
python -m playwright install chromium

Quick Start

# Execute a curl command directly
curlwright -c "curl https://example.com"

# Read the curl command from a file
curlwright -f request.txt

# Emit structured JSON for automation
curlwright -f request.txt --json-output

Usage

Command Line Interface

# Basic request
curlwright -c "curl https://httpbin.org/get"

# Save the response body to a file
curlwright -f request.txt -o response.html

# Server/CI mode
curlwright -f request.txt --no-gui --json-output

# Persist diagnostics for failures
curlwright -f request.txt --artifact-dir .artifacts/run-1 --sarif-output report.sarif

# Increase retries and timeout
curlwright -c "curl https://target.example" --timeout 60 --retries 5 --delay 3

Available Options

Option Description
-c, --curl Curl command to execute
-f, --file File containing the curl command
--headless Run Chromium headless
--no-gui Server-oriented mode without display requirements
--user-agent Override the browser user agent
--timeout Request timeout in seconds
--cookie-file Override cookie persistence path
--state-file Override trusted-session state path
--artifact-dir Directory for diagnostics, screenshots, HTML and logs
--profile-dir Override the persistent Chromium profile directory
--no-persist-cookies Disable automatic cookie load/save
--bypass-attempts Challenge-resolution attempts per request
--retries Retry count after failures
--delay Delay between retries
-o, --output Save the rendered response output to a file
-v, --verbose Print a runtime execution summary
--json-output Emit the stable JSON contract
--sarif-output Write a SARIF 2.1.0 report

Output Contracts

--json-output emits a stable machine-readable structure:

{
  "schema_version": 1,
  "kind": "curlwright-result",
  "ok": true,
  "exit_code": 0,
  "response": {
    "status": 200,
    "url": "https://example.com/",
    "headers": {},
    "body": "..."
  },
  "meta": {}
}

Failure JSON includes error, error_type, exit_code, and for bypass failures also artifact_dir plus an assessment block.


Python Library

Basic Usage

import asyncio

from curlwright import RequestExecutor


async def main() -> None:
    executor = RequestExecutor(headless=True, timeout=30)
    result = await executor.execute('curl -H "Accept: application/json" https://httpbin.org/get')

    print(result["status"])
    print(result["url"])
    print(result["body"][:120])

    await executor.close()


asyncio.run(main())

Parse curl Before Execution

from curlwright import CurlParser

parser = CurlParser()
request = parser.parse('curl -X POST -H "Content-Type: application/json" https://api.example.com')

print(request.method)
print(request.url)
print(request.headers)

Cookie Persistence

import asyncio

from curlwright import RequestExecutor
from curlwright.utils import CookieManager


async def main() -> None:
    cookies = CookieManager("cookies.pkl")
    executor = RequestExecutor(headless=True, cookie_file="cookies.pkl")
    result = await executor.execute("curl https://example.com")
    print(result["status"])
    await executor.close()


asyncio.run(main())

Examples

API Request Through A Browser Session

curlwright -c 'curl -H "Authorization: Bearer TOKEN" https://api.example.com/data' --json-output

Request File

Create request.txt:

curl -X GET \
  -H "Accept: application/json" \
  -H "User-Agent: Analyst/1.0" \
  -b "session=abc123" \
  https://protected.example.com/api/data

Run it:

curlwright -f request.txt -o response.json

CI-Friendly Execution

mkdir -p .artifacts/job-1

curlwright \
  -f request.txt \
  --no-gui \
  --json-output \
  --sarif-output .artifacts/job-1/curlwright.sarif \
  --artifact-dir .artifacts/job-1 \
  --state-file .artifacts/job-1/state.json \
  --cookie-file .artifacts/job-1/cookies.pkl \
  > .artifacts/job-1/result.json

Headless Retry-Tuned Request

curlwright -c "curl https://target.example" --headless --timeout 90 --retries 5 --delay 2

Architecture

The active codebase follows an explicit layered structure:

curlwright/
  domain/           Pure models, policies and ports
  application/      Use cases and orchestration
  infrastructure/   Playwright, persistence and parser adapters
  interfaces/       CLI, JSON and SARIF presenters
  bootstrap.py      Composition root

This separation keeps browser automation and heuristics in infrastructure while the policy and use-case flow stay isolated from Playwright details.


Requirements

  • Python >=3.13,<3.15
  • Playwright Chromium installed via python -m playwright install chromium
  • See pyproject.toml for the full package metadata and dependency declarations

Contributing

Contributions are welcome. If you want to change behavior, add support for more curl flags, or improve challenge handling, open an issue or send a pull request.

  1. Fork the repository
  2. Create your branch: git checkout -b feature/my-change
  3. Run the test suite
  4. Commit your changes
  5. Push the branch
  6. Open a pull request

Support the Project

If CurlWright is useful in your workflows, you can support the project here:

Buy Me A Coffee

License

This project is licensed under the MIT License. See LICENSE for details.

Attribution


Built for browser-backed automation and resilient protected-request workflows

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

curlwright-2.0.1.tar.gz (65.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

curlwright-2.0.1-py3-none-any.whl (49.7 kB view details)

Uploaded Python 3

File details

Details for the file curlwright-2.0.1.tar.gz.

File metadata

  • Download URL: curlwright-2.0.1.tar.gz
  • Upload date:
  • Size: 65.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for curlwright-2.0.1.tar.gz
Algorithm Hash digest
SHA256 76e74574958cca5275e34a5b031a4547b53a9019e9949ac52d3a46f029fc782f
MD5 d84758753e4f1f989eef9cd194cab6d8
BLAKE2b-256 a3e6ed419cc6d96ed55de94c353933f2e902a64096bd07ac9eb27e492bc7ec78

See more details on using hashes here.

Provenance

The following attestation bundles were made for curlwright-2.0.1.tar.gz:

Publisher: publish.yml on seifreed/Curlwright

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file curlwright-2.0.1-py3-none-any.whl.

File metadata

  • Download URL: curlwright-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 49.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for curlwright-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b4888a0305b090cd98c77c1cb52e2f21805f6c480e70f48f695026ad84f66202
MD5 95e6a1a02df055e33074066eac8d8020
BLAKE2b-256 7221bb58250f1cd01a66aa6e070a01091ec654c0f0f9a74c3df311109d612591

See more details on using hashes here.

Provenance

The following attestation bundles were made for curlwright-2.0.1-py3-none-any.whl:

Publisher: publish.yml on seifreed/Curlwright

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page