tartiflette/tartiflette-aiohttp

Context passed to subscriptions is None

jonypawks opened this issue · 3 comments

When using subscriptions, both the resolver and the subscription handler receive None as the context, regardless of what is passed in to register_graphql_handlers.

I was expecting that context to be the same context (though a unique instance as for all requests) that is received by query and mutation resolvers. I wondered how the examples worked but then noticed that it just uses a global instead of passing the redis connection through the context.

I noticed that for subscriptions the context is being pulled from the websocket message payload, which seems odd to me but maybe I don't fully understand:

Here's an small example app that demos the behavior I'm seeing:

import asyncio
import sys

from aiohttp import web

from tartiflette import Resolver, Subscription
from tartiflette_aiohttp import register_graphql_handlers


SDL = """
type Query {
    countdownLength: Int!
}

type Subscription {
    countdown: Int!
}
"""


@Resolver("Query.countdownLength")
async def resolver_length(_parent, _args, ctx, _info):
    return ctx["length"]


@Subscription("Subscription.countdown")
async def on_countdown(parent, _args, ctx, _info):
    print(f"subscription: ctx={ctx}")
    countdown = 5  # would expect to use ctx["length"] here
    while countdown > 0:
        yield countdown
        countdown -= 1
        await asyncio.sleep(1)
    yield 0


@Resolver("Subscription.countdown")
async def resolver_countdown(payload, _args, ctx, _info):
    print(f"resolver: payload={payload} ctx={ctx}")
    return payload


def main():
    app = web.Application()
    register_graphql_handlers(
        app,
        engine_sdl=SDL,
        executor_context={"length": 5},
        subscription_ws_endpoint="/ws",
        graphiql_enabled=True,
    )
    web.run_app(app, port=8089)
    return 0


if __name__ == "__main__":
    sys.exit(main())

Which produces output:

======== Running on http://0.0.0.0:8089 ========
(Press CTRL+C to quit)
subscription: ctx=None
resolver: payload=5 ctx=None
resolver: payload=4 ctx=None
resolver: payload=3 ctx=None
resolver: payload=2 ctx=None
resolver: payload=1 ctx=None
resolver: payload=0 ctx=None

Hi @jonypawks,

Thank you for raising this issue, indeed, the context isn't properly injected in the case of subscriptions.

Getting the context from the payload is indeed an error on our side.

A fix has been made on this PR.

You can test that this corrects your issue by installing the version linked to the PR with:

pip install --extra-index-url https://test.pypi.org/simple/ tartiflette-aiohttp==0.8.5a1567583033

Thanks @Maximilien-R, installing the PR version does indeed fix the issue for me.

@jonypawks The fix is available in the tartiflette-aiohttp==0.8.5 release.

Again thank you for raising this issue.