Simple GET request:
import httpmorph
response = httpmorph.get('https://httpbin.org/get')
print(response.status_code)
print(response.text)POST with JSON data:
response = httpmorph.post(
'https://httpbin.org/post',
json={'name': 'value'}
)
print(response.json())POST with form data:
response = httpmorph.post(
'https://httpbin.org/post',
data={'field': 'value'}
)All HTTP methods:
httpmorph.get(url)
httpmorph.post(url, data=...)
httpmorph.put(url, data=...)
httpmorph.delete(url)
httpmorph.head(url)
httpmorph.patch(url, data=...)
httpmorph.options(url)Create a client for more control:
client = httpmorph.Client()
response = client.get('https://example.com')Enable HTTP/2:
client = httpmorph.Client(http2=True)
response = client.get('https://www.google.com')
print(response.http_version) # '2.0'Set default timeout:
client = httpmorph.Client(timeout=10)
response = client.get('https://example.com')Sessions persist cookies and headers:
session = httpmorph.Session()
# First request sets cookies
session.get('https://example.com/login')
# Subsequent requests include cookies
session.get('https://example.com/protected')
# Access cookies
print(session.cookies)Use as context manager:
with httpmorph.Session() as session:
response = session.get('https://example.com')Mimic Chrome browser with realistic fingerprints:
# Chrome browser profile (defaults to Chrome 143)
session = httpmorph.Session(browser='chrome')
response = session.get('https://example.com')
# Use specific Chrome version (127-143 supported)
session = httpmorph.Session(browser='chrome143')
response = session.get('https://example.com')
# Random browser selection
session = httpmorph.Session(browser='random')The Chrome browser profile includes:
- Chrome-specific User-Agent
- Chrome-specific TLS cipher suites and extensions
- Post-quantum cryptography (X25519MLKEM768)
- Certificate compression (Brotli, with zlib fallback)
- Chrome-specific HTTP/2 settings and priority
- Perfect JA3N, JA4, JA4_R, and Akamai fingerprint matching
- Chrome-like default headers (sec-ch-ua, sec-fetch-*, etc.)
Simulate requests from different operating systems:
import httpmorph
# macOS (default)
session = httpmorph.Session(browser='chrome', os='macos')
# User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...
# Windows
session = httpmorph.Session(browser='chrome', os='windows')
# User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...
# Linux
session = httpmorph.Session(browser='chrome', os='linux')
# User-Agent: Mozilla/5.0 (X11; Linux x86_64) ...Supported OS values:
macos- macOS / Mac OS X (default)windows- Windows 10/11linux- Linux distributions
The os parameter only affects the User-Agent string. All other fingerprinting characteristics (TLS, HTTP/2, JA3/JA4) remain consistent with the specified browser profile.
Headers:
headers = {'User-Agent': 'MyApp/1.0'}
response = httpmorph.get(url, headers=headers)Query parameters:
params = {'key': 'value', 'foo': 'bar'}
response = httpmorph.get(url, params=params)
# Requests: https://example.com?key=value&foo=barAuthentication:
# Basic authentication
response = httpmorph.get(
url,
auth=('username', 'password')
)Timeout:
# 5 second timeout
response = httpmorph.get(url, timeout=5)Proxy:
# HTTP proxy
response = httpmorph.get(
url,
proxy='http://proxy.example.com:8080'
)
# With authentication
response = httpmorph.get(
url,
proxy='http://proxy.example.com:8080',
proxy_auth=('user', 'pass')
)
# Proxy dict (requests-compatible)
proxies = {
'http': 'http://proxy.example.com:8080',
'https': 'https://proxy.example.com:8080'
}
response = httpmorph.get(url, proxies=proxies)SSL verification:
# Disable SSL verification (not recommended)
response = httpmorph.get(url, verify=False)Redirects:
# Disable redirect following
response = httpmorph.get(url, allow_redirects=False)
# Limit max redirects
response = httpmorph.get(url, max_redirects=5)Access response data:
response = httpmorph.get('https://httpbin.org/get')
# Status
print(response.status_code) # 200
print(response.ok) # True for 200-399
print(response.reason) # 'OK'
# Content
print(response.body) # bytes
print(response.text) # str (decoded)
print(response.content) # bytes (alias)
# JSON
data = response.json()
# Headers
print(response.headers)
print(response.headers['Content-Type'])
# URL
print(response.url) # Final URL after redirectsTiming information:
print(response.total_time_us) # Total time in microseconds
print(response.connect_time_us) # Connection time
print(response.tls_time_us) # TLS handshake time
print(response.first_byte_time_us) # Time to first byte
print(response.elapsed) # As timedeltaTLS information:
print(response.tls_version) # 'TLSv1.3'
print(response.tls_cipher) # Cipher suite name
print(response.ja3_fingerprint) # JA3 fingerprintHTTP version:
print(response.http_version) # '1.1' or '2.0'Redirect history:
print(len(response.history)) # Number of redirects
for r in response.history:
print(r.status_code, r.url)Handle exceptions:
import httpmorph
try:
response = httpmorph.get('https://example.com', timeout=5)
response.raise_for_status() # Raise on 4xx/5xx
except httpmorph.Timeout:
print('Request timed out')
except httpmorph.ConnectionError:
print('Connection failed')
except httpmorph.HTTPError as e:
print(f'HTTP error: {e.response.status_code}')
except httpmorph.RequestException as e:
print(f'Request failed: {e}')Available exceptions:
RequestException- Base exceptionHTTPError- 4xx/5xx status codes (after raise_for_status)ConnectionError- Connection failuresTimeout- Request timeoutTooManyRedirects- Max redirects exceeded
Upload files:
# Single file
files = {'file': open('report.pdf', 'rb')}
response = httpmorph.post('https://httpbin.org/post', files=files)
# Multiple files
files = {
'file1': open('report.pdf', 'rb'),
'file2': open('data.csv', 'rb')
}
response = httpmorph.post(url, files=files)
# With filename and content type
files = {
'file': ('report.pdf', open('report.pdf', 'rb'), 'application/pdf')
}
response = httpmorph.post(url, files=files)Both Client and Session default to HTTP/2 to match Chrome behavior:
# Both Client and Session default to HTTP/2 (http2=True)
client = httpmorph.Client()
response = client.get('https://www.google.com')
print(response.http_version) # '2.0'
session = httpmorph.Session(browser='chrome')
response = session.get('https://www.google.com')
print(response.http_version) # '2.0'
# Per-request override (disable HTTP/2 for specific request)
client = httpmorph.Client() # Defaults to HTTP/2
response = client.get('https://example.com', http2=False)Check HTTP version:
response = client.get('https://www.google.com')
if response.http_version == '2.0':
print('Using HTTP/2')Use AsyncClient for async/await:
import asyncio
import httpmorph
async def fetch():
async with httpmorph.AsyncClient() as client:
response = await client.get('https://httpbin.org/get')
print(response.status_code)
return response
asyncio.run(fetch())Make concurrent requests:
import asyncio
import httpmorph
async def fetch_all(urls):
async with httpmorph.AsyncClient() as client:
tasks = [client.get(url) for url in urls]
responses = await asyncio.gather(*tasks)
return responses
urls = [
'https://httpbin.org/get',
'https://httpbin.org/headers',
'https://httpbin.org/user-agent'
]
responses = asyncio.run(fetch_all(urls))
for response in responses:
print(response.status_code, response.url)- See :doc:`api` for complete API reference
- See :doc:`advanced` for advanced features
- Check the examples directory in the repository