mirumee/ariadne

Pass dict to `context` argument from SchemaDirectiveVisitor.__init__

rafalp opened this issue · 2 comments

SchemaDirectiveVisitor accept's context as one of constructors arguments, but it's not passed to directives at any point, and doesn't even exist when directive is initiated, making this arg's value always be None.

We could initialize empty dict in visit_schema_directives and then pass it to directive instances to let them share state between fields without having to resort to type attributes which are leaky abstraction in multi-schema projects.

+1 I had the None issue trying to implement an Auth Directive 😔

Auth directive should wrap resolver in custom one that has access to info.context, eg:

from typing import Union

from ariadne import SchemaDirectiveVisitor
from graphql import (
    GraphQLField,
    GraphQLInterfaceType,
    GraphQLObjectType,
    default_field_resolver,
)


class AuthDirective(SchemaDirectiveVisitor):
    def visit_field_definition(
        self,
        field: GraphQLField,
        object_type: Union[GraphQLObjectType, GraphQLInterfaceType],
    ) -> GraphQLField:
        resolver = field.resolve or default_field_resolver

        def auth_resolver(obj, info, **kwargs):
            if not info.context["has_valid_auth"]:
                raise Exception("Auth is required!")

            return resolver(obj, info, **kwargs)

        field.resolve = auth_resolver
        return field