{"record":{"id":"0ed909bfab5e8c8f","repo":"psf/requests","slug":"auth-hooks-must-be-callable","errorCode":null,"errorMessage":"Auth hooks must be callable.","messagePattern":"Auth hooks must be callable\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"src/requests/auth.py","lineNumber":82,"sourceCode":"\n    if isinstance(username, str):\n        username = username.encode(\"latin1\")\n\n    if isinstance(password, str):\n        password = password.encode(\"latin1\")\n\n    authstr = \"Basic \" + to_native_string(\n        b64encode(b\":\".join((username, password))).strip()\n    )\n\n    return authstr\n\n\nclass AuthBase:\n    \"\"\"Base class that all auth implementations derive from\"\"\"\n\n    def __call__(self, r: PreparedRequest) -> PreparedRequest:\n        raise NotImplementedError(\"Auth hooks must be callable.\")\n\n\nclass HTTPBasicAuth(AuthBase):\n    \"\"\"Attaches HTTP Basic Authentication to the given Request object.\"\"\"\n\n    username: bytes | str\n    password: bytes | str\n\n    @overload\n    def __init__(self, username: str, password: str) -> None: ...\n    @overload\n    def __init__(self, username: bytes, password: bytes) -> None: ...\n\n    def __init__(self, username: bytes | str, password: bytes | str) -> None:\n        self.username = username\n        self.password = password\n\n    def __eq__(self, other: object) -> bool:","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/psf/requests/blob/8068356288978c4f54661ae6f95afe0e0831885e/src/requests/auth.py#L64-L100","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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))."],"exampleFix":"// before\nclass MyAuth(requests.auth.AuthBase):\n    def __init__(self, token):\n        self.token = token\n\n// after\nclass MyAuth(requests.auth.AuthBase):\n    def __init__(self, token):\n        self.token = token\n    def __call__(self, r):\n        r.headers['Authorization'] = f'Bearer {self.token}'\n        return r","handlingStrategy":"type-guard","validationCode":"from requests.auth import AuthBase\n\ndef is_valid_auth(auth) -> bool:\n    return isinstance(auth, AuthBase) and callable(getattr(type(auth), '__call__', None)) and type(auth).__call__ is not AuthBase.__call__","typeGuard":"from requests.auth import AuthBase\n\ndef implements_call(auth: AuthBase) -> bool:\n    \"\"\"True iff the instance's class overrides AuthBase.__call__.\"\"\"\n    return '__call__' in type(auth).__dict__ or any(\n        '__call__' in vars(base) for base in type(auth).__mro__[1:-1]\n    )","tryCatchPattern":"from requests.auth import AuthBase\n\nif not (isinstance(auth, AuthBase) and type(auth).__call__ is not AuthBase.__call__):\n    raise TypeError('auth must be an AuthBase subclass that overrides __call__')\nsession.request(..., auth=auth)","preventionTips":["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."],"tags":["auth","notimplemented","authbase","subclassing","http"],"backgroundTag":null,"analyzedSha":"8068356288978c4f54661ae6f95afe0e0831885e","analyzedAt":"2026-08-11T20:11:09.238Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}