psf/requests · error · NotImplementedError

Auth hooks must be callable.

Error message

Auth hooks must be callable.

What it means

A NotImplementedError raised by AuthBase.__call__ in src/requests/auth.py. AuthBase is the abstract base for all Requests auth handlers; subclasses must override __call__(self, r) to modify and return the PreparedRequest (typically by setting r.headers['Authorization']). If the base implementation runs, either a subclass forgot the override or a non-callable was passed as auth.

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 414f0513c3)

Solutions

  1. Implement __call__(self, r) in your AuthBase subclass, mutate r (usually r.headers), and return r.
  2. For simple bearer tokens, skip the class entirely and pass headers={'Authorization': f'Bearer {token}'} or use a (user, pass) tuple for basic auth.
  3. Verify the method is named exactly __call__ with the (self, r) signature and that it returns the request.

Example fix

# before
class TokenAuth(requests.auth.AuthBase):
    def __init__(self, token):
        self.token = token
    def apply(self, r):  # wrong method name
        r.headers['Authorization'] = f'Bearer {self.token}'
        return r

# after
class TokenAuth(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

assert callable(auth) or isinstance(auth, tuple), 'auth must be callable (AuthBase) or a (user, pass) tuple'

Type guard

from requests.auth import AuthBase

def is_valid_auth(auth):
    return auth is None or callable(auth) or (isinstance(auth, tuple) and len(auth) == 2)

Try / catch

try:
    resp = session.get(url, auth=my_auth)
except ValueError as e:
    if 'callable' in str(e):
        raise TypeError('auth must implement __call__; subclass requests.auth.AuthBase') from e
    raise

Prevention

When it happens

Trigger: Passing auth=MyAuth() where MyAuth subclasses AuthBase without defining __call__ (or defines it with the wrong name/signature so the base method is hit); instantiating AuthBase directly as an auth handler in requests.get(url, auth=AuthBase()).

Common situations: Writing custom token/HMAC/signing auth classes and misspelling __call__ (e.g. defining call or authenticate instead); copying an example that only defines __init__; subclassing AuthBase for typing purposes and never implementing the hook.

Related errors


AI-assisted analysis of psf/requests@414f0513c3 (2026-07-31). Data as JSON: /data/errors/0ed909bfab5e8c8f.json. Report an issue: GitHub ↗.