⚡ High-performance async HTTP client in Rust with Python bindings for blazing-fast batch requests.
Project description
rusty-req
A high-performance asynchronous request library based on Rust and Python, suitable for scenarios that require high-throughput concurrent HTTP requests. It implements the core concurrent logic in Rust and packages it into a Python module using PyO3 and maturin, combining Rust's performance with Python's ease of use.
🚀 Features
- Dual Request Modes: Supports both batch concurrent requests (
fetch_requests) and single asynchronous requests (fetch_single). - High Performance: Built with Rust, Tokio, and a shared
reqwestclient for maximum throughput. - Highly Customizable: Allows custom headers, parameters/body, per-request timeouts, and tags.
- Smart Response Handling: Automatically decompresses
gzip,brotli, anddeflateencoded responses. - Global Timeout Control: Use
total_timeoutin batch requests to prevent hangs. - Detailed Results: Each response includes the HTTP status, body, metadata (like processing time), and any exceptions.
- Debug Mode: An optional debug mode (
set_debug(True)) prints detailed request/response information.
🔧 Installation
pip install rusty-req
Or build from source:
# This will compile the Rust code and create a .whl file
maturin build --release
# Install from the generated wheel
pip install target/wheels/rusty_req-*.whl
Development & Debugging
cargo watch -s "maturin develop"
📦 Example Usage
1. Fetching a Single Request (fetch_single)
Perfect for making a single asynchronous call and awaiting its result.
import asyncio
import pprint
import rusty_req
async def single_request_example():
"""Demonstrates how to use fetch_single for a POST request."""
print("🚀 Fetching a single POST request to httpbin.org...")
# Enable debug mode to see detailed logs in the console
rusty_req.set_debug(True)
response = await rusty_req.fetch_single(
url="https://httpbin.org/post",
method="POST",
params={"user_id": 123, "source": "example"},
headers={"X-Client-Version": "1.0"},
tag="my-single-post"
)
print("\n✅ Request finished. Response:")
pprint.pprint(response)
if __name__ == "__main__":
asyncio.run(single_request_example())```
2. Fetching Batch Requests (fetch_requests)
The core feature for handling a large number of requests concurrently. This example simulates a simple load test.
import asyncio
import time
import rusty_req
async def batch_requests_example():
"""Demonstrates 100 concurrent requests with a global timeout."""
requests = [
rusty_req.RequestItem(
url="https://httpbin.org/delay/2", # This endpoint waits 2 seconds
method="GET",
timeout=2.9, # Per-request timeout, should succeed
tag=f"test-req-{i}",
)
for i in range(100)
]
# Disable debug logs for cleaner output
rusty_req.set_debug(False)
print("🚀 Starting 100 concurrent requests...")
start_time = time.perf_counter()
# Set a global timeout of 3.0 seconds. Some requests will be cut off.
responses = await rusty_req.fetch_requests(
requests,
total_timeout=3.0
)
total_time = time.perf_counter() - start_time
# --- Process results ---
success_count = 0
failed_count = 0
for r in responses:
# Check the 'exception' field to see if the request was successful
if r.get("exception") and r["exception"].get("type"):
failed_count += 1
else:
success_count += 1
print("\n📊 Load Test Summary:")
print(f"⏱️ Total time taken: {total_time:.2f}s")
print(f"✅ Successful requests: {success_count}")
print(f"⚠️ Failed or timed-out requests: {failed_count}")
if __name__ == "__main__":
asyncio.run(batch_requests_example())
🧱 Data Structure
RequestItem Parameters
| Field | Type | Required | Description |
|---|---|---|---|
url |
str |
✅ | Target URL |
method |
str |
✅ | HTTP method |
params |
dict / None |
No | For GET/DELETE, converted to URL query parameters. For POST/PUT/PATCH, sent as a JSON body. |
headers |
dict / None |
No | Custom HTTP headers |
timeout |
float |
✅ | Timeout for this single request in seconds. Defaults to 30s. |
tag |
str |
No | An arbitrary tag to help identify or index the response. |
Response Dictionary Format
Both fetch_single and fetch_requests return a dictionary (or a list of dictionaries) with a consistent structure.
Example of a successful response:
{
"http_status": 200,
"response": "{\"data\": \"...\", \"headers\": {\"...\"}}",
"meta": {
"process_time": "0.4531",
"request_time": "2025-08-08 03:15:01 -> 2025-08-08 03:15:01",
"tag": "my-single-post"
},
"exception": {}
}
Example of a failed response (e.g., timeout):
{
"http_status": 0,
"response": "",
"meta": {
"process_time": "3.0012",
"request_time": "2025-08-08 03:15:05 -> 2025-08-08 03:15:08",
"tag": "test-req-50"
},
"exception": {
"type": "Timeout",
"message": "Request timeout after 3.00 seconds"
}
}
📄 License
This project is licensed under the MIT License.
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 Distributions
Built Distributions
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 rusty_req-0.2.8-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: rusty_req-0.2.8-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 1.5 MB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1188fd21b2b8cf1e64607e6b03e2dc29362d909d00f8d393e7cd529a6b8e280d
|
|
| MD5 |
f8ad01b0d3a140c2964e1e5ace6797b6
|
|
| BLAKE2b-256 |
0284f2db40a3a4c0cf215d7ed4f597badbc8ce6ac017db1156a3caedee9afcd1
|
File details
Details for the file rusty_req-0.2.8-cp312-cp312-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: rusty_req-0.2.8-cp312-cp312-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.12, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb3ec7ff4a94efb1ffb8e64b73f53571b1ffeb24ffab7741a8927e517cf7c013
|
|
| MD5 |
36d869508bc26d5d72bb2ac9775fcc10
|
|
| BLAKE2b-256 |
c606aeacecca3cabb0b643c4623cbc2dcd3630a90bf7eef2924d63fc5d2b7c2c
|
File details
Details for the file rusty_req-0.2.8-cp312-cp312-macosx_10_12_universal2.whl.
File metadata
- Download URL: rusty_req-0.2.8-cp312-cp312-macosx_10_12_universal2.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.12, macOS 10.12+ universal2 (ARM64, x86-64)
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f975abaf455a781938984557b8e209ba9f3a2a70ca964482c41f39e7f6d95865
|
|
| MD5 |
62354ced9384528df4c61dcc1b7167f0
|
|
| BLAKE2b-256 |
5991d891aff08085cbb97963835fcc99c69e26829867b071123f300e4195c992
|
File details
Details for the file rusty_req-0.2.8-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: rusty_req-0.2.8-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 1.6 MB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
356017aca2a11b8dc24852a397f8e375396a7a34db3d478deed59630728be4ed
|
|
| MD5 |
20560cc2025dc0c8c1ace29fa6c623b4
|
|
| BLAKE2b-256 |
ee1e7e4140fe553625579e6dab79f63a651b7e2311869aa2a64b2a8719e0bbad
|
File details
Details for the file rusty_req-0.2.8-cp311-cp311-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: rusty_req-0.2.8-cp311-cp311-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.11, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45c14668dddffe06fa7198c5c14f000e14fb68e7a4d3297aa93ba4c901e3cf28
|
|
| MD5 |
3af76235650ddac18d15383f3ee7bea1
|
|
| BLAKE2b-256 |
631213e321e18d9f2a515a90fd133dc4b8548f06654bb2478409fca4af64c381
|
File details
Details for the file rusty_req-0.2.8-cp311-cp311-macosx_10_12_universal2.whl.
File metadata
- Download URL: rusty_req-0.2.8-cp311-cp311-macosx_10_12_universal2.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.11, macOS 10.12+ universal2 (ARM64, x86-64)
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed21986d74f5f5681cdaeaa98336b3da6ee87e5772429387c1c1061fbefc2ff3
|
|
| MD5 |
1be40e28a1eb79be4fdc5d350b4ce779
|
|
| BLAKE2b-256 |
75c1354f124bae1e239b15f626dfab130d37a8fddec1a6da2d5308c7d379f69a
|
File details
Details for the file rusty_req-0.2.8-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: rusty_req-0.2.8-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 1.6 MB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0f99e52965537d3d24e8ecfa04d8ffd7707ea891d1c1b1a6eb44312c60285f28
|
|
| MD5 |
91c35020118ec4a7410d8df198114c37
|
|
| BLAKE2b-256 |
421f6d34a8a69699f150e09ae2699d7c0292d7394139c0ed987bf7e8c7a5dcee
|
File details
Details for the file rusty_req-0.2.8-cp310-cp310-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: rusty_req-0.2.8-cp310-cp310-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.10, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
687b4e8d103b40bb0a2bf8a663ff921e69aaecaa93b1eec193f27fa58ae5b885
|
|
| MD5 |
78d3966a4ee9cf3fab14de2ed0da5aae
|
|
| BLAKE2b-256 |
feccb41832ac12fb3d2ccd111dc99cd996674e03b184db9ec79ce98db6996315
|
File details
Details for the file rusty_req-0.2.8-cp310-cp310-macosx_10_12_universal2.whl.
File metadata
- Download URL: rusty_req-0.2.8-cp310-cp310-macosx_10_12_universal2.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.10, macOS 10.12+ universal2 (ARM64, x86-64)
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58bc29e0a565396b03f76277c160784cef2262ca4ef6ed0ebfa0082f769b4931
|
|
| MD5 |
fc7bc9bb1c137690ad6321ff35f40e7d
|
|
| BLAKE2b-256 |
96cd54ca28a6f7c96717a60fc8f5759e3939e20c7f40f951de314bb5e8788cf0
|
File details
Details for the file rusty_req-0.2.8-cp39-cp39-win_amd64.whl.
File metadata
- Download URL: rusty_req-0.2.8-cp39-cp39-win_amd64.whl
- Upload date:
- Size: 1.6 MB
- Tags: CPython 3.9, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca336c5cb765e1eb5df6cfce6ac852260d578e7ca8c11138fc12e6ed5f83391c
|
|
| MD5 |
6825ff10665dda217f074df132e0a1ad
|
|
| BLAKE2b-256 |
6543d9778f2396267344eae4a88577adb0e5a087272b6b675785e52616a90fc6
|
File details
Details for the file rusty_req-0.2.8-cp39-cp39-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: rusty_req-0.2.8-cp39-cp39-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.9, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85aef077b5cad85b8fa0258caec69210f22704d7ed60174380eac0293b969498
|
|
| MD5 |
b1a3c81cbba28d3f94cfae30586e103e
|
|
| BLAKE2b-256 |
9c9930a02077ebad32e904efd09dc32c462a648f2785dba610b902fa08726e0b
|
File details
Details for the file rusty_req-0.2.8-cp39-cp39-macosx_10_12_universal2.whl.
File metadata
- Download URL: rusty_req-0.2.8-cp39-cp39-macosx_10_12_universal2.whl
- Upload date:
- Size: 3.7 MB
- Tags: CPython 3.9, macOS 10.12+ universal2 (ARM64, x86-64)
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f662ce14c518618e19cafe24b6364d535998e6c2100d25a8e3208b6a36873794
|
|
| MD5 |
5935b7a8a08174c89f6ccc8a3f8ec55e
|
|
| BLAKE2b-256 |
d324cb1ba981e768a560788a533e47d6d1295a9886559c82f88f905c1f62fd1a
|