Skip to content

Feature/v5 fully compatible version#36

Merged
wuqunfei merged 64 commits into
mainfrom
feature/v5-fully-compatible-version
Feb 6, 2026
Merged

Feature/v5 fully compatible version#36
wuqunfei merged 64 commits into
mainfrom
feature/v5-fully-compatible-version

Conversation

@wuqunfei
Copy link
Copy Markdown
Member

@wuqunfei wuqunfei commented Feb 4, 2026

No description provided.

wuqunfei and others added 30 commits January 29, 2026 10:34
- Define project objective: httpx-compatible Python HTTP client powered by Rust reqwest
- Document architecture requirements: Rust-first implementation, minimal Python layer
- Outline implementation phases: clean Python layer, Rust implementation checklist, PyO3 patterns
- Establish testing strategy and success criteria
- Reference pyreqwest implementation

https://claude.ai/code/session_01W7i6eJxTpfuYTErxqjSSV5
- Add Golden Rule: fastest Python code doesn't call Python
- Add performance hierarchy showing 10-100x improvement levels
- Add priority rules table with impact ratings
- Document type conversion rules with examples
- Document GIL management rules with decision tree
- Add memory management rules (zero-copy, references, pre-allocation)
- Add JSON processing rules (serde_json vs Python json benchmarks)
- Add error handling rules with proper exception types
- Add async programming rules and scenario guidance
- Document Python protocol implementations required
- Add free-threaded Python (PyO3 0.28+) patterns
- Add type conversion quick reference table
- Document 8 anti-patterns to avoid

https://claude.ai/code/session_01W7i6eJxTpfuYTErxqjSSV5
- Replace serde_json with sonic-rs as primary JSON library
- sonic-rs provides SIMD-accelerated parsing/serialization
- Update benchmarks showing 50-330x speedup over Python json
- Add Cargo.toml dependency example
- Keep serde_json as fallback option

https://claude.ai/code/session_01W7i6eJxTpfuYTErxqjSSV5
- Add Core Dependencies section with full Cargo.toml example
- Specify pyo3 0.23 with extension-module feature
- Use pyo3-async-runtimes (not deprecated pyo3-asyncio) for async
- Configure reqwest with json, cookies, gzip, brotli features
- Update async programming rules with pyo3_async_runtimes patterns
- Add AsyncClient method example using future_into_py

https://claude.ai/code/session_01W7i6eJxTpfuYTErxqjSSV5
- pyo3: 0.27 (was 0.23)
- pyo3-async-runtimes: 0.27 (was 0.23)
- reqwest: 0.13 with full feature set (blocking, multipart, stream, etc.)
- sonic-rs: 0.5 (was 0.3)
- Add all project dependencies: url, urlencoding, bytes, http, mime, futures
- Include complete Cargo.toml with package info and release profile

https://claude.ai/code/session_01W7i6eJxTpfuYTErxqjSSV5
- Condense to essential information only
- Add 6-iteration development plan based on test structure:
  1. Core Types (URL, Headers, QueryParams, Cookies)
  2. Request & Response models
  3. Sync Client
  4. Async Client
  5. Client Features (auth, redirects, proxies, etc.)
  6. Top-level API & Exceptions
- Map each iteration to specific test files
- Include test commands for each phase
- Keep PyO3 rules as quick reference (5 key rules)

https://claude.ai/code/session_01W7i6eJxTpfuYTErxqjSSV5
- Add Quick Commands section for common operations
- Simplify project structure overview
- Consolidate critical rules into 6 focused sections
- Add clear "Don't" section for anti-patterns
- Keep core dependencies and essential PyO3 patterns
- Fix test folder names (tests_httpx, tests_requestx)
- Remove redundant content while preserving key information

https://claude.ai/code/session_01W7i6eJxTpfuYTErxqjSSV5
This implements the full RequestX HTTP client library with httpx-compatible API:

- Core types: URL, Headers, QueryParams, Cookies, Request, Response
- Sync and async HTTP clients (Client, AsyncClient)
- Top-level API functions (get, post, put, patch, delete, head, options)
- Full exception hierarchy matching httpx
- HTTP status codes via codes class
- Auth types: BasicAuth, DigestAuth, NetRCAuth
- Timeout and Limits configuration
- SIMD-accelerated JSON parsing via sonic-rs
- GIL release during I/O operations for better performance

The implementation follows the CLAUD.md specification with all business
logic in Rust, using pyo3 0.27 and reqwest 0.13.

https://claude.ai/code/session_01W7i6eJxTpfuYTErxqjSSV5
- Add MockTransport and AsyncMockTransport for testing with subclass support
- Add Auth base class and FunctionAuth for custom authentication
- Add HTTPTransport and AsyncHTTPTransport
- Add event_hooks (request/response) and trust_env to Client/AsyncClient
- Add mount() method for transport mounting
- Add _utils module with URLPattern and proxy utilities
- Add streaming iterators (BytesIterator, TextIterator, LinesIterator)

Tests: 683 passing, 723 failing (from 0 due to collection errors)

https://claude.ai/code/session_01W7i6eJxTpfuYTErxqjSSV5
- Add multipart.rs module for multipart form encoding
- Fix Client to support files parameter in HTTP methods
- Fix Request to build multipart body when files provided
- Fix Response to have settable request attribute
- Fix URL to have public get_host method
- Fix api.rs to pass files parameter correctly
- Update _utils.py with URLPattern and proxy fixes
- 754 tests passing (up from 729)

https://claude.ai/code/session_01W7i6eJxTpfuYTErxqjSSV5
- Request.stream now returns a SyncByteStream with content data
- SyncByteStream has from_data constructor for creating with data
- 755 tests passing

https://claude.ai/code/session_01W7i6eJxTpfuYTErxqjSSV5
wuqunfei and others added 29 commits February 3, 2026 12:18
…ipart uploads

Non-seekable file-like objects in multipart form data now set
Transfer-Encoding: chunked instead of Content-Length, matching httpx behavior.
The multipart body builder returns a has_non_seekable flag that propagates
through all call sites in client.rs, request.rs, and multipart.rs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ing support

Headers now store original casing internally while returning lowercased keys
through dict-like interfaces (items, keys, multi_items, __iter__) for httpx
compatibility. The .raw property returns original-case bytes. Host header is
inserted at the front of the header list via new insert_front() method. Default
headers use proper HTTP casing (Accept, User-Agent, etc.). Client now extracts
default_encoding from kwargs and passes it to Response constructors, enabling
autodetect and explicit encoding for text decoding.

Fixes 3 failing tests: test_raw_client_header, test_client_decode_text_using_autodetect,
test_client_decode_text_using_explicit_encoding (35/35 test_client.py now passing).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ontext

Changed `verify: Option<bool>` to `verify: Option<&Bound<'_, PyAny>>` in all
9 top-level API functions (get, post, put, patch, delete, head, options,
request, stream) so that ssl.SSLContext, string paths, and booleans are all
accepted, matching httpx's polymorphic verify parameter.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove pool timeout from Rust's to_duration() since reqwest lacks concurrent
connection limiting, and implement pool concurrency control via asyncio.Semaphore
in the Python AsyncClient wrapper. All HTTP methods and stream() acquire/release
the semaphore, with stream() calling Rust directly to avoid double-acquisition.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The stream() method was calling self._client.request() (Rust) directly,
bypassing Python-level custom transport routing. This meant MockTransport
and other custom transports were ignored during streaming requests. Now
checks for _custom_transport and routes through _send_single_request()
when present, matching the pattern used by request() and other methods.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1: Split 5,536-line __init__.py into 11 focused modules
(_api, _async_client, _auth, _client, _client_common, _compat,
_exceptions, _request, _response, _streams, _transports).

Phase 2: Extract shared Client/AsyncClient logic into _client_common.py
(HeadersProxy, cookie extraction, URL merging, proxy helpers,
transport routing).

Phase 3: Create src/common.rs with shared Rust utilities (JSON
conversion, host header, URL pattern matching, default headers),
reducing ~553 lines of duplication across client, async_client,
request, and response modules.

Phase 4: Add impl_py_iterator! and impl_byte_stream! macros to
unify 5 iterator classes and 2 byte stream classes, saving ~144
lines.

All 1406 tests pass with no behavior changes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Major performance and architecture improvements:
- Phase 1: Switch JSON serialization to sonic-rs (50-300x faster)
- Phase 2: Move decompression (gzip/brotli/zstd/deflate), charset parsing,
  Set-Cookie parsing, and BasicAuth base64 encoding to Rust
- Phase 3: Move DigestAuth hash computation (MD5/SHA/SHA-256/SHA-512) to Rust,
  add guess_json_utf BOM detection, cache lowercase header keys

New Rust functions exposed to Python:
- decompress(), json_from_bytes(), guess_json_utf()
- basic_auth_header(), generate_cnonce(), digest_hash(), compute_digest_response()
- parse_set_cookie()

Dependencies added: flate2, brotli, zstd, md-5, sha1, sha2, digest, rand, hex

All 1406 tests pass.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extract shared helper functions into new src/client_common.rs module:
- AuthAction enum and auth extraction functions
- Header/cookie merging from Python objects
- Event hooks getter/setter helpers
- Basic auth application utilities

This centralizes duplicated business logic that was repeated between
sync and async clients, improving maintainability.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update all PyO3 type casting calls from deprecated downcast() to cast()
across the codebase. Also removes unused imports flagged by compiler
warnings.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace deprecated PyO3 APIs: PyObject -> Py<PyAny>, allow_threads -> detach
- Replace deprecated .downcast() with .cast() across all files
- Fix unused imports in async_client, headers, request, url modules
- Add #[allow(non_camel_case_types)] to codes struct for Python API compat
- Add #[allow(clippy::upper_case_acronyms)] to URL struct
- Replace manual Option::map with .ok() for cleaner auth extraction
- Use sort_by_key with Reverse for mount pattern sorting
- Replace .chars().any(|c| !c.is_ascii()) with !.is_ascii()
- Replace manual prefix stripping with strip_prefix()
- Use (a..=b).contains(&x) for range checks
- Replace manual is_multiple_of checks with .is_multiple_of()
- Fix iterator flatten pattern, remove needless borrows
- Add #[allow(dead_code)] for intentionally unused struct fields
- Add module/impl-level #[allow(unused_variables)] where PyO3 signatures
  require specific parameter names for Python API compatibility
- Derive Default for Auth struct instead of manual impl

Passes: cargo clippy -- -D warnings -A clippy::too_many_arguments
Tests: 1406 passed, 1 skipped

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add multi-concurrency benchmark test that compares requestx against httpx,
aiohttp, requests, and urllib3 across concurrency levels 1-10. Results show
requestx achieves up to 7.35x sync and 12.45x async speedup over httpx.

Include PERFORMANCE.md with detailed tables and Mermaid charts visualizing
the benchmark results and scaling characteristics.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Analyze the market opportunity for requestx as an httpx replacement,
covering the full ecosystem reach of 1.6B+ monthly downloads including
FastAPI, Starlette, AI/ML SDKs (OpenAI, Anthropic, LangChain, etc.),
and workflow tools (Prefect). Document includes detailed financial
impact calculations showing $1.16T annual savings potential at full
replacement, CPU/memory/network efficiency gains, and carbon footprint
reduction estimates.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@wuqunfei wuqunfei merged commit e26e468 into main Feb 6, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants