Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
9cbe588
adding all requests test
wuqunfei Jan 29, 2026
dab008a
adding all the tests for target version
wuqunfei Jan 29, 2026
608d924
replace the import only
wuqunfei Jan 29, 2026
c3ac4c1
fix the until issues.
wuqunfei Jan 29, 2026
d123189
create empty project branch
wuqunfei Jan 29, 2026
f0ce123
Add CLAUD.md project specification for RequestX
claude Jan 29, 2026
6019a02
Add comprehensive PyO3 best practices and performance rules to CLAUD.md
claude Jan 29, 2026
fa6c6f3
Update JSON processing to use sonic-rs for SIMD acceleration
claude Jan 29, 2026
50435ee
Add core dependencies with pyo3, pyo3-async-runtimes, reqwest
claude Jan 29, 2026
1bc0e9b
Update CLAUD.md with actual Cargo.toml library versions
claude Jan 29, 2026
f8891c3
Simplify CLAUD.md with iterative development strategy
claude Jan 29, 2026
2d0b349
Revert "Simplify CLAUD.md with iterative development strategy"
claude Jan 29, 2026
e56adfc
Streamline CLAUD.md with cleaner format
claude Jan 29, 2026
75250f7
Implement RequestX core HTTP client in Rust
claude Jan 29, 2026
6e7cb47
Add MockTransport, Auth, event hooks, and utils module
claude Jan 29, 2026
bc2ce97
Add multipart file upload support and various fixes
claude Jan 29, 2026
340f761
Add stream property to Request and SyncByteStream.from_data
claude Jan 29, 2026
0eb94af
push status into 809 successfully
wuqunfei Jan 29, 2026
619913b
into 927 pass
wuqunfei Jan 30, 2026
9d3d29c
adding over 1014 test
wuqunfei Jan 30, 2026
26ec31a
1066 pass
wuqunfei Jan 30, 2026
9768956
1200 test cases successfully
wuqunfei Jan 31, 2026
6ac3a84
1295 issues was fixed
wuqunfei Jan 31, 2026
81b2eb0
> 1300 use cases
wuqunfei Jan 31, 2026
1cd8daa
over 1300
wuqunfei Jan 31, 2026
d7ad09d
> 1300 cases
wuqunfei Jan 31, 2026
ff7811f
adding status
wuqunfei Feb 1, 2026
74a8892
53 failed version
wuqunfei Feb 1, 2026
d99c7be
48 left
wuqunfei Feb 1, 2026
df61773
fixing the CLAUDE md
wuqunfei Feb 1, 2026
a0edf8a
adding files
wuqunfei Feb 1, 2026
f114377
only 34 unit test failed
wuqunfei Feb 2, 2026
a93de2b
Adding Claude md update
wuqunfei Feb 2, 2026
cea346e
32 unit test failed
wuqunfei Feb 3, 2026
316c868
fixing url issues
wuqunfei Feb 3, 2026
98dc7d4
fix into 22 left
wuqunfei Feb 3, 2026
781313e
adding commit
wuqunfei Feb 3, 2026
f6217c4
adding updated status in claude
wuqunfei Feb 3, 2026
86ff653
fixing the heade issue
wuqunfei Feb 3, 2026
4231e25
adding files
wuqunfei Feb 4, 2026
b9850cb
Add non-seekable file detection for chunked Transfer-Encoding in mult…
wuqunfei Feb 4, 2026
fb6054d
Fix header case preservation, Host ordering, and Client default_encod…
wuqunfei Feb 4, 2026
65e4e9b
Widen verify parameter type in top-level API functions to accept SSLC…
wuqunfei Feb 4, 2026
15108e4
Add Python-level pool semaphore for AsyncClient pool timeout support
wuqunfei Feb 4, 2026
a03ab49
Fix stream() method to route through custom transports
wuqunfei Feb 4, 2026
5986a41
Fix DigestAuth cnonce format for RFC 7616 compliance
wuqunfei Feb 4, 2026
89460e9
Refactor: split Python monolith and deduplicate Rust/Python code
wuqunfei Feb 4, 2026
1dcae2e
Refactor: move business logic from Python to Rust (Phases 1-3)
wuqunfei Feb 5, 2026
07f008b
Refactor: deduplicate Client/AsyncClient request building logic
wuqunfei Feb 5, 2026
25c0420
fix python format
wuqunfei Feb 5, 2026
0921d83
Refactor: replace deprecated PyO3 downcast() with cast()
wuqunfei Feb 5, 2026
300bd6e
Fix all cargo clippy warnings for strict mode compliance
wuqunfei Feb 5, 2026
96eeb84
Adding performance tests for sync and async benchmarks.
wuqunfei Feb 5, 2026
cca6bc9
update 2 concurrency for http client
wuqunfei Feb 5, 2026
85df773
clean the examples
wuqunfei Feb 5, 2026
a02d086
update version
wuqunfei Feb 5, 2026
59c9547
Add comprehensive performance benchmarks with concurrency comparison
wuqunfei Feb 5, 2026
7dafe96
Add comprehensive business impact analysis document
wuqunfei Feb 5, 2026
f14c613
fixing the issues
wuqunfei Feb 5, 2026
05fc644
format files
wuqunfei Feb 6, 2026
3adff34
fixing test python folder
wuqunfei Feb 6, 2026
9457ed0
fix the ci of the test
wuqunfei Feb 6, 2026
6236996
fixing the version issue
wuqunfei Feb 6, 2026
e38037f
chore: bump version to 1.0.10
wuqunfei Feb 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ jobs:
run: uv run maturin develop

- name: Run Python tests
run: uv run pytest tests/ -v
run: uv run pytest tests_requestx/ -v

# ===========================================================================
# GitHub Release
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,4 @@ jobs:
run: uv run maturin develop

- name: Run Python tests
run: uv run pytest tests/ -v
run: uv run pytest tests_requestx/ -v
376 changes: 194 additions & 182 deletions CLAUDE.md

Large diffs are not rendered by default.

22 changes: 21 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "requestx"
version = "1.0.8"
version = "1.0.10"
edition = "2021"
description = "High-performance Python HTTP client based on reqwest"
license = "MIT"
Expand Down Expand Up @@ -42,6 +42,7 @@ sonic-rs = "0.5"
# URL handling
url = "2"
urlencoding = "2"
percent-encoding = "2"

# Bytes
bytes = "1"
Expand All @@ -56,6 +57,25 @@ mime_guess = "2"
# Futures
futures = "0.3"

# Base64 encoding
base64 = "0.22"

# Compression (already transitive deps from reqwest, declared explicitly for direct use)
flate2 = "1"
brotli = "8"
zstd = "0.13"

# Hashing (for digest auth)
md-5 = "0.10"
sha1 = "0.10"
sha2 = "0.10"
digest = "0.10"
rand = "0.8"
hex = "0.4"

# Thread-safe primitives
parking_lot = "0.12"

[profile.release]
lto = true
codegen-units = 1
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ help: ## Show available commands

6-test-python: 5-build ## Run Python tests (requires build)
@echo "$(BLUE)Running Python tests...$(RESET)"
uv run python -m pytest tests/ -v
uv run python -m pytest tests_requestx/ -v
@echo "$(GREEN)✓ Python tests passed$(RESET)"

6-test-all: 6-test-rust 6-test-python ## Run all tests
Expand Down
272 changes: 12 additions & 260 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,289 +1,41 @@
# Requestx
# RequestX

High-performance Python HTTP client based on [reqwest](https://docs.rs/reqwest/) (Rust), using [PyO3](https://pyo3.rs/) as a bridge. The API is designed to be compatible with [HTTPX](https://www.python-httpx.org/).

## Features

- **High Performance**: Built on Rust's reqwest library for maximum speed
- **Async Support**: Full async/await support using Tokio runtime
- **HTTPX-Compatible API**: Familiar interface for Python developers
- **Connection Pooling**: Automatic connection reuse for better performance
- **HTTP/2 Support**: Optional HTTP/2 with prior knowledge
- **TLS/SSL**: Secure connections via rustls
- **Compression**: Automatic gzip, brotli, and deflate decompression
- **Cookies**: Built-in cookie handling
- **Redirects**: Configurable redirect following
- **Timeouts**: Flexible timeout configuration
- **Proxy Support**: HTTP/HTTPS/SOCKS proxy support
- **Authentication**: Basic, Bearer, and Digest authentication
High-performance Python HTTP client, API-compatible with httpx, powered by Rust's reqwest via PyO3.

## Installation

### From PyPI (when published)

```bash
pip install requestx
```

### From Source

Requires Rust toolchain and Python 3.12+.

```bash
# Install maturin
pip install maturin

# Build and install
maturin develop --release
```

## Quick Start

### Synchronous API
## Usage

```python
import requestx

# Simple GET request
# Synchronous requests
response = requestx.get("https://httpbin.org/get")
print(response.status_code) # 200
print(response.json())

# POST with JSON
response = requestx.post(
"https://httpbin.org/post",
json={"key": "value"}
)

# POST with form data
response = requestx.post(
"https://httpbin.org/post",
data={"field": "value"}
)

# Custom headers
response = requestx.get(
"https://httpbin.org/headers",
headers={"X-Custom-Header": "value"}
)

# Query parameters
response = requestx.get(
"https://httpbin.org/get",
params={"key": "value"}
)

# Using a client for connection pooling
with requestx.Client() as client:
response = client.get("https://httpbin.org/get")
print(response.text)
```

### Asynchronous API

```python
# Async requests
import asyncio
import requestx

async def main():
async with requestx.AsyncClient() as client:
# Simple GET
response = await client.get("https://httpbin.org/get")
print(response.json())

# Concurrent requests
tasks = [
client.get("https://httpbin.org/get"),
client.get("https://httpbin.org/get"),
client.get("https://httpbin.org/get"),
]
responses = await asyncio.gather(*tasks)
for r in responses:
print(r.status_code)

asyncio.run(main())
```

## Client Configuration

### Sync Client

```python
from requestx import Client, Timeout, Proxy, Auth

client = Client(
base_url="https://api.example.com",
headers={"Authorization": "Bearer token"},
timeout=Timeout(timeout=30.0, connect=5.0),
follow_redirects=True,
max_redirects=10,
verify=True, # SSL verification
http2=False,
proxy=Proxy(url="http://proxy:8080"),
auth=Auth.basic("user", "pass"),
)
```

### Async Client

```python
from requestx import AsyncClient, Timeout, Auth

client = AsyncClient(
base_url="https://api.example.com",
headers={"Authorization": "Bearer token"},
timeout=Timeout(timeout=30.0, connect=5.0),
follow_redirects=True,
max_redirects=10,
verify=True,
http2=False,
auth=Auth.bearer("token"),
)
```

## Response Object

```python
response = requestx.get("https://httpbin.org/get")

# Status
response.status_code # 200
response.reason_phrase # "OK"

# Content
response.text # Decoded text
response.content # Raw bytes
response.json() # Parse as JSON

# Headers and cookies
response.headers # Headers object
response.cookies # Cookies object

# URL and timing
response.url # Final URL after redirects
response.elapsed # Request duration in seconds

# Status checks
response.is_success # 2xx
response.is_redirect # 3xx
response.is_client_error # 4xx
response.is_server_error # 5xx
response.is_error # 4xx or 5xx

# Raise exception on error
response.raise_for_status()
```

## Authentication

```python
from requestx import Auth

# Basic authentication
response = requestx.get(
"https://api.example.com",
auth=Auth.basic("username", "password")
)

# Bearer token
response = requestx.get(
"https://api.example.com",
auth=Auth.bearer("your-token")
)
```

## Timeouts

```python
from requestx import Timeout

# Simple timeout (total)
response = requestx.get("https://example.com", timeout=30.0)

# Detailed timeout configuration
timeout = Timeout(
timeout=30.0, # Total timeout
connect=5.0, # Connection timeout
read=10.0, # Read timeout
write=10.0, # Write timeout
pool=5.0, # Pool timeout
)
response = requestx.get("https://example.com", timeout=timeout)
```

## Proxy Configuration

```python
from requestx import Proxy, Client

# Single proxy for all protocols
proxy = Proxy(url="http://proxy.example.com:8080")

# Separate proxies
proxy = Proxy(
http="http://http-proxy:8080",
https="http://https-proxy:8080",
)

client = Client(proxy=proxy)
```

## File Uploads

```python
# Multipart file upload
files = {
"file": ("filename.txt", b"file content", "text/plain")
}
response = requestx.post(
"https://httpbin.org/post",
files=files
)
```

## Error Handling

```python
from requestx import RequestError

try:
response = requestx.get("https://example.com")
response.raise_for_status()
except RequestError as e:
print(f"Request failed: {e}")
```

## Comparison with HTTPX

| Feature | Requestx | HTTPX |
|---------|----------|-------|
| Language | Rust + Python | Python |
| Async Support | Yes | Yes |
| HTTP/2 | Yes | Yes |
| Connection Pooling | Yes | Yes |
| Performance | Higher | Standard |

## Development

### Building

```bash
# Install development dependencies
pip install maturin pytest pytest-asyncio

# Build in development mode
maturin develop

# Build release wheel
maturin build --release
```

### Testing
## Features

```bash
pytest tests/ -v
```
- Drop-in replacement for httpx
- Powered by Rust's reqwest for high performance
- Full support for HTTP/1.1 and HTTP/2
- SIMD-accelerated JSON parsing via sonic-rs
- Compression support: gzip, brotli, deflate, zstd

## License

MIT License
MIT
Loading
Loading