Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add assert error for requires() when request param is not Request type#3298

Merged
Kludex merged 2 commits into
Kludex:mainfrom
KeeganOP:requires_assert_error
May 30, 2026
Merged

Add assert error for requires() when request param is not Request type#3298
Kludex merged 2 commits into
Kludex:mainfrom
KeeganOP:requires_assert_error

Conversation

@KeeganOP

@KeeganOP KeeganOP commented May 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Adding requires('scope') to a function that has a request param that is not of type Request currently throws an AssertionError:

  File ".venv/lib/python3.14/site-packages/anyio/_backends/_asyncio.py", line 1002, in run
    result = context.run(func, *args)
  File ".venv/lib/python3.14/site-packages/starlette/authentication.py", line 79, in sync_wrapper
    assert isinstance(request, Request)
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^
AssertionError

Which isn't much of a problem specifically in starlette since all functions that handle post requests will do so from accessing request.json(). However, in fastapi, body parameters are pydantic models that can be any name and type, including request.

This change is to add a message to the assert to better communicate what the issue might be for the case where the request parameter is not of type Request:

  File ".venv/lib/python3.14/site-packages/anyio/_backends/_asyncio.py", line 1002, in run
    result = context.run(func, *args)
  File ".venv/lib/python3.14/site-packages/starlette/authentication.py", line 84, in sync_wrapper
    assert isinstance(request, Request), (
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^
AssertionError: Parameter with name 'request' is required to be of type 'Request' not 'ExampleRequest'

MRE:

import fastapi
import uvicorn
from starlette.authentication import AuthenticationBackend, AuthCredentials, SimpleUser, requires
from starlette.middleware import Middleware
from starlette.middleware.authentication import AuthenticationMiddleware
from starlette.responses import PlainTextResponse
import pydantic


class ExampleRequest(pydantic.BaseModel):
    name: str


class BasicAuthBackend(AuthenticationBackend):
    async def authenticate(self, conn):
        return AuthCredentials(["authenticated"]), SimpleUser("username")


middleware = [
    Middleware(AuthenticationMiddleware, backend=BasicAuthBackend())
]

app = fastapi.FastAPI(middleware=middleware)



@app.post("/")
@requires("authenticated")
def example(request: ExampleRequest):
    return PlainTextResponse(f'Hello, {request.name}!')


uvicorn.run(app, host='0.0.0.0', port=8000)
curl -X 'POST' \
  'http://127.0.0.1:8000/' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "string"
}'

Changing request: ExampleRequest to body: ExampleRequest and adding a request: Request to the function params above works fine.

Checklist

  • I understand that this PR may be closed in case there was no previous discussion. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change. non functional change
  • I've updated the documentation accordingly.

@KeeganOP KeeganOP force-pushed the requires_assert_error branch from a2677ad to 64ede9b Compare May 28, 2026 12:14

@Kludex Kludex left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

@Kludex

Kludex commented May 30, 2026

Copy link
Copy Markdown
Owner

We should probably use raise TypeError instead, and have tests here, but this seems impossible (?) using pure Starlette.

@Kludex Kludex enabled auto-merge (squash) May 30, 2026 23:47
@Kludex Kludex merged commit 1478775 into Kludex:main May 30, 2026
9 checks passed
@Kludex Kludex mentioned this pull request May 31, 2026
@KeeganOP

Copy link
Copy Markdown
Contributor Author

We should probably use raise TypeError instead, and have tests here, but this seems impossible (?) using pure Starlette.

Agreed, I don't think its possible with pure Starlette and rather a consequence of how FastAPI handles params. I did look into if there's a way to improve that handling inside of FastAPI and somehow inject the Request but unfortunately since @requires is a decorator its difficult to get the object when its not a param to the function without changing the API for both the requires functionality and how FastAPI (or any other lib built on top of starlette) resolves / injects. I'll have a think on this and open a discussion if I can think of a better way.

@KeeganOP KeeganOP mentioned this pull request May 31, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants