Drop-in curl replacement with automatic anti-bot bypass
Project description
recurl-cli
Python's missing curl. Drop-in HTTP client with automatic anti-bot bypass for Python developers, data scientists, and web scrapers.
What is recurl?
recurl is a smart drop-in replacement for curl that transparently handles bot detection and anti-bot protections used by modern websites. It runs real curl under the hood, detects when a request is blocked (403, captcha, Cloudflare challenge), and automatically escalates through browser impersonation and headless Chromium rendering to get the response you need.
Same curl syntax. No code changes. It just works.
# Works even on Cloudflare-protected sites
python -m recurl https://protected-site.com/api/data
Why Python developers need recurl
If you've ever written Python scripts for web scraping or API access, you've hit these walls:
requests.get()returns 403 Forbidden on protected sitesurllibgets blocked by TLS fingerprinting- You end up installing Selenium, Playwright, or Puppeteer just to fetch a single page
- Headless browser setup is heavy, slow, and overkill for simple requests
recurl solves this by being a curl replacement with built-in escalation:
- First attempt: Standard curl request (fast, low overhead)
- If blocked: Retries with browser TLS fingerprint impersonation
- Still blocked: Launches headless Chromium, solves JS challenges, extracts cookies, replays the request
No Python dependencies for browser automation. No heavy browser setup. Just install and use.
Installation
pip (recommended)
pip install recurl-cli
Other package managers
| Platform | Command |
|---|---|
| npm | npm install -g recurl-cli |
| Homebrew | brew tap neul-labs/tap && brew install recurl |
| Cargo | cargo install recurl |
| Scoop | scoop install recurl |
See the full installation guide for platform-specific instructions.
Quick Start
# Use as a Python module
python -m recurl https://api.example.com/data
# Pass through all curl flags
python -m recurl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' https://api.example.com
# Force JS rendering for heavily protected sites
python -m recurl --recurl-js https://cloudflare-protected-site.com
# Debug mode to see escalation steps
python -m recurl --recurl-debug https://example.com
Python API (coming soon)
from recurl import fetch
# Simple fetch that handles anti-bot protections automatically
response = fetch("https://protected-site.com")
print(response.text)
Supported Anti-Bot Services
recurl automatically detects and bypasses protection from:
| Service | Detection | Bypass |
|---|---|---|
| Cloudflare | Bot Management, Turnstile, JS Challenge | ✓ |
| Akamai Bot Manager | Behavioral analysis | ✓ |
| PerimeterX / HUMAN | Client-side fingerprinting | ✓ |
| DataDome | Bot Protection | ✓ |
| Imperva / Incapsula | Challenge pages | ✓ |
| Kasada | Bot Mitigation | ✓ |
| AWS WAF Bot Control | Request analysis | ✓ |
| Shape / F5 | Bot Defense | ✓ |
| hCaptcha | Challenge widget | ✓ |
| reCAPTCHA | Challenge widget | ✓ |
Platform Support
| Platform | Architecture | Impersonation | JS Preflight |
|---|---|---|---|
| Linux | x86_64 | ✓ | ✓ |
| Linux | aarch64 | ✓ | ✓ |
| macOS | Apple Silicon | ✓ | ✓ |
| macOS | Intel | ✓ | ✓ |
| Windows | x86_64 | — | ✓ |
CLI Reference
recurl-specific flags
| Flag | Description |
|---|---|
--recurl-strict |
Disable fallback, pure curl passthrough |
--recurl-impersonate <profile> |
Force TLS fingerprint profile (chrome, firefox, safari) |
--recurl-js |
Force JS preflight (skip straight to Chromium) |
--recurl-js-rendered |
Return rendered DOM instead of raw response |
--recurl-js-wait <selector> |
Wait for CSS selector before capturing |
--recurl-js-timeout <ms> |
JS preflight timeout (default: 30000) |
--recurl-debug |
Show diagnostic output and escalation steps |
All standard curl flags work as expected.
Use Cases for Python Developers
- Web scraping - Extract data from protected sites without Selenium/Playwright overhead
- Data pipelines - Reliable HTTP requests in Airflow, Luigi, or cron jobs
- API integration - Test and call APIs behind bot protection
- Research & analytics - Fetch pricing, inventory, or public datasets
- CI/CD - Reliable HTTP calls in GitHub Actions, GitLab CI, Jenkins
- Shell scripting from Python - Use
subprocess.run(["recurl", ...])for guaranteed delivery
How It Works
recurl receives request
|
+---> curl_engine (real curl binary)
| |
| +---> Success? Return response immediately
| |
| +---> Blocked? (403, 429, captcha, challenge page)
| |
| +---> Retry with impersonation (browser TLS fingerprint)
| | |
| | +---> Success? Return response
| | |
| | +---> Still blocked?
| | |
| | +---> JS preflight (headless Chromium)
| | |
| | +---> Solve challenge, extract cookies
| | |
| | +---> Replay request with cookies
| | |
| | +---> Return final response
|
+---> Return result to user
The user sees only the final successful response.
Configuration
Environment Variables
| Variable | Description |
|---|---|
RECURL_STRICT=1 |
Same as --recurl-strict |
RECURL_DEBUG=1 |
Enable debug output |
RECURL_DAEMON_IDLE_MS |
Daemon idle timeout (default: 60000) |
Daemon Mode
The optional recurld daemon keeps Chromium warm for sub-second responses:
# Start daemon
recurld start
# Check status
recurld status
# Stop daemon
recurld stop
Links
- Main Repository: github.com/neul-labs/recurl
- Documentation: docs.neullabs.com/recurl
- Issues: github.com/neul-labs/recurl/issues
- License: MIT
Keywords
Python HTTP client, curl replacement, web scraping Python, anti-bot bypass, Cloudflare bypass Python, headless browser Python, TLS fingerprint spoofing, bot detection evasion, requests alternative, urllib replacement, Python CLI tool, data extraction, API client Python, web crawler Python, Chromium automation Python
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file recurl_cli-0.1.2.tar.gz.
File metadata
- Download URL: recurl_cli-0.1.2.tar.gz
- Upload date:
- Size: 6.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
42bb7f4747c03b24c9d9f30a0e18313fef47c1116cda7ca6916c08e747abd509
|
|
| MD5 |
ee545de93a33f41d33fa5af5c9e10844
|
|
| BLAKE2b-256 |
c0b9cb248c67cb348191a15def468835f6a3007cb68c486198982b4f19bea1f5
|
File details
Details for the file recurl_cli-0.1.2-py3-none-any.whl.
File metadata
- Download URL: recurl_cli-0.1.2-py3-none-any.whl
- Upload date:
- Size: 3.4 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bcdb766865b5f2e63eb06e296a37cc3061378181a876450222e74c78379d5dc0
|
|
| MD5 |
362542cfe9c9d4bf9551e69766c19b90
|
|
| BLAKE2b-256 |
206c774627367c1a303790d0826b331b88837f0e07a85eb7e41da93e0761deed
|