-
-
Notifications
You must be signed in to change notification settings - Fork 518
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom context_getter function overrides default context behaviour thus removing 'request' #1493
Comments
@tsmith023 sounds like something we should do, especially since we don't have a way to get the request from the context getter. Do you agree @Kludex? |
We'll need to perform some magic here if we want to inject information. @staticmethod
def __get_context_getter(
custom_getter: Callable[..., Optional[Dict[str, Any]]]
) -> Callable[..., Dict[str, Any]]:
async def dependency(
background_tasks: BackgroundTasks,
request: Request = None,
ws: WebSocket = None,
custom_getter: Optional[Dict[str, Any]] = None
)
return {"request": request or ws, "background_tasks": background_tasks, **custom_getter}
sig = signature(dependency)
sig = sig.replace(
parameters=[
*list(sig.parameters.values())[:-1],
sig.parameters["custom_getter"].replace(default=Depends(custom_getter))
]
)
dependency.__signature__ = sig
return dependency Then on the self.context_getter = self.__get_context_getter(context_getter) Notice that FastAPI will look at the signature to resolve the dependencies. That's why it looks "weird". A minimal working snippet with this solution: from fastapi import FastAPI, Request, Depends
from inspect import signature
from functools import partial
app = FastAPI()
def dependency(request: Request, context_getter: dict):
return {"request": request, **context_getter}
def context_getter():
return {"hi": "there"}
sig = signature(dependency)
sig = sig.replace(
parameters=[
*list(sig.parameters.values())[:-1],
sig.parameters["context_getter"].replace(default=Depends(context_getter))
]
)
dependency.__signature__ = sig
@app.get("/")
def home(dep = Depends(dependency)):
print(dep) |
@Kludex and @patrick91, thank you for your rapid response to this issue, especially on a Saturday evening! @Kludex, your solution works well in my application and I will leave that minimal solution for now while I proceed with the rest of the migration. Can I assume that this change will be integrated into the main package in a further feature update? |
@patrick91 is the one to ask that. |
I don't see why not 😊 would you be able to send a PR for this? 😊 |
Absolutely, I'd love to! I'll make sure the above solution works on my fork and then open the PR to be reviewed :) |
Hello strawberry devs. I've recently come across this package when desiring to move away from Graphene+Flask to Strawberry+FastAPI.
However, when I define a custom context_getter function like:
and call it in:
then the default context values of
'request'
and'background_tasks'
are overwritten by the custom context. Since I see no other way of passingrequest
down to theinfo.context
object outside of theGraphQLRouter
instance through the customcontext_getter
function, is this potentially a bug?I looked at the source code and saw that line 65 of strawberry/fastapi/router.py reads
self.context_getter = context_getter or self._get_context
where:which will naturally ignore the addition of
'request'
intoinfo.context
when there is a customcontext_getter
function.Since these are functions at this point, it is not simple to merge their results. However, further down on lines 88 and 136, these functions are injected as dependencies and passed to handlers on lines 123, 153, and 163. If separate
default_context
andcustom_context
variables were defined, could their results be merged at this point?The text was updated successfully, but these errors were encountered: