psf/requests · error · NotImplementedError
Auth hooks must be callable.
Error message
Auth hooks must be callable.
What it means
Raised by the base AuthBase.__call__ when an auth object is invoked but the subclass did not override __call__. Every concrete auth handler must accept a PreparedRequest and return it (possibly mutated). This NotImplementedError signals a contract violation: an AuthBase subclass was instantiated without implementing the hook that applies credentials to the outgoing request.
Solutions
- Implement __call__(self, r: PreparedRequest) -> PreparedRequest on your AuthBase subclass, mutating r.headers with your credentials and returning r.
- If you only need HTTP Basic/Digest, use requests.auth.HTTPBasicAuth / HTTPDigestAuth instead of subclassing.
- Verify the instance is callable before passing it to auth= (inspect it via callable(auth)).
Example fix
// before
class MyAuth(requests.auth.AuthBase):
def __init__(self, token):
self.token = token
// after
class MyAuth(requests.auth.AuthBase):
def __init__(self, token):
self.token = token
def __call__(self, r):
r.headers['Authorization'] = f'Bearer {self.token}'
return r Defensive patterns
Strategy: type-guard
Validate before calling
from requests.auth import AuthBase
def is_valid_auth(auth) -> bool:
return isinstance(auth, AuthBase) and callable(getattr(type(auth), '__call__', None)) and type(auth).__call__ is not AuthBase.__call__ Type guard
from requests.auth import AuthBase
def implements_call(auth: AuthBase) -> bool:
"""True iff the instance's class overrides AuthBase.__call__."""
return '__call__' in type(auth).__dict__ or any(
'__call__' in vars(base) for base in type(auth).__mro__[1:-1]
) Try / catch
from requests.auth import AuthBase
if not (isinstance(auth, AuthBase) and type(auth).__call__ is not AuthBase.__call__):
raise TypeError('auth must be an AuthBase subclass that overrides __call__')
session.request(..., auth=auth) Prevention
- Always override __call__ when subclassing AuthBase; treat it as an abstract method.
- Prefer built-in HTTPBasicAuth/HTTPDigestAuth unless you need custom logic.
- Add an abstractmethod decorator in your base to surface the requirement at instantiation time.
When it happens
Trigger: Subclassing requests.auth.AuthBase and calling the instance as a function (auth_hook(prepared_request)) without defining __call__; passing a partially-implemented AuthBase subclass to the auth= parameter of requests.get/Session.request; instantiating AuthBase directly and invoking it.
Common situations: Building a custom token-injection auth scheme (e.g. Bearer, AWS SigV4) and forgetting to implement __call__; copy-pasting an auth class from docs that only overrode __eq__; version upgrades where a previously-abstract method was removed from the subclass.
Related errors
- Cookie headers should be added with…
- Streamed bodies and files are mutually exclusive.
- {e}
- {e.args}
- Invalid URL : No host supplied
AI-assisted analysis of psf/requests@8068356288 (2026-08-11).
Data as JSON: /api/errors/0ed909bfab5e8c8f.
Report an issue: GitHub.
Appendix: source
Thrown at src/requests/auth.py:82
if isinstance(username, str):
username = username.encode("latin1")
if isinstance(password, str):
password = password.encode("latin1")
authstr = "Basic " + to_native_string(
b64encode(b":".join((username, password))).strip()
)
return authstr
class AuthBase:
"""Base class that all auth implementations derive from"""
def __call__(self, r: PreparedRequest) -> PreparedRequest:
raise NotImplementedError("Auth hooks must be callable.")
class HTTPBasicAuth(AuthBase):
"""Attaches HTTP Basic Authentication to the given Request object."""
username: bytes | str
password: bytes | str
@overload
def __init__(self, username: str, password: str) -> None: ...
@overload
def __init__(self, username: bytes, password: bytes) -> None: ...
def __init__(self, username: bytes | str, password: bytes | str) -> None:
self.username = username
self.password = password
def __eq__(self, other: object) -> bool:View on GitHub (pinned to 8068356288)