Exemple #1
0
def build_schema(config, engine, subset=None):
    """
    Build the object types for all the indexes. Subset is a list of
    index names that the schema should include. If no subset is
    provided, then all indexes are built and added to the schema.
    """
    fields = {}

    for i in Index.list_indexes(engine):
        if not subset or i.name in subset:
            try:
                output_type, args = build_index_type(config, engine, i)
                resolver = ql_resolver(config, engine, i)

                # create the field for this table, with arguments and resolver
                fields[f'{i.table.name}'] = graphql.GraphQLField(
                    graphql.GraphQLList(output_type),
                    args=args,
                    resolve=resolver,
                )
            except (ValueError, AssertionError) as ex:
                logging.error('%s; skipping %s...', str(ex), i.name)

    # construct the query object for the root object type
    root = graphql.GraphQLObjectType('Query', fields)

    # build the schema
    return graphql.GraphQLSchema(query=root)
def _create_graphql_schema(query_type, mutation_type):
    graphql_query_type = to_graphql_type(query_type).of_type
    if mutation_type is None:
        graphql_mutation_type = None
    else:
        graphql_mutation_type = to_graphql_type(query_type).of_type

    return graphql.GraphQLSchema(
        query=graphql_query_type,
        mutation=graphql_mutation_type,
    )
Exemple #3
0
    def build(self, **options):
        self._root_context.update(options)
        queries = list(map(query, self._queries))
        mutations = list(map(mutation, self._mutations))
        subscriptions = list(map(subscription, self._subscriptions))

        extra_types = [
            self.transformer.transform(t, allow_null=True) for t in self._types
        ]

        return graphql.GraphQLSchema(
            query=self.transformer.transform(
                generate_root_type(queries, name="Query"), allow_null=True)
            if queries else None,
            mutation=self.transformer.transform(
                generate_root_type(mutations, name="Mutation"),
                allow_null=True) if mutations else None,
            subscription=self.transformer.transform(
                generate_root_type(subscriptions, name="Subscription"),
                allow_null=True) if subscriptions else None,
            types=extra_types,
        )
Exemple #4
0
def graphql_schema(
    *,
    query: Iterable[Union[Callable, Query]] = (),
    mutation: Iterable[Union[Callable, Mutation]] = (),
    subscription: Iterable[Union[Callable[..., AsyncIterable],
                                 Subscription]] = (),
    types: Iterable[Type] = (),
    directives: Optional[Collection[graphql.GraphQLDirective]] = None,
    description: Optional[str] = None,
    extensions: Optional[Dict[str, Any]] = None,
    aliaser: Optional[Aliaser] = to_camel_case,
    enum_aliaser: Optional[Aliaser] = str.upper,
    enum_schemas: Optional[Mapping[Enum, Schema]] = None,
    id_types: Union[Collection[AnyType], IdPredicate] = (),
    id_encoding: Tuple[Optional[Callable[[str], Any]],
                       Optional[Callable[[Any], str]]] = (None, None),
    # TODO deprecate union_ref parameter
    union_ref: UnionNameFactory = "Or".join,
    union_name: UnionNameFactory = "Or".join,
    default_deserialization: DefaultConversion = None,
    default_serialization: DefaultConversion = None,
) -> graphql.GraphQLSchema:
    if aliaser is None:
        aliaser = settings.aliaser
    if enum_aliaser is None:
        enum_aliaser = lambda s: s
    if default_deserialization is None:
        default_deserialization = settings.deserialization.default_conversion
    if default_serialization is None:
        default_serialization = settings.serialization.default_conversion
    query_fields: List[ResolverField] = []
    mutation_fields: List[ResolverField] = []
    subscription_fields: List[ResolverField] = []
    for operations, op_class, fields in [
        (query, Query, query_fields),
        (mutation, Mutation, mutation_fields),
    ]:
        for operation in operations:  # type: ignore
            alias, resolver = operation_resolver(operation, op_class)
            resolver_field = ResolverField(
                alias,
                resolver,
                resolver.types(),
                resolver.parameters,
                resolver.parameters_metadata,
            )
            fields.append(resolver_field)
    for sub_op in subscription:  # type: ignore
        if not isinstance(sub_op, Subscription):
            sub_op = Subscription(sub_op)  # type: ignore
        sub_parameters: Sequence[Parameter]
        if sub_op.resolver is not None:
            alias = sub_op.alias or sub_op.resolver.__name__
            _, subscriber2 = operation_resolver(sub_op, Subscription)
            _, *sub_parameters = resolver_parameters(sub_op.resolver,
                                                     check_first=False)
            resolver = Resolver(
                sub_op.resolver,
                sub_op.conversion,
                sub_op.schema,
                subscriber2.error_handler,
                sub_parameters,
                sub_op.parameters_metadata,
            )
            sub_types = resolver.types()
            subscriber = replace(subscriber2, error_handler=None)
            subscribe = resolver_resolve(
                subscriber,
                subscriber.types(),
                aliaser,
                default_deserialization,
                default_serialization,
                serialized=False,
            )
        else:
            alias, subscriber2 = operation_resolver(sub_op, Subscription)
            resolver = Resolver(
                lambda _: _,
                sub_op.conversion,
                sub_op.schema,
                subscriber2.error_handler,
                (),
                {},
            )
            subscriber = replace(subscriber2, error_handler=None)
            sub_parameters = subscriber.parameters
            sub_types = subscriber.types()
            if get_origin2(sub_types["return"]) not in async_iterable_origins:
                raise TypeError(
                    "Subscriptions must return an AsyncIterable/AsyncIterator")
            event_type = get_args2(sub_types["return"])[0]
            subscribe = resolver_resolve(
                subscriber,
                sub_types,
                aliaser,
                default_deserialization,
                default_serialization,
                serialized=False,
            )
            sub_types = {
                **sub_types, "return": resolver.return_type(event_type)
            }

        resolver_field = ResolverField(
            alias,
            resolver,
            sub_types,
            sub_parameters,
            sub_op.parameters_metadata,
            subscribe,
        )
        subscription_fields.append(resolver_field)

    is_id = id_types.__contains__ if isinstance(id_types,
                                                Collection) else id_types
    if id_encoding == (None, None):
        id_type: graphql.GraphQLScalarType = graphql.GraphQLID
    else:
        id_deserializer, id_serializer = id_encoding
        id_type = graphql.GraphQLScalarType(
            name="ID",
            serialize=id_serializer or graphql.GraphQLID.serialize,
            parse_value=id_deserializer or graphql.GraphQLID.parse_value,
            parse_literal=graphql.GraphQLID.parse_literal,
            description=graphql.GraphQLID.description,
        )

    output_builder = OutputSchemaBuilder(
        aliaser,
        enum_aliaser,
        enum_schemas or {},
        default_serialization,
        id_type,
        is_id,
        union_name or union_ref,
        default_deserialization,
    )

    def root_type(
        name: str, fields: Sequence[ResolverField]
    ) -> Optional[graphql.GraphQLObjectType]:
        if not fields:
            return None
        tp, type_name = type(name, (), {}), TypeName(graphql=name)
        return output_builder.object(tp, (), fields).merge(
            type_name, None).raw_type  # type: ignore

    return graphql.GraphQLSchema(
        query=root_type("Query", query_fields),
        mutation=root_type("Mutation", mutation_fields),
        subscription=root_type("Subscription", subscription_fields),
        types=[output_builder.visit(cls).raw_type
               for cls in types],  # type: ignore
        directives=directives,
        description=description,
        extensions=extensions,
    )
Exemple #5
0

class Root:
    def __init__(self, data):
        self.data = data

    def person(self, info, *, name: t.Optional[str] = None) -> Person:
        if name is None:
            return None
        for row in self.data["people"]:
            if name == row["name"]:
                return row
        return None


schema = g.GraphQLSchema(query_type)


@as_command
def run():
    q = """\
{
 foo: person(name: "foo") { name, age, nickname }
 xxx: person(name: "xxx") { name, age, nickname }
}
    """

    data = {
        "people": [
            {"name": "boo", "age": 20},
            {"name": "foo", "age": 20, "nickname": "F"},
Exemple #6
0
import graphql
from graphql.utilities import print_schema

Person = graphql.GraphQLObjectType(
    "Person",
    lambda: {
        "name":
        graphql.GraphQLField(graphql.GraphQLNonNull(graphql.GraphQLString, )),
    },
)
Query = graphql.GraphQLObjectType(
    "Query",
    lambda: {
        "people":
        graphql.GraphQLField(
            graphql.GraphQLNonNull(graphql.GraphQLList(Person)))
    },
)
schema = graphql.GraphQLSchema(Query)

print(print_schema(schema))
# or graphql.print_schema(schema)
def create_graphql_schema(query_type, mutation_type, types=None):
    if types is None:
        types = ()

    graphql_types = {}

    def to_graphql_type(graph_type):
        if graph_type not in graphql_types:
            graphql_types[graph_type] = generate_graphql_type(graph_type)

        return graphql_types[graph_type]

    def generate_graphql_type(graph_type):
        if graph_type == schema.Boolean:
            return graphql.GraphQLNonNull(graphql.GraphQLBoolean)
        elif graph_type == schema.Float:
            return graphql.GraphQLNonNull(graphql.GraphQLFloat)
        elif graph_type == schema.Int:
            return graphql.GraphQLNonNull(graphql.GraphQLInt)
        elif graph_type == schema.String:
            return graphql.GraphQLNonNull(graphql.GraphQLString)

        elif isinstance(graph_type, schema.EnumType):
            # TODO: should enums map names or values?
            values = iterables.to_dict(
                (member.value, graphql.GraphQLEnumValue(member.value))
                for member in graph_type.enum)
            graphql_type = graphql.GraphQLEnumType(graph_type.name,
                                                   values=values)
            return graphql.GraphQLNonNull(graphql_type)

        elif isinstance(graph_type, schema.InputObjectType):
            return graphql.GraphQLNonNull(
                graphql.GraphQLInputObjectType(
                    name=graph_type.name,
                    fields=lambda: iterables.to_dict(
                        (snake_case_to_camel_case(field.name),
                         to_graphql_input_field(field))
                        for field in graph_type.fields),
                ))

        elif isinstance(graph_type, schema.InterfaceType):
            return graphql.GraphQLNonNull(
                graphql.GraphQLInterfaceType(
                    name=graph_type.name,
                    fields=to_graphql_fields(graph_type.fields),
                    resolve_type=lambda: None,
                ))

        elif isinstance(graph_type, schema.ListType):
            return graphql.GraphQLNonNull(
                graphql.GraphQLList(to_graphql_type(graph_type.element_type)))

        elif isinstance(graph_type, schema.NullableType):
            return to_graphql_type(graph_type.element_type).of_type

        elif isinstance(graph_type, schema.ObjectType):
            return graphql.GraphQLNonNull(
                graphql.GraphQLObjectType(
                    name=graph_type.name,
                    fields=to_graphql_fields(graph_type.fields),
                    interfaces=tuple(
                        to_graphql_type(interface).of_type
                        for interface in graph_type.interfaces),
                ))

        else:
            raise ValueError("unsupported type: {}".format(graph_type))

    def to_graphql_input_field(graph_field):
        graphql_type = to_graphql_type(graph_field.type)

        if graph_field.has_default and isinstance(graphql_type,
                                                  graphql.GraphQLNonNull):
            graphql_type = graphql_type.of_type

        return graphql.GraphQLInputField(type_=graphql_type)

    def to_graphql_fields(graph_fields):
        return lambda: iterables.to_dict(
            (snake_case_to_camel_case(field.name), to_graphql_field(field))
            for field in graph_fields)

    def to_graphql_field(graph_field):
        return graphql.GraphQLField(
            type_=to_graphql_type(graph_field.type),
            args=iterables.to_dict((snake_case_to_camel_case(param.name),
                                    to_graphql_argument(param))
                                   for param in graph_field.params),
        )

    def to_graphql_argument(param):
        graphql_type = to_graphql_type(param.type)

        if param.has_default and isinstance(graphql_type,
                                            graphql.GraphQLNonNull):
            graphql_type = graphql_type.of_type

        return graphql.GraphQLArgument(type_=graphql_type)

    graphql_query_type = to_graphql_type(query_type).of_type
    if mutation_type is None:
        graphql_mutation_type = None
    else:
        graphql_mutation_type = to_graphql_type(mutation_type).of_type

    for extra_type in types:
        to_graphql_type(extra_type)

    return Schema(
        query_type=query_type,
        mutation_type=mutation_type,
        types=types,
        graphql_schema=graphql.GraphQLSchema(
            query=graphql_query_type,
            mutation=graphql_mutation_type,
            types=tuple(graphql_types.values()),
        ),
    )
Exemple #8
0
 def graphql_schema(self):
     return graphql.GraphQLSchema(
         query=self.mapper.map(self.query, default_non_null=False),
         mutation=self.mapper.map(self.mutation, default_non_null=False))
Exemple #9
0
schema = graphql.GraphQLSchema(
    query=graphql.GraphQLObjectType(
        name="RootQueryType",
        fields={
            "name": graphql.GraphQLField(
                graphql.GraphQLString,
                resolve=resolve_name,
                args={
                    "title": graphql.GraphQLArgument(
                        graphql.GraphQLNonNull(graphql.GraphQLString)
                    )
                },
            )
        },
    ),
    subscription=graphql.GraphQLObjectType(
        name="RootSubscriptionType",
        fields={
            "counter": graphql.GraphQLField(
                graphql.GraphQLString,
                resolve=resolve_counter,
                subscribe=subscribe_counter,
                args={
                    "ceil": graphql.GraphQLArgument(
                        graphql.GraphQLNonNull(graphql.GraphQLInt)
                    )
                },
            )
        },
    ),
)
Exemple #10
0
    return g.ObjectType(name='Mutation', fields=mutations)


# For extra types only which are unreachable from query and mutation types,
# e.g. for WagtailPage interface implementations.
def load_types():
    types = []
    for schema_module in get_schema_modules():
        if not hasattr(schema_module, 'exported_types'):
            continue
        if not isinstance(schema_module.exported_types, list):
            raise Exception(f"Expected list for {schema_module}.exported_types")
        types.extend(schema_module.exported_types)

    return types


def load_subscriptions():
    subscriptions = object_from_modules('subscriptions')

    return g.ObjectType(name='Subscription', fields=subscriptions)


schema = graphql.GraphQLSchema(
    query=load_queries(),
    mutation=load_mutations(),
    subscription=load_subscriptions(),
    types=load_types(),
)
Exemple #11
0
def graphql_schema(
    *,
    query: Iterable[Callable] = (),
    mutation: Iterable[Callable] = (),
    subscription: Iterable[Union[Subscribe, Tuple[Subscribe, Callable]]] = (),
    types: Iterable[Type] = (),
    aliaser: Aliaser = to_camel_case,
    id_types: Union[Collection[AnyType], IdPredicate] = None,
    error_as_null: bool = True,
    generic_ref_factory: GenericRefFactory = None,
    union_ref_factory: UnionRefFactory = None,
    directives: Optional[Collection[graphql.GraphQLDirective]] = None,
    description: Optional[str] = None,
    extensions: Optional[Dict[str, Any]] = None,
) -> graphql.GraphQLSchema:
    def operation_resolver(operation: Callable,
                           *,
                           skip_first=False) -> Resolver:
        if skip_first:
            wrapper = operation
        else:

            def wrapper(_, *args, **kwargs):
                return operation(*args, **kwargs)

        parameters = resolver_parameters(operation, skip_first=skip_first)
        return Resolver(operation, wrapper, parameters)

    query_fields: List[ObjectField] = []
    mutation_fields: List[ObjectField] = []
    subscription_fields: List[ObjectField] = []
    for operations, fields in [(query, query_fields),
                               (mutation, mutation_fields)]:
        for operation in operations:
            resolver = operation_resolver(operation)
            fields.append(
                ObjectField(
                    operation.__name__,
                    wrap_return_type(resolver.return_type, error_as_null),
                    resolve=resolver_resolve(resolver, aliaser, error_as_null),
                    parameters=field_parameters(resolver),
                    schema=get_schema(operation),
                ))
    for operation in subscription:  # type: ignore
        resolve: Callable
        if isinstance(operation, tuple):
            operation, event_handler = operation
            name, schema = event_handler.__name__, get_schema(event_handler)
            try:
                resolver = operation_resolver(event_handler, skip_first=True)
            except MissingFirstParameter:
                raise TypeError(
                    "Subscription resolver must have at least one parameter"
                ) from None
            return_type = resolver.return_type
            subscribe = resolver_resolve(
                operation_resolver(operation),
                aliaser,
                error_as_null,
                serialized=False,
            )
            resolve = resolver_resolve(resolver, aliaser, error_as_null)
        else:
            name, schema = operation.__name__, get_schema(operation)
            resolver = operation_resolver(operation)
            if get_origin(resolver.return_type) not in async_iterable_origins:
                raise TypeError(
                    "Subscriptions must return an AsyncIterable/AsyncIterator")
            return_type = get_args(resolver.return_type)[0]
            subscribe = resolver_resolve(resolver,
                                         aliaser,
                                         error_as_null,
                                         serialized=False)

            def resolve(_, *args, **kwargs):
                return _

        subscription_fields.append(
            ObjectField(
                name,
                wrap_return_type(return_type, error_as_null),
                parameters=field_parameters(resolver),
                resolve=resolve,
                subscribe=subscribe,
                schema=schema,
            ))

    is_id = id_types.__contains__ if isinstance(id_types,
                                                Collection) else id_types
    builder = OutputSchemaBuilder(aliaser, is_id, error_as_null,
                                  generic_ref_factory, union_ref_factory)

    def root_type(
        name: str, fields: Collection[ObjectField]
    ) -> Optional[graphql.GraphQLObjectType]:
        if not fields:
            return None
        return exec_thunk(builder.object(type(name, (), {}), fields),
                          non_null=False)

    return graphql.GraphQLSchema(
        root_type("Query", query_fields),
        root_type("Mutation", mutation_fields),
        root_type("Subscription", subscription_fields),
        [exec_thunk(builder.visit(cls), non_null=False) for cls in types],
        directives,
        description,
        extensions,
    )