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

  1. Implement __call__(self, r: PreparedRequest) -> PreparedRequest on your AuthBase subclass, mutating r.headers with your credentials and returning r.
  2. If you only need HTTP Basic/Digest, use requests.auth.HTTPBasicAuth / HTTPDigestAuth instead of subclassing.
  3. 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

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


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)