# Extension points — psf/requests

> Canonical page: https://codevetter.com/unpack/requests/extension-points

# Extension points — psf/requests

Scanned commit 611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60 (2026-09-21). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

There is one primary extension seam and several secondary ones. The primary is the Transport Adapter: `Session.mount(prefix, adapter)` keeps `self.adapters` sorted by descending prefix length and `get_adapter` picks the longest matching prefix, so any URL prefix can be routed to a `BaseAdapter` subclass — this is how retry policies, custom TLS contexts, and test doubles are injected. Secondary seams are the response hook system, the `AuthBase` callable protocol, the `SessionRedirectMixin` methods documented as overridable, and the packager-facing `certs.where()`. Nearly every private-looking `HTTPAdapter` method carries a docstring saying it exists specifically for subclass overrides.
- `Session.mount(prefix, adapter)` is the registry: it inserts into the `self.adapters` OrderedDict then re-pops every shorter key so adapters stay in descending prefix-length order. — [src/requests/sessions.py#L888-L896](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/sessions.py#L888-L896)
- `Session.get_adapter(url)` resolves by case-insensitive `startswith` over that ordered map, raising `InvalidSchema(f"No connection adapters were found for {url!r}")` when nothing matches — so registering a new scheme is purely a mount call. — [src/requests/sessions.py#L870-L881](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/sessions.py#L870-L881) [src/requests/exceptions.py#L114-L116](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/exceptions.py#L114-L116)
- `BaseAdapter` defines the minimal contract — `send(request, stream, timeout, verify, cert, proxies)` and `close()` — that any replacement transport must implement. — [src/requests/adapters.py#L122-L156](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/adapters.py#L122-L156)
- Eight `HTTPAdapter` methods are documented as subclass-override points rather than user API: `init_poolmanager`, `proxy_manager_for`, `cert_verify`, `build_response`, `get_connection_with_tls_context`, `request_url`, `add_headers`, and `proxy_headers`. — [src/requests/adapters.py#L239-L268](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/adapters.py#L239-L268) [src/requests/adapters.py#L365-L372](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/adapters.py#L365-L372) [src/requests/adapters.py#L599-L632](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/adapters.py#L599-L632)
- `HTTPAdapter.add_headers()` is an intentional empty hook — 'As of v2.0 this does nothing by default, but is left for overriding by users that subclass' — and is called on every send with the full kwargs. — [src/requests/adapters.py#L599-L612](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/adapters.py#L599-L612) [src/requests/adapters.py#L648-L655](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/adapters.py#L648-L655)
- `init_poolmanager(**pool_kwargs)` forwards arbitrary kwargs to `urllib3.PoolManager`, which is the documented way to inject a custom `ssl_context` or TLS version. — [src/requests/adapters.py#L239-L267](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/adapters.py#L239-L267) [docs/user/advanced.rst#L968-L1055](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/docs/user/advanced.rst#L968-L1055)
- The hook registry is the `HOOKS = ['response']` list in `hooks.py`, with `default_hooks()` building `{event: []}` and `dispatch_hook()` chaining callables so each non-None return replaces the data for the next hook. — [src/requests/hooks.py#L23-L48](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/hooks.py#L23-L48)
- Hooks can be attached per-request (`hooks=` kwarg), per-session (`Session.hooks`), or programmatically via `RequestHooksMixin.register_hook` / `deregister_hook`, which both `Request` and `PreparedRequest` inherit. — [src/requests/models.py#L254-L282](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/models.py#L254-L282) [src/requests/sessions.py#L456-L458](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/sessions.py#L456-L458)
- Custom auth plugs in via `AuthBase`, whose `__call__(self, r) -> PreparedRequest` raises `NotImplementedError` by default; `prepare_auth` treats any non-2-tuple auth value as such a callable. — [src/requests/auth.py#L78-L83](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/auth.py#L78-L83) [src/requests/models.py#L681-L691](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/models.py#L681-L691)
- `SessionRedirectMixin` is a separately-inheritable class exposing `get_redirect_target`, `should_strip_auth`, `resolve_redirects`, `rebuild_auth`, `rebuild_proxies` and `rebuild_method` — the tests subclass it directly as `RedirectSession` to exercise redirect logic without a network. — [src/requests/sessions.py#L127-L392](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/sessions.py#L127-L392) [tests/test_requests.py#L2608](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/tests/test_requests.py#L2608)
- `get_redirect_target`'s docstring explicitly invites a custom mixin that caches the redirect location on the response as a private attribute, acknowledging the method is called redundantly per hop. — [src/requests/sessions.py#L134-L140](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/sessions.py#L134-L140)
- `certs.where()` is the packager extension point: the module docstring instructs distributors to change its definition to return a separately packaged CA bundle. — [src/requests/certs.py](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/certs.py)
- Character-detection backends are pluggable at import: `_resolve_char_detection()` tries `chardet` then `charset_normalizer`, and `Response.apparent_encoding` degrades to a plain `utf-8` assumption if neither is installed. — [src/requests/compat.py#L36-L48](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/compat.py#L36-L48) [src/requests/models.py#L897-L904](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/models.py#L897-L904)
- The status-code table is data-driven: adding a code means adding an entry to the `_codes` dict, and `_init()` generates both lowercase and uppercase attributes plus the docstring table automatically. — [src/requests/status_codes.py#L22-L108](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/status_codes.py#L22-L108) [src/requests/status_codes.py#L109-L128](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/status_codes.py#L109-L128)
- Custom HTTP verbs need no new code — `Session.request(method, ...)` uppercases whatever string it is given, which is the documented 'Custom Verbs' capability. — [src/requests/sessions.py#L618-L625](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/src/requests/sessions.py#L618-L625) [docs/user/advanced.rst#L926-L944](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/docs/user/advanced.rst#L926-L944)
- Optional extras are declared as installable feature flags in `pyproject.toml`: `socks` (PySocks), `use_chardet_on_py3` (chardet), and a now-empty `security` extra kept for compatibility. — [pyproject.toml#L49-L54](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/pyproject.toml#L49-L54) [tox.ini](https://github.com/psf/requests/blob/611c6162cbc4ac2020a2f91c7cfa4f3abf9bbb60/tox.ini)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

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