Skip to main content
Version: 0.22

Extension system

Ariadne implements simple extension system that allows developers to inject custom python logic into the query execution process. This system was designed with performance measurement extensions in mind but may potentially support other use cases.

At the moment adding extensions to subscriptions is not supported.

Enabling extensions

To enable extensions, initialize handler with extensions parameter. This parameter accepts list of extensions:

from ariadne.asgi import GraphQL
from ariadne.asgi.handlers import GraphQLHTTPHandler

from .schema import schema
from .extensions import MyExtension


app = GraphQL(
schema,
http_handler=GraphQLHTTPHandler(
extensions=[MyExtension],
),
)

Alternatively, if your extension depends on request or should be enabled conditionally, you can provide callable that will return extensions that should be used:

from ariadne.asgi import GraphQL
from ariadne.asgi.handlers import GraphQLHTTPHandler

from .schema import schema
from .extensions import MyExtension


def get_extensions(request, context):
if request.headers.get("x-enable-my-extension"):
return [MyExtension]
return None


app = GraphQL(
schema,
http_handler=GraphQLHTTPHandler(
extensions=get_extensions,
),
)

Custom extension example

Let's create simple extension that measures query execution time, and appends this time to query's result.

All extensions should extend special base class named Extension, importable from ariadne.types:

from ariadne.types import Extension


class QueryExecutionTimeExtension(Extension):
...

Our extension will measure the query execution time. This means we need to measure the time of two events, request start and creation of JSON response:

import time

from ariadne.types import Extension


class QueryExecutionTimeExtension(Extension):
def __init__(self):
self.start_timestamp = None
self.end_timestamp = None

def request_started(self, context):
self.start_timestamp = time.perf_counter_ns()

def format(self, context):
if self.start_timestamp and self.end_timestamp:
return {
"execution": time.perf_counter_ns() - self.start_timestamp
}

See Extension reference for the list of available events.