Skip to main content

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 Google Chrome browser through Patchright (a stealth-patched Playwright), works through 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.

On the Cloudflare bypass: CurlWright drives real Google Chrome (channel="chrome") with Patchright's protocol-level stealth (navigator.webdriver hidden, no CDP Runtime.enable leak), so it transparently handles passive Cloudflare (CDN) and has a real shot at managed / "I'm Under Attack" / non-interactive challenges.

Run headed for the best results. The default (no --headless/--no-gui) launches a visible Chrome with a genuine, consistent fingerprint — the strongest stealth. --no-gui/--headless use Chrome's new headless for servers/CI, but the browser still advertises HeadlessChrome in its user agent, which strict bot-management may flag; on a VPS, run under xvfb for headed-quality stealth.

Hardened managed challenges → --engine nodriver. The default Patchright engine clears passive CF and Turnstile, but the toughest "Just a moment" managed challenges fingerprint Playwright's automation-protocol signature (Runtime.enable/Target.setAutoAttach) and stall at HTTP 403. Pass --engine nodriver to drive Chrome over a plain CDP WebSocket (no such signature), which clears those interstitials. nodriver requires headed mode (omit --headless); headless is detected just like Patchright. A flagged/datacenter IP still gets blocked regardless of engine — use a residential proxy via curl -x.

It is not a guaranteed solver for every hardened anti-bot setup — some still require a paid CAPTCHA service, which CurlWright does not bundle. It detects the challenge type and progresses what it can; when a page cannot be cleared it fails loudly with diagnostics (exit code 10).

Key Features

Feature Description
Browser-backed curl execution Parse a curl command and execute it through real Chrome (Patchright)
Cloudflare challenge handling Detect and progress browser-side verification; clears passive CF and many managed/non-interactive challenges (not a guaranteed interactive-Turnstile solver)
Turnstile detection Detects Turnstile flows and attempts non-interactive resolution
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

pip install curlwright
# CurlWright drives your system Google Chrome (channel="chrome").
# If you do not have Chrome installed, fetch a Chrome build for Patchright:
patchright install chrome

Requires Google Chrome on the host (the default channel="chrome"). On a server/VPS, install Chrome (or run patchright install chrome); headless runs use Chrome's new headless mode.

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]"
patchright install chrome   # only if system Chrome is absent

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
--engine Browser engine: patchright (default) or nodriver (clears hardened managed challenges; headed only)
--headless Run Chromium headless
--fast Skip the stealth warm-up for non-protected targets (~20% faster; less stealthy, challenge path unchanged)
--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
--import-cookies Load cookies from a JSON file into the jar before the request
--export-cookies Write the captured session cookies to a JSON file after the request
--clear-cookies Clear the persistent cookie jar before the request
--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)
import asyncio

from curlwright import RequestExecutor
from curlwright.utils import CookieManager


async def main() -> None:
    cookies = CookieManager("cookies.json")
    executor = RequestExecutor(headless=True, cookie_file="cookies.json")
    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

Metadata

Release files for curlwright 3.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 curlwright 3.0.0
File Size Uploaded
curlwright-3.0.0.tar.gz 75.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for curlwright 3.0.0
File Interpreter ABI Platform
curlwright-3.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 131.7 kB

Release files / curlwright-3.0.0.tar.gz

Download URL curlwright-3.0.0.tar.gz
Size 75.0 kB
Tags Source
SHA-256 checksum
How to use checksums
9a546a22ec4b607f97a0f86d8bb9cc0e34d053bc23d143ba9c3875431c08a792
BLAKE2b-256 checksum
How to use checksums
b13837d9bd85c12a356e9f13027f70c60af530620a7e9ebaddd84380d9c320c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jun 28, 2026.

Transparency log

Release files / curlwright-3.0.0-py3-none-any.whl

Download URL curlwright-3.0.0-py3-none-any.whl
Size 56.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f74a31b79a3f61829c77121f00f7a4d69267ef7ba250924845c754c77c8dc683
BLAKE2b-256 checksum
How to use checksums
29733fbf18c17de4a6b4afc932227040738eeeb97cb5784f68de583313b9ce51
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jun 28, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

3.0.0 This release

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.0.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