it's not working with django channels: ERROR: ASGI callable returned without starting response.
shmoon-kr opened this issue · comments
- [V ] Is it a bug?
- [V] Is it a question?
Description
I've set up django channels as described in the official documentation, but when I throw a query, I get the message
"ERROR: ASGI callable returned without starting response".
I think this is an issue with django channels, as the other parts are the same and it worked when I served it with GraphQLAsyncView.
django channels setting
arg_schema = JwtSchema(query=Query, mutation=Mutation, subscription=None)
websocket_urlpatterns = [
re_path("^graphql", channels_jwt_middleware(GraphQLWSConsumer.as_asgi(schema=arg_schema))),
]
gql_http_consumer = AuthMiddlewareStack(
channels_jwt_middleware(GraphQLHTTPConsumer.as_asgi(schema=arg_schema))
)
application = ProtocolTypeRouter(
{
"http": URLRouter(
[
re_path("^graphql", gql_http_consumer),
re_path("^", django_asgi_app),
]
),
"websocket": AuthMiddlewareStack(URLRouter(websocket_urlpatterns)),
}
)
-> got "ASGI callable returned without starting response" error
without channels
urlpatterns = [
path('admin/', admin.site.urls),
path("graphql/", AsyncGraphQLView.as_view(schema=schema)),
]
-> no problem
Am I missing something?
Sorry, I can't tell why isn't it working for you from just this code.
If you set a brake point at the middleware does it reaches there? does it exists correctly?
Yes.
I set a break point at if asyncio.iscoroutinefunction(inner):
line of the following function.
It reached at the breakpoint during application loading.
and variables are
database_sync_to_async = {type} <class 'channels.db.DatabaseSyncToAsync'>
context_to_thread_executor = {WeakKeyDictionary: 0} <WeakKeyDictionary at 0x75741b3fce80>
deadlock_context = {ContextVar} <ContextVar name='deadlock_context' at 0x75741b3ef790>
single_thread_executor = {ThreadPoolExecutor} <concurrent.futures.thread.ThreadPoolExecutor object at 0x75741b3fcd30>
thread_sensitive_context = {ContextVar} <ContextVar name='thread_sensitive_context' at 0x75741b3ef7e0>
threadlocal = {_local} <_thread._local object at 0x75741b3ef470>
inner = {function} <function GraphQLWSConsumer at 0x75741a2db880>
consumer_class = {type} <class 'strawberry.channels.handlers.ws_handler.GraphQLWSConsumer'>
consumer_initkwargs = {dict: 1} {'schema': """Date with time (isoformat)"""\nscalar DateTime\n\ntype DjangoModelType {\n pk: ID!\n}\n\n"\n Errors messages and codes mapped to\n fields or non fields errors.\n Example:\n {\n field_name: [\n {\n \"message\": \"error message\",\n \"code\": \"error_code\"\n }\n ],\n other_field: [\n {\n \"message\": \"error message\",\n \"code\": \"error_code\"\n }\n ],\n nonFieldErrors: [\n {\n \"message\": \"error message\",\n \"code\": \"error_code\"\n }\n ]\n }\n "\nscalar ExpectedError\n\ntype Mutation {\n "### Checks if a token is not expired and correct.\n\n *Note that this is not for refresh tokens.*\n "\n verifyToken(token: String!): VerifyTokenType!\n\n "Update user model fields, defined on settings.\n\n User must be verified.\n "\n updateAccount(firstName: String...
def channels_jwt_middleware(inner: Callable):
from channels.db import database_sync_to_async
if asyncio.iscoroutinefunction(inner):
get_user_or_error_async = database_sync_to_async(get_user_or_error)
async def middleware(scope, receive, send):
if not scope.get(USER_OR_ERROR_KEY, None):
user_or_error: UserOrError = await get_user_or_error_async(scope)
scope[USER_OR_ERROR_KEY] = user_or_error
return await inner(scope, receive, send)
else: # pragma: no cover
raise NotImplementedError("sync channels middleware is not supported yet.")
return middleware
It's a bit stange. When the application is starting, it reaches at the breakpoint. But when I resume it and submit a graphql query via graphiql, it doesn't reach there.
your revolvers are running correctly? BTW if you want you can contact me on discord nir_benlulu
Yes. Resolvers are working correctly because there's no problem in running with AsyncGraphQLView without channels.
I just setup a test project at github. https://github.com/shmoon-kr/channels-auth-test
If you have a moment, I'd appreciate it if you could take a look. Next time I'll contact you on discord.
try to change
urlpatterns = [
path('admin/', admin.site.urls),
path("graphql/", AsyncGraphQLView.as_view(schema=schema)),
]
to
urlpatterns = [
path('admin/', admin.site.urls),
path("graphql", AsyncGraphQLView.as_view(schema=schema)),
]
Django said something about post request 😕
Issue occurs here. The request object has no scope in it it's under request.consumer
And here context doesn't have a request object using getattr
on channels requests
strawberry-django-auth/gqlauth/jwt/types_.py
Line 172 in 887bd02
PR is welcomed. I might be able to solve this on thursday