Skip to main content

The missing rate-limit wrapper for aiohttp. Effortlessly handle 429s, Retry-After headers, and domain throttling for scraping and data pipelines.

Project description

HTTP Wizz 🧙‍♂️

PyPI - Version PyPI - License PyPI - Python Version Tests

The missing rate-limit wrapper for aiohttp and asyncio.

HTTP Wizz handles the hard parts of web scraping and high-volume API consumption: Strict Rate Limiting (RPS), Automatic Retries, 429/503 Backoff, and Domain Throttling. Perfect for web crawlers, data processing pipelines, and microservices.


✨ Key Features

  • Strict Global Rate Limiting: Enforce a precise Request Per Second (RPS) limit across all your concurrent tasks.
  • Per-Domain Throttling: Set different rate limits for different domains (e.g., 50 RPS for Google, 1 RPS for a small site) within the same client.
  • Smart Retries & Backoff: Automatically retries failed requests with exponential backoff.
  • Respects Retry-After: Automatically sleeps when a server sends a 429 Too Many Requests or 503 Service Unavailable with a Retry-After header.
  • Custom Retry Logic: Define your own conditions for retrying (e.g., specific JSON content or headers).
  • Drop-in aiohttp Replacement: The RateLimitedSession is compatible with standard aiohttp usage, including proxies, cookies, and all HTTP verbs.

⚡ Why HTTP Wizz?

Whether you are building a web scraper or a data pipeline (e.g., geocoding 100k addresses), hitting rate limits is the #1 cause of failure. asyncio.gather is too aggressive, and requests is too slow.

Feature requests aiohttp (raw) http-wizz 🧙‍♂️
Async / Non-blocking
Strict Rate Limiting (RPS)
Handle Retry-After Header
Domain-Specific Limits
Auto-Retries with Backoff
Data Pipeline Friendly ⚠️

🚀 Installation

pip install http-wizz

(Optional) For progress bars in fetch_all and fetch_urls: pip install tqdm


🏃 Quick Start

Batch Processing (The Simple Way) Perfect for data processing pipelines where you just want to "fire and forget" a list of tasks at a safe speed.

from http_wizz import fetch_urls

urls = [f"https://api.geocoder.com/search?q={addr}" for addr in my_addresses]

# Process items at exactly 20 requests per second
results = fetch_urls(urls, requests_per_second=20, show_progress=True)

🛠 Advanced Usage

1. High-Performance Async Client

Best for modern async applications and microservices.

import asyncio
from http_wizz import WizzClient

async def main():
    # 50 RPS limit for high-throughput pipelines
    async with WizzClient(requests_per_second=50, burst_size=10) as client:
        results = await client.fetch_all(["https://api.com/task/1", ...])

2. Fine-grained Control (RateLimitedSession)

A drop-in replacement for aiohttp.ClientSession. Use this for full control (headers, cookies, POST/PUT methods, proxies, etc.).

from http_wizz import RateLimitedSession

async with RateLimitedSession(requests_per_second=5) as session:
    # Use proxies, headers, or any other aiohttp feature
    async with session.post(
        "https://api.com/update", 
        json={"id": 123}, 
        proxy="http://user:pass@proxy.com:8080"
    ) as resp:
        status = await resp.json()

3. Domain Throttling

Manage multiple services with different quotas simultaneously.

client = WizzClient(
    requests_per_second=10, # Global Limit
    domain_limits={
        "maps.google.com": 50,  # High quota
        "legacy-service.local": 1 # Very fragile service
    }
)

4. Custom Retry Logic

Retry not just on network errors, but also on specific application-level responses (e.g., a 200 OK that actually contains an error message).

def is_error_response(response, content):
    # Retry if the JSON body contains "error": true
    if isinstance(content, dict) and content.get("error"):
        return True
    return False

client = WizzClient(should_retry=is_error_response)

📖 Recipes & Examples

Check out the examples/ directory for ready-to-run scripts:


📚 API Reference

For a complete list of all parameters, flags, and advanced options, please see the Full API Reference.


🤝 Contributing

We love pull requests! If you have a feature idea or found a bug, please open an issue.

License: MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

http_wizz-1.0.2.tar.gz (11.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

http_wizz-1.0.2-py3-none-any.whl (8.5 kB view details)

Uploaded Python 3

File details

Details for the file http_wizz-1.0.2.tar.gz.

File metadata

  • Download URL: http_wizz-1.0.2.tar.gz
  • Upload date:
  • Size: 11.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for http_wizz-1.0.2.tar.gz
Algorithm Hash digest
SHA256 3a5f568cabb1f55db68693cc03ad2427eb568d58293bb136e110fcede57a3858
MD5 65dfb1d427a3499a8f99fa93c25c874f
BLAKE2b-256 29494f7462a97c89876311eaf3e0746a02c3d5dcbbc43786b7a42312e0f35c50

See more details on using hashes here.

Provenance

The following attestation bundles were made for http_wizz-1.0.2.tar.gz:

Publisher: publish.yml on TomMcKenna1/http-wizz

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file http_wizz-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: http_wizz-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 8.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for http_wizz-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 fad8436db98449785ca5aceffa7e0b0abb8931027ed7fa6ea668e0ab6798be6d
MD5 14b9e49dc9a3ade9d16bcc9648d7866a
BLAKE2b-256 ba26934c2d6ac4f0c8d12d4189e601f321fb06c4f6c2ba9d80f38698802cc929

See more details on using hashes here.

Provenance

The following attestation bundles were made for http_wizz-1.0.2-py3-none-any.whl:

Publisher: publish.yml on TomMcKenna1/http-wizz

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page