Home

Awesome

Tartiflette aiohttp

tartiflette-aiohttp is a wrapper of aiohttp which includes the Tartiflette GraphQL Engine. You can take a look at the Tartiflette API documentation.

Usage

# main.py
from aiohttp import web
from tartiflette import Resolver
from tartiflette_aiohttp import register_graphql_handlers

@Resolver("Query.hello")
async def resolver_hello(parent, args, ctx, info):
    return "hello " + args["name"]

sdl = """
    type Query {
        hello(name: String): String
    }
"""

web.run_app(
    register_graphql_handlers(
        web.Application(),
        engine_sdl=sdl
    )
)

Save the file and start the server.

$ python main.py
======== Running on http://0.0.0.0:8080 ========
(Press CTRL+C to quit)

Note: The server will be listening on the /graphql path by default.

Send a request to your server

curl -v -d '{"query": "query { hello(name: "Chuck") }"}' -H "Content-Type: application/json" http://localhost:8080/graphql

Installation

tartiflette-aiohttp is available on pypi.org.

WARNING: Do not forget to install the tartiflette dependencies beforehand as explained in the tutorial.

pip install tartiflette-aiohttp

How to use

Use with built-in Tartiflette Engine

The basic and common way to use Tartiflette with aiohttp, is to create an aiohttp web.Application and use the register_graphql_handlers helper to bind Tartiflette and aiohttp together. engine_* parameters will be forwarded to the built-in tartiflette engine instance.

from aiohttp import web
from tartiflette_aiohttp import register_graphql_handlers

sdl = """
    type Query {
        hello(name: String): String
    }
"""

ctx = {
    'user_service': user_service
}

web.run_app(
    register_graphql_handlers(
        app=web.Application(),
        engine_sdl=sdl,
        engine_schema_name="default",
        executor_context=ctx,
        executor_http_endpoint='/graphql',
        executor_http_methods=['POST', 'GET']
    )
)

Parameters:

Use with custom Tartiflette engine

In the case you already have a Tartiflette Engine instance, or, you do not want to use the built-in instance. You can pass an existing instance to the register_graphql_handlers helper.

# main.py
from aiohttp import web
from tartiflette import Resolver, Engine
from tartiflette_aiohttp import register_graphql_handlers

@Resolver("Query.hello")
async def resolver_hello(parent, args, ctx, info):
    return "hello " + args["name"]

sdl = """
    type Query {
        hello(name: String): String
    }
"""

engine = Engine(sdl)

ctx = {
    'user_service': user_service
}

web.run_app(
    register_graphql_handlers(
        app=web.Application(),
        engine=engine,
        executor_context=ctx,
        executor_http_endpoint='/graphql',
        executor_http_methods=['POST', 'GET']
    )
)

Parameters:

Tartiflette with subscriptions

Tartiflette embeds an easy way to deal with subscriptions. The only thing to do is to fill in the subscription_ws_endpoint parameter and everything will work out of the box with aiohttp WebSockets. You can see a full example here.

Enable GraphiQL handler

Tartiflette allows you to set up an instance of GraphiQL easily to quickly test your queries. The easiest way to do that is to set the graphiql_enabled parameter to True. Then, you can customize your GraphiQL instance by filling the graphiql_options parameter as bellow:

from aiohttp import web

from tartiflette_aiohttp import register_graphql_handlers


_SDL = """
    type Query {
        hello(name: String): String
    }
"""

web.run_app(
    register_graphql_handlers(
        app=web.Application(),
        engine_sdl=_SDL,
        graphiql_enabled=True,
        graphiql_options={  # This is optional
            "endpoint": "/explorer",  # Default: `/graphiql`,
            "default_query": """
                query Hello($name: String) {
                  hello(name: $name)
                }
            """,
            "default_variables": {
                "name": "Bob",
            },
            "default_headers": {
                "Authorization": "Bearer <default_token>",
            },
        },
    )
)

Parameters:

Advance Use Case

Response header manipulation from resolver

It is possible to set header to the response directly from the resolver using set_response_headers method like:

from tartiflette_aiohttp import set_response_headers

@Resolver("Query.X")
async def resolver_x(parent_result, args, ctx, info):
    # do things
    set_response_headers({"Header": "Value", "AnotherHeader": "AnotherValue"})
    return result

Note that this feature uses ContextVar and will only works for python 3.7.1 and later.

OR it is also possible to do, if you do not have ContextVar, or don't want to use them:

from aiohttp import web

def a_callable(req, data, ctx):
    return web.json_response(data, headers=ctx["_any_custom_key"])

web.run_app(
    register_graphql_handlers(
        app=web.Application(),
        engine_sdl=_SDL,
        response_formatter=a_callable
    )
)


@Resolver("Type.field_name")
async def fiel_name_resolver(pr, args, ctx, info):
    ctx["_any_custom_key"] = {"X-Header": "What a wonderfull value"}
    return something