# encode/httpx — codebase unpack

> Canonical page: https://codevetter.com/unpack/httpx

This is a deterministic Repo Unpack scan of encode/httpx — a structural map, not a review, security audit, or maintainer-endorsed description.

- Scanned commit: b5addb64f0161ff6bfe94c124ef76f6a1fba5254 (2026-02-23)
- Last upstream commit: Adapt test_response_decode_text_using_autodetect for chardet 6.0 (#3773)
- Generated by codevetter 1.15.0 on 2026-10-02
- 113 files scanned · 968 KB

Source inspection; upstream code and tests were not executed.

## Languages

- Python: 60 files
- Markdown: 29 files
- YAML: 6 files
- CSS: 1 files
- HTML: 1 files
- JSON: 1 files
- TOML: 1 files

## Repository structure

- tests/ — 40 files
- docs/ — 26 files
- httpx/ — 24 files
- .github/ — 8 files
- scripts/ — 8 files

Probable source entrypoint: `pyproject.toml` (inferred from the tree, not upstream docs)

## Source layout — httpx/

- httpx/_transports/ — 6 files
- httpx/__init__.py — 1 file
- httpx/__version__.py — 1 file
- httpx/_api.py — 1 file
- httpx/_auth.py — 1 file
- httpx/_client.py — 1 file
- httpx/_config.py — 1 file
- httpx/_content.py — 1 file
- httpx/_decoders.py — 1 file
- httpx/_exceptions.py — 1 file
- httpx/_main.py — 1 file
- httpx/_models.py — 1 file
- httpx/_multipart.py — 1 file
- httpx/_status_codes.py — 1 file

## Package

- pyproject.toml: httpx — 18 declared dependencies

## Structural health signals

Average score 7.1/10 across 23 files; 6 hotspots. These are deterministic review leads, not proof of a bug.

## Recent history

- b5addb64f016 (2026-02-23) Adapt test_response_decode_text_using_autodetect for chardet 6.0 (#3773)
- ae1b9f66238f (2025-12-10) Expose `FunctionAuth` in `__all__` (#3699)
- ca097c96f97d (2025-12-10) docs/ssl: fix typo (#3703)
- def4778d622e (2025-10-16) Fixed a syntax error in the file upload example (#3692)
- 435e1dac899a (2025-10-04) Bump actions/setup-python from 5 to 6 (#3677)

## Overview

HTTPX is a Python HTTP client for application developers, with synchronous and asynchronous APIs plus an optional terminal client. It combines reusable connection pools, authentication, redirects, cookies, uploads, and response decoding behind a transport interface that can also call WSGI and ASGI applications directly. This brief reflects source inspection at commit b5addb64f0161ff6bfe94c124ef76f6a1fba5254; tests and CI were inspected, not executed.

## System map

The package separates public APIs, client policy, HTTP models, and transport execution. Client configuration and cookies live in Python objects, while network connection pools belong to httpcore. Packaging produces a Python distribution and a MkDocs documentation site. The inspected workflows define verification and publication, but their outcomes were not observed.
- The distribution requires Python >=3.9, uses Hatchling, and declares certifi, httpcore==1.*, anyio, and idna as runtime dependencies. — [pyproject.toml#L1-L9](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/pyproject.toml#L1-L9) [pyproject.toml#L30-L35](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/pyproject.toml#L30-L35)
- httpx/__init__.py assembles the public API from internal modules; the console entrypoint is httpx:main, with an import fallback that explains how to install missing CLI extras and exits 1. — [httpx/__init__.py#L1-L26](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/__init__.py#L1-L26) [pyproject.toml#L58-L59](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/pyproject.toml#L58-L59)
- _api.request() creates a context-managed Client for one call; BaseClient holds shared configuration, while Client and AsyncClient implement separate dispatch pipelines. — [httpx/_api.py#L102-L120](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_api.py#L102-L120) [httpx/_client.py#L204-L221](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L204-L221) [httpx/_client.py#L879-L928](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L879-L928) [httpx/_client.py#L1594-L1643](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L1594-L1643)
- Request, Response, Headers, and Cookies are HTTP model objects; URL delegates parsing to the repository's RFC3986-oriented normalization implementation rather than relying exclusively on stdlib parsing. — [httpx/_models.py#L139-L162](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L139-L162) [httpx/_models.py#L382-L423](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L382-L423) [httpx/_urls.py#L115-L124](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_urls.py#L115-L124) [httpx/_urlparse.py#L1-L16](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_urlparse.py#L1-L16)
- HTTPTransport and AsyncHTTPTransport select httpcore connection pools or HTTP/SOCKS proxy pools and translate HTTPX requests and responses across that dependency boundary. — [httpx/_transports/default.py#L150-L210](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/default.py#L150-L210) [httpx/_transports/default.py#L230-L259](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/default.py#L230-L259) [httpx/_transports/default.py#L374-L403](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/default.py#L374-L403)
- Alternate runtime boundaries include synchronous WSGI calls, asynchronous ASGI calls, and callable-backed MockTransport dispatch; each returns the same Response model. — [httpx/_transports/wsgi.py#L91-L149](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/wsgi.py#L91-L149) [httpx/_transports/asgi.py#L99-L119](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/asgi.py#L99-L119) [httpx/_transports/asgi.py#L169-L187](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/asgi.py#L169-L187) [httpx/_transports/mock.py#L15-L43](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/mock.py#L15-L43)
- Session state is client-owned: BaseClient initializes Cookies, received responses update that jar, and Cookies wraps stdlib CookieJar. CLI downloads provide an explicit filesystem output boundary. — [httpx/_client.py#L206-L221](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L206-L221) [httpx/_client.py#L1016-L1024](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L1016-L1024) [httpx/_models.py#L1084-L1115](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L1084-L1115) [httpx/_main.py#L251-L270](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_main.py#L251-L270)
- CI invokes install, check, build, test, and coverage scripts on Ubuntu/Python 3.9–3.13; tag publication builds distributions and docs, then uploads to PyPI and deploys MkDocs after checking tag/version agreement. — [.github/workflows/test-suite.yml#L10-L34](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/.github/workflows/test-suite.yml#L10-L34) [.github/workflows/publish.yml#L3-L26](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/.github/workflows/publish.yml#L3-L26) [scripts/build#L11-L13](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/scripts/build#L11-L13) [scripts/publish#L15-L26](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/scripts/publish#L15-L26)

## Feature catalog

The user-facing surface consists of library APIs and a single HTTP request CLI. Library callers can choose convenience helpers or reusable clients, customize request construction, and consume buffered or streaming responses. Protocol, proxy, authentication, and in-process application integrations share the client model. The following eight groups describe capabilities supported by the inspected implementation.
- The top-level API exports get, options, head, post, put, patch, delete, request, and stream; generic request accepts body content, form data, files, JSON, query parameters, headers, cookies, and authentication. — [httpx/_api.py#L26-L56](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_api.py#L26-L56) [httpx/_api.py#L102-L120](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_api.py#L102-L120)
- Reusable clients combine default headers, query parameters, and cookies with request values, append relative paths to base_url, retain cookies, and offer synchronous or awaited request methods. — [httpx/_client.py#L340-L443](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L340-L443) [httpx/_client.py#L1751-L1778](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L1751-L1778) [docs/advanced/clients.md#L21-L28](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/docs/advanced/clients.md#L21-L28)
- Response offers decoded bytes, text, JSON, links, cookies, HTTP metadata, status predicates, and explicit raise_for_status(); the latter raises for any non-success response and requires an associated request. — [httpx/_models.py#L611-L672](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L611-L672) [httpx/_models.py#L794-L852](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L794-L852)
- Uploads support raw strings/bytes, sync or async byte iterables, URL-encoded forms, compact UTF-8 JSON, and multipart files with optional filename, content type, and per-part headers. — [httpx/_content.py#L107-L157](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_content.py#L107-L157) [httpx/_content.py#L176-L218](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_content.py#L176-L218) [httpx/_multipart.py#L122-L169](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_multipart.py#L122-L169)
- Streaming responses expose raw bytes, decompressed bytes, incremental text and lines, plus corresponding async methods; gzip/deflate are built in and Brotli/Zstandard decoders depend on installed extras. — [httpx/_models.py#L884-L959](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L884-L959) [httpx/_models.py#L982-L1035](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L982-L1035) [httpx/_decoders.py#L381-L393](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_decoders.py#L381-L393)
- Authentication supports Basic, Digest, explicit NetRCAuth, callable request transforms, and custom Auth flows. Redirect following is optional, with history and next_request available for automatic or manual navigation. — [httpx/_auth.py#L19-L32](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_auth.py#L19-L32) [httpx/_auth.py#L113-L172](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_auth.py#L113-L172) [httpx/_auth.py#L193-L222](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_auth.py#L193-L222) [httpx/_client.py#L964-L999](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L964-L999)
- Transport configuration exposes HTTP/1 and opt-in HTTP/2, HTTP/HTTPS/SOCKS proxies, TLS contexts, four timeout categories, connection limits, socket options, local addresses, Unix sockets, and connection-error retries; ASGI/WSGI transports call local apps. — [httpx/_transports/default.py#L135-L210](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/default.py#L135-L210) [httpx/_config.py#L72-L138](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_config.py#L72-L138) [docs/advanced/transports.md#L1-L23](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/docs/advanced/transports.md#L1-L23) [httpx/_transports/asgi.py#L63-L97](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/asgi.py#L63-L97)
- The CLI accepts URL, method, body/query/header/cookie/auth options, proxy, timeout, redirects, TLS verification toggle, HTTP/2, download destination, and verbose tracing; it renders text/JSON or a binary-size summary and exits according to response success. — [httpx/_main.py#L41-L99](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_main.py#L41-L99) [httpx/_main.py#L170-L186](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_main.py#L170-L186) [httpx/_main.py#L475-L506](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_main.py#L475-L506)

## Data flow

Request construction turns caller inputs into normalized URL, header, cookie, extension, and stream objects. Authentication and redirect loops can produce additional exchanges before the final response reaches the caller. Transports preserve raw protocol data and delegate network execution, while response models decode and optionally buffer bodies. State persists through the client cookie jar and connection pools; CLI downloads explicitly write decoded content.
- build_request() merges URL, headers, cookies, and query parameters, inserts a timeout extension unless already supplied, then constructs Request with the merged values and body inputs. — [httpx/_client.py#L366-L389](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L366-L389)
- URL construction validates component types and invokes urlparse(); normalization lowercases scheme, encodes hosts, normalizes ports and paths, and preserves the distinction between absent and empty query strings. — [httpx/_urls.py#L77-L124](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_urls.py#L77-L124) [httpx/_urlparse.py#L293-L345](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_urlparse.py#L293-L345)
- Request uppercases the method, copies extensions, applies cookie headers, and invokes encode_request(); body selection prefers explicit content, then files, nonempty form data, and JSON, with a deprecated raw-data compatibility branch. — [httpx/_models.py#L398-L423](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L398-L423) [httpx/_content.py#L186-L218](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_content.py#L186-L218)
- Body encoders return headers plus a byte stream: known lengths use Content-Length, unknown iterable lengths use chunked transfer, and multipart length becomes unknown when any file length cannot be determined. — [httpx/_content.py#L107-L131](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_content.py#L107-L131) [httpx/_multipart.py#L265-L300](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_multipart.py#L265-L300) [httpx/_models.py#L441-L460](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L441-L460)
- send() resolves timeout/auth policy; each exchange runs request hooks, dispatches through the URL-selected transport, runs response hooks, and either returns, follows a redirect, or exposes next_request. — [httpx/_client.py#L899-L925](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L899-L925) [httpx/_client.py#L964-L999](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L964-L999) [httpx/_client.py#L1001-L1014](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L1001-L1014)
- HTTPTransport converts raw scheme, host, port, request target, headers, stream, and extensions into httpcore.Request; pool output becomes Response with wrapped response stream and preserved extensions. — [httpx/_transports/default.py#L237-L259](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/default.py#L237-L259)
- The client attaches the originating request, binds elapsed-time tracking to stream closure, extracts Set-Cookie into its jar, and supplies default text encoding; subsequent requests obtain Cookie headers through CookieJar adapters. — [httpx/_client.py#L139-L159](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L139-L159) [httpx/_client.py#L1016-L1024](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L1016-L1024) [httpx/_models.py#L1101-L1115](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L1101-L1115) [httpx/_models.py#L1243-L1277](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L1243-L1277)
- iter_raw() counts received bytes; iter_bytes() applies content decoding and chunking; read() joins decoded chunks into cached content. CLI download_response() writes iter_bytes() chunks while reporting raw-byte progress. — [httpx/_models.py#L876-L905](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L876-L905) [httpx/_models.py#L935-L959](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L935-L959) [httpx/_main.py#L251-L270](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_main.py#L251-L270)

## Behavior traces

These traces follow implementation call order rather than executing scenarios. They cover client startup, an ordinary network request, redirects, authentication retries, cookie persistence, asynchronous application dispatch, and CLI downloads. Cleanup paths determine when connections are released and elapsed time becomes available. Each trace retains material branches such as disabled redirects, streaming mode, and application exceptions.
- Startup: Client.__init__() calls BaseClient.__init__(), checks the h2 dependency when HTTP/2 is enabled, computes proxy mappings, initializes the transport, constructs and sorts mounts; __enter__() changes state to OPENED and enters configured transports. — [httpx/_client.py#L663-L716](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L663-L716) [httpx/_client.py#L1275-L1291](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L1275-L1291)
- Ordinary GET: _api.get() → request() → temporary Client → Client.request() → build_request() → send() → auth loop → redirect loop → _send_single_request() → HTTPTransport.handle_request() → httpcore pool → Response.read(). — [httpx/_api.py#L195-L207](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_api.py#L195-L207) [httpx/_api.py#L102-L120](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_api.py#L102-L120) [httpx/_client.py#L811-L925](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L811-L925) [httpx/_transports/default.py#L230-L259](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/default.py#L230-L259)
- Redirect: after response hooks, _send_handling_redirects() invokes _build_redirect_request(), which computes method, URL, headers, stream, and jar cookies. Following consumes the previous body and loops; otherwise next_request is set, and excessive history raises TooManyRedirects. — [httpx/_client.py#L475-L515](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L475-L515) [httpx/_client.py#L964-L999](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L964-L999)
- Digest challenge: DigestAuth.auth_flow() yields the initial request, checks a 401 for a Digest challenge, parses and caches it, builds Authorization, applies challenge-response cookies, and yields a retry; the client reads intermediate responses and adds them to auth history. — [httpx/_auth.py#L193-L222](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_auth.py#L193-L222) [httpx/_client.py#L938-L961](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L938-L961)
- Cookie persistence: response dispatch calls extract_cookies(); a redirect copies the client jar and removes the previous Cookie header before Request rebuilds it. The inspected login/logout test follows a Set-Cookie redirect, reuses the session, then expires it. — [httpx/_client.py#L475-L491](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L475-L491) [httpx/_client.py#L546-L571](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L546-L571) [httpx/_client.py#L1016-L1024](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L1016-L1024) [tests/client/test_redirects.py#L403-L431](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/client/test_redirects.py#L403-L431)
- Async ASGI request: AsyncClient.send() → async auth/redirect loops → _send_single_request() → ASGITransport.handle_async_request(); scope and receive/send callbacks bridge the request to await app(), then collected body parts become an ASGIResponseStream and aread() buffers the result unless streaming. — [httpx/_client.py#L1625-L1639](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L1625-L1639) [httpx/_client.py#L1717-L1738](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L1717-L1738) [httpx/_transports/asgi.py#L105-L187](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/asgi.py#L105-L187)
- CLI download: Click opens the destination in wb mode; main() infers GET or POST when method is omitted, creates Client and its streaming context, installs a trace callback, calls download_response(), and exits 0 for a successful response or 1 otherwise. — [httpx/_main.py#L431-L435](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_main.py#L431-L435) [httpx/_main.py#L475-L506](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_main.py#L475-L506) [httpx/_main.py#L251-L270](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_main.py#L251-L270)
- Cleanup: Client.stream()/AsyncClient.stream() close responses in finally; complete raw iteration also closes them. Bound streams record elapsed time and close the underlying stream, while client close/aclose closes the default and mounted transports and marks the client CLOSED. — [httpx/_client.py#L139-L182](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L139-L182) [httpx/_client.py#L869-L877](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L869-L877) [httpx/_client.py#L1583-L1592](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L1583-L1592) [httpx/_client.py#L1978-L1988](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L1978-L1988)

## Testing signals

Tests and CI were inspected, not executed; test existence and configured thresholds are not passing results. The suite uses pytest, AnyIO-marked async tests, mock transports, and local Uvicorn servers. Inspected cases exercise important policy, streaming, CLI, and timeout behavior. Coverage exclusions and filtered conformance fixtures limit what the advertised coverage goal establishes, and this investigation is bounded rather than exhaustive.
- pytest is pinned in tooling requirements; pyproject configures warnings as errors and a network marker, while async tests use pytest.mark.anyio and test helpers accommodate asyncio and Trio. — [requirements.txt#L20-L29](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/requirements.txt#L20-L29) [pyproject.toml#L117-L128](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/pyproject.toml#L117-L128) [tests/test_timeouts.py#L6-L27](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/test_timeouts.py#L6-L27) [tests/concurrency.py#L11-L15](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/concurrency.py#L11-L15)
- The inspected Test Suite workflow runs on Ubuntu with Python 3.9–3.13 and calls install, check, build, test, and coverage scripts. No execution result was obtained for this commit. — [.github/workflows/test-suite.yml#L10-L34](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/.github/workflows/test-suite.yml#L10-L34)
- scripts/test runs pytest under coverage and adds check/coverage steps outside GitHub Actions; coverage includes httpx and tests and enforces fail-under=100. Certificate environment branches and several CLI TLS/HTTP2 trace branches carry coverage exclusions. — [scripts/test#L10-L18](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/scripts/test#L10-L18) [scripts/coverage#L11-L11](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/scripts/coverage#L11-L11) [pyproject.toml#L130-L132](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/pyproject.toml#L130-L132) [httpx/_main.py#L223-L248](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_main.py#L223-L248)
- MockTransport redirect tests assert cross-domain Authorization removal, same-domain retention and HTTP-to-HTTPS retention, 308 body preservation, 303 body removal, generator replay failure, and login/logout cookie persistence. — [tests/client/test_redirects.py#L266-L334](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/client/test_redirects.py#L266-L334) [tests/client/test_redirects.py#L345-L361](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/client/test_redirects.py#L345-L361) [tests/client/test_redirects.py#L403-L431](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/client/test_redirects.py#L403-L431)
- Hook tests check sync/async request and response events, closure after response-hook exceptions, and repeated hook invocation on redirects; auth tests explicitly expect unsupported Digest auth-int and consumed async-body replay failures. — [tests/client/test_event_hooks.py#L51-L115](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/client/test_event_hooks.py#L51-L115) [tests/client/test_event_hooks.py#L118-L138](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/client/test_event_hooks.py#L118-L138) [tests/client/test_auth.py#L505-L512](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/client/test_auth.py#L505-L512) [tests/client/test_auth.py#L688-L707](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/client/test_auth.py#L688-L707)
- CLI tests use CliRunner with a local server to assert text/JSON/binary output, redirects, POST JSON, verbose authorization output, downloads in an isolated filesystem, and unsupported-protocol exit behavior. — [tests/test_main.py#L17-L118](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/test_main.py#L17-L118) [tests/test_main.py#L121-L187](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/test_main.py#L121-L187) [tests/conftest.py#L283-L287](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/conftest.py#L283-L287)
- Timeout tests exercise read, write, connection and pool failures; the connection case is network-marked and targets 10.255.255.1, while the pool case holds a stream with max_connections=1 before issuing a second request. — [tests/test_timeouts.py#L6-L44](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/test_timeouts.py#L6-L44) [tests/conftest.py#L101-L110](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/conftest.py#L101-L110)
- Decoder tests assert decompression, stacked encodings, invalid-data errors, streaming text and split-line behavior; WHATWG URL tests omit fixture failure cases and return early for two space-encoding cases, so that adapter is not full WHATWG conformance coverage. — [tests/test_decoders.py#L14-L88](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/test_decoders.py#L14-L88) [tests/test_decoders.py#L144-L201](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/test_decoders.py#L144-L201) [tests/test_decoders.py#L222-L231](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/test_decoders.py#L222-L231) [tests/models/test_whatwg.py#L13-L28](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/models/test_whatwg.py#L13-L28)

## Risk map

The following are source observations and one explicitly labeled resource-risk hypothesis, not confirmed vulnerabilities. Sensitive boundaries include outbound routing, certificate trust, credentials, redirects, stream ownership, and filesystem downloads. Several restrictions are intentional compatibility or API limits with corresponding tests. Documentation drift and excluded branches also matter when an agent assesses behavior.
- Verbose CLI tracing prints raw request headers, including reversible Basic Authorization; help text warns about this and test_auth asserts the exposed header. Headers.__repr__ masking therefore does not imply CLI output redaction. — [httpx/_main.py#L116-L126](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_main.py#L116-L126) [httpx/_main.py#L235-L240](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_main.py#L235-L240) [httpx/_main.py#L385-L389](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_main.py#L385-L389) [tests/test_main.py#L145-L160](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/test_main.py#L145-L160)
- trust_env defaults true; environment/system proxy discovery can alter routing, and SSL_CERT_FILE/SSL_CERT_DIR can replace default certificate locations. Custom transports disable automatic environment-proxy discovery, while explicit proxy configuration remains supported. — [httpx/_client.py#L639-L650](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L639-L650) [httpx/_client.py#L685-L687](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L685-L687) [httpx/_utils.py#L30-L76](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_utils.py#L30-L76) [httpx/_config.py#L33-L40](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_config.py#L33-L40)
- verify=False explicitly disables hostname checking and certificate verification. NetRCAuth loads a caller-selected or default netrc file at construction, and deprecated cert arguments load certificate chains from external paths. — [httpx/_config.py#L41-L44](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_config.py#L41-L44) [httpx/_config.py#L58-L67](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_config.py#L58-L67) [httpx/_auth.py#L145-L166](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_auth.py#L145-L166)
- Redirect authorization policy depends on scheme, host and effective port; Authorization survives only same-origin redirects or the defined same-host HTTP:80-to-HTTPS:443 upgrade exception. Redirect requests also discard the original Cookie header and rebuild cookies from the jar. — [httpx/_client.py#L62-L91](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L62-L91) [httpx/_client.py#L546-L571](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L546-L571) [tests/client/test_redirects.py#L266-L308](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/client/test_redirects.py#L266-L308)
- Manual stream=True callers must arrange response closure, and generator request bodies can raise StreamConsumed when redirected or retried for Digest authentication; inspected tests encode both replay restrictions. — [docs/async.md#L87-L105](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/docs/async.md#L87-L105) [httpx/_content.py#L50-L64](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_content.py#L50-L64) [tests/client/test_redirects.py#L345-L361](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/client/test_redirects.py#L345-L361) [tests/client/test_auth.py#L688-L707](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/client/test_auth.py#L688-L707)
- Resource-risk hypothesis: large or highly compressed responses can demand substantial memory because read()/aread() join decoded bodies, ASGITransport collects response parts, and its stream joins them. Connection Limits do not impose a body-size bound in these inspected paths. (inferred) — [httpx/_models.py#L876-L905](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L876-L905) [httpx/_models.py#L974-L980](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L974-L980) [httpx/_transports/asgi.py#L55-L60](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/asgi.py#L55-L60) [httpx/_transports/asgi.py#L158-L185](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/asgi.py#L158-L185) [httpx/_config.py#L159-L182](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_config.py#L159-L182)
- Digest authentication retains challenge and nonce-counter state and deliberately rejects auth-int-only challenges with NotImplementedError; a test expects that failure, so auth-int must not be described as supported. — [httpx/_auth.py#L187-L222](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_auth.py#L187-L222) [httpx/_auth.py#L329-L340](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_auth.py#L329-L340) [tests/client/test_auth.py#L505-L512](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/client/test_auth.py#L505-L512)
- The WSGITransport docstring still recommends Client(app=app), but the inspected Client constructor accepts transport and has no app argument. This concrete documentation drift makes constructor source a necessary check before copying examples. — [httpx/_transports/wsgi.py#L44-L64](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/wsgi.py#L44-L64) [httpx/_client.py#L639-L662](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L639-L662)

## Extension points

Extension is primarily explicit object injection rather than automatic plugin discovery. Transports replace execution, mounts route execution, and Auth generators implement multi-exchange credential behavior. Hooks and extensions add observation and transport-specific metadata without changing the simplified Request/Response model. Internal decoder registries and the CLI option table provide additional edit locations, with public exports checked separately.
- Custom transports subclass BaseTransport.handle_request() or AsyncBaseTransport.handle_async_request(), return Response, and implement close/aclose when they own resources; Client._init_transport() returns an injected transport directly. — [httpx/_transports/base.py#L26-L62](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/base.py#L26-L62) [httpx/_transports/base.py#L65-L86](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/base.py#L65-L86) [httpx/_client.py#L718-L738](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L718-L738)
- mounts maps URL patterns to transports or None; explicit entries update proxy-derived mounts, sorting uses URLPattern priority, and the first match selects its transport or falls back to the default for None. — [httpx/_client.py#L698-L716](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L698-L716) [httpx/_client.py#L760-L769](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L760-L769) [httpx/_utils.py#L192-L223](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_utils.py#L192-L223)
- Auth.auth_flow() is a Request/Response generator protocol supporting multiple exchanges; requires_request_body and requires_response_body trigger buffering, and I/O-bearing schemes can override sync_auth_flow()/async_auth_flow(). — [httpx/_auth.py#L22-L36](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_auth.py#L22-L36) [httpx/_auth.py#L38-L110](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_auth.py#L38-L110)
- Client event_hooks registers lists under request and response, can be changed through the property, and may mutate models. AsyncClient awaits hooks; response hooks needing content must explicitly read or await aread(). — [httpx/_client.py#L262-L270](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L262-L270) [httpx/_client.py#L1691-L1697](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L1691-L1697) [docs/advanced/event-hooks.md#L33-L65](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/docs/advanced/event-hooks.md#L33-L65)
- Request/Response extensions are an untyped transport-specific channel; the default transport forwards them, documented request keys include timeout and trace, and response network_stream permits lower-level connection access. — [docs/advanced/extensions.md#L3-L5](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/docs/advanced/extensions.md#L3-L5) [docs/advanced/extensions.md#L34-L48](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/docs/advanced/extensions.md#L34-L48) [docs/advanced/extensions.md#L121-L139](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/docs/advanced/extensions.md#L121-L139) [docs/advanced/extensions.md#L204-L216](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/docs/advanced/extensions.md#L204-L216)
- MockTransport injects a Request-to-Response handler, reads the request body before dispatch, and allows async clients to use either sync or coroutine handlers; sync clients reject an async handler result. — [httpx/_transports/mock.py#L8-L43](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_transports/mock.py#L8-L43)
- SUPPORTED_DECODERS maps content-encoding names to ContentDecoder classes and drops unavailable optional codecs; Response selects and combines those decoders. default_encoding separately accepts a callable over buffered bytes for text detection. — [httpx/_decoders.py#L36-L41](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_decoders.py#L36-L41) [httpx/_decoders.py#L381-L393](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_decoders.py#L381-L393) [httpx/_models.py#L653-L672](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L653-L672) [httpx/_models.py#L699-L722](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L699-L722)
- CLI options are defined by Click decorators around main(), while package-level symbols are curated in __all__; test_all_imports_are_exported checks that public imports match the sorted export list. — [httpx/_main.py#L313-L363](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_main.py#L313-L363) [httpx/_main.py#L431-L452](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_main.py#L431-L452) [httpx/__init__.py#L29-L100](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/__init__.py#L29-L100) [tests/test_exported_members.py#L4-L13](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/test_exported_members.py#L4-L13)

## Contributor handoff

Tests and CI were inspected, not executed, and this brief is a bounded source investigation rather than an exhaustive audit. Start at the public entrypoint and follow the specific policy, model, and transport boundary involved in the task. Preserve synchronous/asynchronous parity, stream ownership, request-merging rules, and explicit disabling semantics. Verification commands below describe the repository workflow for a separately authorized execution task; publication is a distinct external action.
- Read pyproject.toml, __init__.py and _api.py before altering entrypoints: optional extras determine CLI/protocol availability, public exports are explicit, and top-level request helpers own temporary client lifetime. — [pyproject.toml#L38-L59](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/pyproject.toml#L38-L59) [httpx/__init__.py#L14-L26](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/__init__.py#L14-L26) [httpx/__init__.py#L29-L100](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/__init__.py#L29-L100) [httpx/_api.py#L102-L120](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_api.py#L102-L120)
- Client dispatch fixes need parity review in both send/auth/redirect pipelines; shared URL/header/cookie redirect transformations live on BaseClient, while sync and async hooks and stream operations differ. — [httpx/_client.py#L475-L582](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L475-L582) [httpx/_client.py#L930-L999](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L930-L999) [httpx/_client.py#L1645-L1715](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L1645-L1715)
- Preserve build_request() versus send() behavior: construction merges client defaults, but manually constructed requests bypass that merge. send() still sets missing timeout metadata and resolves authentication policy. — [httpx/_client.py#L355-L389](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L355-L389) [httpx/_client.py#L888-L913](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L888-L913) [httpx/_client.py#L584-L591](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L584-L591)
- USE_CLIENT_DEFAULT distinguishes omission from explicit None for auth and timeout; relative request URLs append to a slash-normalized base path rather than replacing it. These semantics are deliberate and documented in implementation. — [httpx/_client.py#L94-L110](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L94-L110) [httpx/_client.py#L391-L411](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L391-L411) [httpx/_client.py#L457-L473](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L457-L473)
- Treat stream cleanup and replay as acceptance criteria: stream contexts close in finally, raw iteration rejects closed/consumed streams, and generator redirects have a regression case expecting StreamConsumed. — [httpx/_client.py#L869-L877](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L869-L877) [httpx/_client.py#L1583-L1592](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L1583-L1592) [httpx/_models.py#L935-L972](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L935-L972) [tests/client/test_redirects.py#L345-L361](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/tests/client/test_redirects.py#L345-L361)
- For separately authorized execution, the documented focused command is scripts/test -- tests/test_multipart.py; arguments reach pytest, but local execution also runs global checks and a 100-percent coverage gate. Test servers require ports 8000 and 8001. — [.github/CONTRIBUTING.md#L59-L78](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/.github/CONTRIBUTING.md#L59-L78) [scripts/test#L10-L18](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/scripts/test#L10-L18) [scripts/coverage#L11-L11](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/scripts/coverage#L11-L11)
- Repository checks enforce changelog/version agreement, Ruff formatting and lint, and strict mypy over httpx and tests; QueryParams is immutable, and per-request client cookies emit a deprecation warning. — [scripts/check#L7-L14](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/scripts/check#L7-L14) [scripts/sync-version#L3-L10](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/scripts/sync-version#L3-L10) [httpx/_urls.py#L631-L641](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_urls.py#L631-L641) [httpx/_client.py#L804-L810](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L804-L810) [pyproject.toml#L108-L110](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/pyproject.toml#L108-L110)
- Build and release are separate boundaries: scripts/build creates distributions and docs; scripts/publish uploads distributions and force-deploys docs, and the Publish workflow responds to pushed tags. None of these commands was executed during this investigation. — [scripts/build#L11-L13](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/scripts/build#L11-L13) [scripts/publish#L25-L26](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/scripts/publish#L25-L26) [.github/workflows/publish.yml#L3-L26](https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/.github/workflows/publish.yml#L3-L26)

Source repository: https://github.com/encode/httpx
Full evidence corpus: https://github.com/Codevetter/codevetter/tree/main/benchmarks/repo-unpacks/httpx.json

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
