Open Stuwert opened 2 years ago
Not sure if this is what you're looking for, but I tried two different ways that retain the app.mount()
pattern:
1) Provide a callable to context_value
(this appears to be the intent looking at https://github.com/ciscorn/starlette-graphene3/blob/0.6.0/starlette_graphene3.py#L144 and https://github.com/ciscorn/starlette-graphene3/blob/0.6.0/tests/conftest.py#L98):
from starlette.background import BackgroundTasks
from fastapi import FastAPI
class Context(object):
def __init__(self, foo_resource):
self.foo_resource= foo_resource
async def __call__(self, request):
return {
"foo_resource": self.foo_resource,
"request": request, # provided to maintain previous default behavior
"background": BackgroundTasks(), # provided to maintain previous default behavior
}
foo_resource = get_foo()
graphql_app = GraphQLApp(schema=schema, context_value=Context(foo_resource))
app = FastAPI()
app.mount("/graphql", graphql_app)
2) Subclass GraphQLApp
and overload _get_context_value
:
from fastapi import FastAPI
class AugmentedGraphQLApp(GraphQLApp):
def __init__(self, *args, **kwargs):
foo_resource = kwargs.pop("foo_resource")
super().__init__(*args, **kwargs)
self.foo_resource = foo_resource
async def _get_context_value(self, request):
context = await super()._get_context_value(request)
context["foo_resource"] = self.foo_resource
return context
foo_resource = get_foo()
graphql_app = AugmentedGraphQLApp(schema=schema, foo_resource=foo_resource)
app = FastAPI()
app.mount("/graphql", graphql_app)
I was then able to use context["foo_resource"]
using both ways. Disclaimer: I was using graphene-sqlalchemy
, so in actuality I had to use info.context["foo_resource"]
. I know you were trying to avoid using the SQLAlchemy Graphene connection but I had to use another client (my foo_resource
contacting another server) on top of using graphene-sqlalchemy
in my project. I would think having the DB session as foo_resource
would work.
Edit: missing lines of code
I'm trying to understand the best way to inject the database as a dependency for my graphql queries/mutations.
It looks like context is the appropriate way to do so, and based on reviewing other issues raised on the starlette repo https://github.com/encode/starlette/issues/591, it sounds like the problem was never really solved. Given that starlette is deprecating graphql support and this repo appears to be filling in the gaps of that connection, it felt right to ask the question here.
The workaround described in issue 591 mentions adding the db session to the request via injection on the route, however, that appears to require calling execute on the GraphQL app directly, rather than the
app.mount()
pattern described in ythe README. I wasn't able to find another way attach the GraphQL app to appropriately, so I'm wondering if I'm missing something or if db dependency injection just isn't possible at the moment.Is this functionality currently possible to manage or is the expectation that the db will be accessed via things like the SQLAlchemy Graphene connection?