Example from documentation doesn't work
I tried to run the example from https://authx.yezz.me/get-started/basic-usage/ and got an error:
INFO: 127.0.0.1:18932 - "GET /login?username=test&password=test HTTP/1.1" 200 OK
INFO: 127.0.0.1:18980 - "GET /protected HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\uvicorn\protocols\http\httptools_impl.py", line 409, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\uvicorn\middleware\proxy_headers.py", line 60, in __call__
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\fastapi\applications.py", line 1054, in __call__
await super().__call__(scope, receive, send)
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\starlette\applications.py", line 113, in __call__
await self.middleware_stack(scope, receive, send)
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\starlette\middleware\errors.py", line 187, in __call__
raise exc
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\starlette\middleware\errors.py", line 165, in __call__
await self.app(scope, receive, _send)
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\starlette\middleware\exceptions.py", line 62, in __call__
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
raise exc
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\starlette\routing.py", line 715, in __call__
await self.middleware_stack(scope, receive, send)
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\starlette\routing.py", line 735, in app
await route.handle(scope, receive, send)
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\starlette\routing.py", line 288, in handle
await self.app(scope, receive, send)
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\starlette\routing.py", line 76, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
raise exc
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\starlette\routing.py", line 73, in app
response = await f(request)
^^^^^^^^^^^^^^^^
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\fastapi\routing.py", line 291, in app
solved_result = await solve_dependencies(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\fastapi\dependencies\utils.py", line 638, in solve_dependencies
solved = await call(**solved_result.values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\authx\main.py", line 619, in _auth_required
return await self._auth_required(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\authx\main.py", line 351, in _auth_required
request_token = await method(
^^^^^^^^^^^^^
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\authx\main.py", line 308, in get_access_token_from_request
return await self._get_token_from_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\authx\main.py", line 281, in _get_token_from_request
return await _get_token_from_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\nawas\PycharmProjects\fastapi_playground\.venv\Lib\site-packages\authx\core.py", line 156, in _get_token_from_request
raise MissingTokenError(*(str(err) for err in errors))
authx.exceptions.MissingTokenError: Missing 'Bearer' in 'Authorization' header.
I believe your second request is just curl -s http://0.0.0.0:8000/protected . You used this because it is under the Protected Routes - curl-without-jsonwebtoken section.
The error is on purpose, as it demonstrates an unauthorized request to a protected endpoint. If you want to see response to an authorized request, you should use the example under the tab "With a valid JsonWebToken".
This behaviour is actually explained under that very section:
In the curl requests above, a 401 HTTP Error is raised when the token is not valid. By default, AuthX triggers a 500 Internal Server Error HTTP Error. For the sake of simplicity, we won't delve into error handling in this section.
Example of a valid request (access token will be different in your case):
curl -s --oauth2-bearer eyJhbGciOiJIUzI1NiIsInR5cCI6...9vJcIWEE http://127.0.0.1:8000/protected
(I just tried it in local just to be sure that it still works. response: {"message":"Hello World"} )
Edit: I wanted to add that maybe you are looking for handling these exceptions automatically, in which case you should use auth.handle_errors(app) and (optionally) try&except as you can see here.
Hello @John2013 Yes I'm working on a big refactoring for the documentation!
cc @gokhanmeteerturk in case you want to open a Pull request to fix the issue 🚀
Hello, most of the examples in the documentation don't seem to work. For instance, the TokenPayload example from https://authx-git-docs-fix-yasser-tahiris-projects.vercel.app/get-started/payload/ doesn't function as expected.
Versions
Platform: Windows 11
Python: 3.13.2
fastapi: 0.115.14
authx: 1.4.3
Code
import requests
import uvicorn
from fastapi import FastAPI, Depends, HTTPException
from authx import AuthX, AuthXConfig, RequestToken, TokenPayload
app = FastAPI()
config = AuthXConfig(
JWT_ALGORITHM="HS256",
JWT_SECRET_KEY="4AA743755308486A17A322F93A59598C",
JWT_TOKEN_LOCATION=["headers"],
)
auth = AuthX(config=config)
auth.handle_errors(app)
@app.get('/token')
def get_token():
token = auth.create_access_token(uid="123", foo="bar", age=22)
return {"access_token": token}
@app.get('/profile')
def get_profile(payload: TokenPayload = Depends(auth.access_token_required)):
return {
"id": payload.sub,
"age": getattr(payload, "age"),
"foo": getattr(payload, "foo"),
}
@app.get("/protected")
def get_protected(token: RequestToken = Depends(auth.access_token_required)):
try:
# auth.verify_token(token=token)
return {"message": f"Hello world! {token.sub}"}
except Exception as e:
raise HTTPException(401, detail={"message": str(e)}) from e
def test_request():
response = requests.get("http://127.0.0.1:8000/token")
access_token = response.json().get("access_token")
print(access_token)
response = requests.get("http://127.0.0.1:8000/protected",
headers={"Authorization": f"Bearer {access_token}"})
print(response.json()) if response.status_code == 200 else print(response.text)
response = requests.get("http://127.0.0.1:8000/profile",
headers={"Authorization": f"Bearer {access_token}"})
print(response.json()) if response.status_code == 200 else print(response.status_code)
def main():
uvicorn.run(app, host="127.0.0.1", port=8000)
if __name__ == '__main__':
main()
Request
>>> from testtest import test_request2
>>> test_request2()
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJqdGkiOiI3Y2JkOTE5MS1hNTNkLTQ0NmUtODJkNy1iNDZhYThjNjY5OTAiLCJ0eXBlIjoiYWNjZXNzIiwiZnJlc2giOmZhbHNlLCJjc3JmIjoiIiwiaWF0IjoxNzU4MzU2NTE3LCJleHAiOjE3NTgzNTc0MTcuODY3ODF9.P0wNvgc8M6X-v6Qb4gmesTHqKMDqVztSJ0jvAdTUbAE
{'message': 'Hello world! 123'}
500
JWTDecode
{
"sub": "123",
"jti": "7cbd9191-a53d-446e-82d7-b46aa8c66990",
"type": "access",
"fresh": false,
"csrf": "",
"iat": 1758356517,
"exp": 1758357417.86781
}
Traceback
Traceback (most recent call last):
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 403, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
self.scope, self.receive, self.send
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\uvicorn\middleware\proxy_headers.py", line 60, in __call__
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\fastapi\applications.py", line 1054, in __call__
await super().__call__(scope, receive, send)
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\starlette\applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\starlette\middleware\errors.py", line 187, in __call__
raise exc
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\starlette\middleware\errors.py", line 165, in __call__
await self.app(scope, receive, _send)
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\starlette\middleware\exceptions.py", line 62, in __call__
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
raise exc
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\starlette\routing.py", line 714, in __call__
await self.middleware_stack(scope, receive, send)
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\starlette\routing.py", line 734, in app
await route.handle(scope, receive, send)
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\starlette\routing.py", line 288, in handle
await self.app(scope, receive, send)
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\starlette\routing.py", line 76, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
raise exc
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\starlette\routing.py", line 73, in app
response = await f(request)
^^^^^^^^^^^^^^^^
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\fastapi\routing.py", line 301, in app
raw_response = await run_endpoint_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...<3 lines>...
)
^
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\fastapi\routing.py", line 214, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\starlette\concurrency.py", line 37, in run_in_threadpool
return await anyio.to_thread.run_sync(func)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\anyio\to_thread.py", line 56, in run_sync
return await get_async_backend().run_sync_in_worker_thread(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
func, args, abandon_on_cancel=abandon_on_cancel, limiter=limiter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\anyio\_backends\_asyncio.py", line 2476, in run_sync_in_worker_thread
return await future
^^^^^^^^^^^^
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\anyio\_backends\_asyncio.py", line 967, in run
result = context.run(func, *args)
File "H:\WoLSite\testtest.py", line 29, in get_profile
"age": getattr(payload, "age"),
~~~~~~~^^^^^^^^^^^^^^^^
File "C:\Users\ibras\AppData\Local\pypoetry\Cache\virtualenvs\wol-api-4qW3MH0p-py3.13\Lib\site-packages\pydantic\main.py", line 991, in __getattr__
raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')
AttributeError: 'TokenPayload' object has no attribute 'age'