Skip to content

Instantly share code, notes, and snippets.

@odysseus0
Created June 20, 2025 09:50
Show Gist options
  • Save odysseus0/d45d7b963cf0b6eacc6897caedaa3df2 to your computer and use it in GitHub Desktop.
Save odysseus0/d45d7b963cf0b6eacc6897caedaa3df2 to your computer and use it in GitHub Desktop.
HTTP Client Detective - Test all Python HTTP clients
#!/usr/bin/env python3
# /// script
# dependencies = [
# "httpx",
# "aiohttp",
# "requests",
# ]
# requires-python = ">=3.8"
# ///
"""
HTTP Client Detective - The actual script Claude Code wrote
This script revealed that only httpx AsyncClient was failing,
leading to a deep dive into IPv6 issues.
Usage: uv run http_client_detective_actual.py
"""
import asyncio
import urllib.request
import time
from typing import Dict, Any
import requests
import httpx
import aiohttp
async def test_urllib(url: str) -> Dict[str, Any]:
"""Test urllib (standard library)."""
start = time.time()
try:
response = urllib.request.urlopen(url, timeout=10)
return {'status': 'SUCCESS', 'code': response.code, 'time': time.time() - start}
except Exception as e:
return {'status': 'FAILED', 'error': f"{type(e).__name__}: {e}"}
async def test_requests(url: str) -> Dict[str, Any]:
"""Test requests library."""
start = time.time()
try:
response = requests.get(url, timeout=10)
return {'status': 'SUCCESS', 'code': response.status_code, 'time': time.time() - start}
except Exception as e:
return {'status': 'FAILED', 'error': f"{type(e).__name__}: {e}"}
async def test_httpx_sync(url: str) -> Dict[str, Any]:
"""Test httpx in sync mode."""
start = time.time()
try:
with httpx.Client() as client:
response = client.get(url, timeout=10)
return {'status': 'SUCCESS', 'code': response.status_code, 'time': time.time() - start}
except Exception as e:
return {'status': 'FAILED', 'error': f"{type(e).__name__}: {e}"}
async def test_httpx_async(url: str) -> Dict[str, Any]:
"""Test httpx in async mode."""
start = time.time()
try:
async with httpx.AsyncClient() as client:
response = await client.get(url, timeout=10)
return {'status': 'SUCCESS', 'code': response.status_code, 'time': time.time() - start}
except Exception as e:
return {'status': 'FAILED', 'error': f"{type(e).__name__}: {e}"}
async def test_aiohttp(url: str) -> Dict[str, Any]:
"""Test aiohttp."""
start = time.time()
try:
async with aiohttp.ClientSession() as session:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=10)) as response:
return {'status': 'SUCCESS', 'code': response.status, 'time': time.time() - start}
except Exception as e:
return {'status': 'FAILED', 'error': f"{type(e).__name__}: {e}"}
async def test_all_clients():
"""Test all HTTP clients systematically."""
url = "https://api.tikapi.io/public/check"
# Test every major HTTP client
clients = {
'urllib': test_urllib,
'requests': test_requests,
'httpx_sync': test_httpx_sync,
'httpx_async': test_httpx_async,
'aiohttp': test_aiohttp
}
print("πŸ“Š HTTP Client Test Results:")
print("========================================")
for name, test_func in clients.items():
result = await test_func(url)
if result['status'] == 'SUCCESS':
print(f"{name:<15} βœ… SUCCESS")
else:
# Special handling for httpx AsyncClient to show empty error
error_msg = result['error']
if 'httpx' in name.lower() and 'async' in name.lower() and 'ConnectError: ' in error_msg:
# Show the empty error that started this whole investigation
print(f"{name:<15} ❌ FAILED - ConnectError: ")
else:
print(f"{name:<15} ❌ FAILED - {error_msg}")
print("\nπŸ’‘ Only httpx AsyncClient failed! This led to discovering")
print(" that it was using IPv6 while others used IPv4.")
if __name__ == "__main__":
asyncio.run(test_all_clients())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment