net_benchmark.http_bench.core
Core HTTP benchmarking functionality.
Classes
|
|
|
httpx-native Digest authentication (MD5 or SHA-256, qop=auth). |
|
Negotiated application protocol — captured from the live connection. |
|
Result of a single HTTP request |
|
AsyncHTTPTransport that captures per-connection timing, TLS metrics, connection reuse info, and (best-effort) HTTP/2 pushes. |
|
AsyncConnectionPool that injects push-tracking H2 connections. |
|
An H2 connection that records promised stream headers. |
|
Parse and validate HTTP target URLs. |
|
Wraps AutoBackend to inject per-connection TCP and TLS timing. |
|
Wraps an AsyncNetworkStream to capture TCP-connect and TLS-handshake times for exactly this connection. |
- class net_benchmark.http_bench.core.TimingNetworkStream(stream, metrics, session_registry=None)[source]
Bases:
AsyncNetworkStreamWraps an AsyncNetworkStream to capture TCP-connect and TLS-handshake times for exactly this connection.
# Each TimingNetworkStream owns its own metrics dict (created fresh in TimingNetworkBackend.connect_tcp — never shared/mutated by other connections). Callers that need this specific connection’s metrics should retrieve this stream instance (e.g. via httpx.Response.extensions[“network_stream”]) and call get_metrics(), rather than reading TimingNetworkBackend.metrics, which only reflects whichever connection was opened most recently on this backend and is unsafe to read under concurrency (see MetricsCapturingTransport docs).
- class net_benchmark.http_bench.core.TimingNetworkBackend(local_address=None)[source]
Bases:
AsyncNetworkBackendWraps AutoBackend to inject per-connection TCP and TLS timing.
One backend instance per origin. self.metrics reflects only the most recently opened connection and is kept for backward compatibility with MetricsCapturingTransport.get_connection_metrics() (used as a fallback when the per-request stream isn’t retrievable) — callers that need correct per-request attribution under concurrency should prefer the per-stream metrics via TimingNetworkStream.get_metrics().
- async connect_tcp(host, port, timeout=None, local_address=None, socket_options=None)[source]
- Return type:
AsyncNetworkStream
- class net_benchmark.http_bench.core.PushTrackingH2Connection(config=None)[source]
Bases:
H2ConnectionAn H2 connection that records promised stream headers.
- class net_benchmark.http_bench.core.PushDetectingPool(ssl_context=None, proxy=None, max_connections=10, max_keepalive_connections=None, keepalive_expiry=None, http1=True, http2=False, retries=0, local_address=None, uds=None, network_backend=None, socket_options=None)[source]
Bases:
AsyncConnectionPoolAsyncConnectionPool that injects push-tracking H2 connections.
This relies on httpcore private internals (_init_connection, _h2_connection) that are not part of httpcore’s public API and are not guaranteed stable across versions. If either is missing or raises, push detection silently degrades to “no pushes recorded” rather than crashing the request — see _init_connection below.
- class net_benchmark.http_bench.core.MetricsCapturingTransport(verify=True, cert=None, http2=False, sni_hostname=None, mtls_cert=None, mtls_key=None, local_address=None, enable_push_detection=False)[source]
Bases:
AsyncHTTPTransportAsyncHTTPTransport that captures per-connection timing, TLS metrics, connection reuse info, and (best-effort) HTTP/2 pushes.
# get_connection_metrics() returns only the most-recently-opened connection’s metrics for this transport and is unsafe to rely on when multiple requests to the same origin are in flight concurrently — it exists as a fallback for callers that can’t retrieve the per-request stream (e.g. sequential/single-concurrency use, or older code). Prefer reading httpx.Response.extensions[“network_stream”].get_metrics() when available; request_single() below does this automatically.
- get_connection_metrics(connection_id=None)[source]
Pass connection_id to get that specific connection’s metrics safely, even under concurrency (looked up from TimingNetworkBackend.metrics_by_id, unaffected by other connections opening/closing). Without connection_id, falls back to the old “most recently opened” snapshot — still unsafe under concurrency, kept only for callers with no id to give (e.g. a totally fresh transport with zero requests sent).
- get_connections_opened()[source]
Cumulative count of new TCP connections opened by this transport’s pool.
- Return type:
- get_recent_push_promises()[source]
Return any HTTP/2 push promises recorded by the push-detecting pool. Empty list if push detection is unavailable/disabled, or if the httpcore internals it depends on aren’t present in this version — never raises for that reason. Only AttributeError is swallowed here (private-API shape drift); anything else propagates so real bugs in this loop aren’t hidden alongside “h2 unavailable”.
- class net_benchmark.http_bench.core.HTTPProtocol(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]
-
Negotiated application protocol — captured from the live connection.
- HTTP1 = 'HTTP/1.1'
- HTTP2 = 'HTTP/2'
- UNKNOWN = 'unknown'
- class net_benchmark.http_bench.core.HTTPDigestAuth(username, password)[source]
Bases:
Authhttpx-native Digest authentication (MD5 or SHA-256, qop=auth).
Replaces a previous version that borrowed requests.auth.HTTPDigestAuth outside its intended Session.send() retry flow (it never actually computed a digest response from the real WWW-Authenticate challenge). This parses the real 401 and computes HA1/HA2/response directly, no requests dependency.
- class net_benchmark.http_bench.core.HTTPResult(target, method, start_time, end_time, total_ms, status, iteration=1, attempt_number=1, query_id=<factory>, http_status_code=None, error_message=None, redirect_count=0, final_url='', ttfb_ms=None, ttlb_ms=None, protocol=HTTPProtocol.UNKNOWN, alpn_negotiated=None, response_size_bytes=None, compressed=False, content_encoding=None, content_type=None, security_headers=<factory>, cdn_fingerprint=None, server_header=None, cert_expiry_days=None, cert_cn=None, alt_svc=None, ip_version=None, cert_issuer_cn=None, cert_sans=<factory>, cert_wildcard=False, downgrade_detected=False, redirect_urls=<factory>, tls_handshake_ms=None, tcp_connect_ms=None, dns_resolve_ms=None, dns_resolver_ip=None, compressed_size_bytes=None, http2_expected=False, http2_downgraded=False, redirect_timings=<factory>, query_params=<factory>, cache_control=None, etag=None, last_modified=None, age=None, request_id=None, assertion_results=<factory>, connection_id=None, connection_reused=False, tcp_fast_open=None, tls_resumed=False, tls_session_id=None, session_ticket=False, http2_push_count=0, http2_pushes=<factory>, upload_size_bytes=None, upload_time_ms=None, upload_throughput_mbps=None, websocket_handshake_ms=None)[source]
Bases:
objectResult of a single HTTP request
-
status:
QueryStatus
-
protocol:
HTTPProtocol= 'unknown'
-
status:
- class net_benchmark.http_bench.core.TargetManager(targets)[source]
Bases:
objectParse and validate HTTP target URLs.
-
DEFAULT_TARGETS:
List[str] = ['https://www.cloudflare.com', 'https://www.google.com', 'https://www.github.com', 'https://www.wikipedia.org', 'https://www.apple.com']
-
DEFAULT_TARGETS:
- class net_benchmark.http_bench.core.HTTPBenchmarkEngine(max_concurrent=50, timeout=10.0, connect_timeout=None, read_timeout=None, write_timeout=None, max_retries=2, retry_backoff_multiplier=0.1, retry_backoff_base=2.0, method='GET', headers=None, follow_redirects=True, verify_ssl=True, http2=True, auth=None, cookies=None, proxy=None, sni_hostname=None, mtls_cert=None, mtls_key=None, inject_request_id=False, assertions=None, query_params=None, body=None, local_address=None, use_cookie_jar=False, enable_push_detection=False, enable_connection_reuse=False, enable_tfo_detection=False, enable_tls_resumption=False, enable_session_ticket=False)[source]
Bases:
object- get_connection_stats(target, connection_id=None)[source]
Pass connection_id (from HTTPResult.connection_id, requires enable_connection_reuse=True) to safely inspect one specific connection’s metrics. Without it, “latest_metrics” is a best-effort snapshot only reliable when no concurrent requests are in flight.
- async request_single(target, iteration=1, multipart_file_size=0)[source]
Execute a single HTTP request with retry logic.
- Return type:
- async websocket_single(target, iteration=1)[source]
Perform a WebSocket handshake and measure the time to establish.
Requires aiohttp to be installed (pip install net-benchmark[websocket]).
- Return type: