Beispiel #1
0
 def mapping(self, cls: Type[Mapping], key_type: AnyType,
             value_type: AnyType) -> Thunk[graphql.GraphQLType]:
     try:
         name, description = self._ref_and_desc
         return graphql.GraphQLScalarType(name, description=description)
     except MissingRef:
         return JsonScalar
Beispiel #2
0
 def factory(name: Optional[str],
             description: Optional[str]) -> graphql.GraphQLScalarType:
     assert cls is not NoneType
     if name is not None:
         return graphql.GraphQLScalarType(name, description=description)
     else:
         return GRAPHQL_PRIMITIVE_TYPES[cls]
Beispiel #3
0
 def primitive(self, cls: Type) -> Thunk[graphql.GraphQLType]:
     if cls is NoneType:
         raise Nullable
     try:
         name, description = self._ref_and_desc
         return graphql.GraphQLScalarType(name, description=description)
     except MissingRef:
         return GRAPHQL_PRIMITIVE_TYPES[cls]
Beispiel #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,
    )
Beispiel #5
0
 def factory(name: Optional[str],
             description: Optional[str]) -> graphql.GraphQLScalarType:
     if name is not None:
         return graphql.GraphQLScalarType(name, description=description)
     else:
         return JsonScalar
Beispiel #6
0
from apischema.utils import (
    Lazy,
    context_setter,
    empty_dict,
    get_args2,
    get_origin2,
    get_origin_or_type,
    identity,
    is_union_of,
    sort_by_annotations_position,
    to_camel_case,
)

JsonScalar = graphql.GraphQLScalarType(
    "JSON",
    specified_by_url=
    "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf",
)
GRAPHQL_PRIMITIVE_TYPES = {
    int: graphql.GraphQLInt,
    float: graphql.GraphQLFloat,
    str: graphql.GraphQLString,
    bool: graphql.GraphQLBoolean,
}

ID = NewType("ID", str)


class MissingName(Exception):
    pass
Beispiel #7
0

ID = gql.GraphQLID

Int = gql.GraphQLInt

Float = gql.GraphQLFloat

String = gql.GraphQLString

Boolean = gql.GraphQLBoolean

Currency = gql.GraphQLScalarType(
    name="Currency",
    description="Currency",
    serialize=serialize,
    parse_value=coerce,
    parse_literal=parse,
)


def serialize_date(v):
    print("serialize date", v)
    return v


def coerce_date(v):
    print("coerce date", v)
    return v

Beispiel #8
0
from datetime import time as PyTime

import aniso8601
import graphql
from graphql.language import ast


def serialize(value: PyTime):
    return value.isoformat()


def coerce(value: str):
    return aniso8601.parse_time(value)


def parse_literal(ast_node, _variables=None):
    if isinstance(ast_node, ast.StringValueNode):
        return aniso8601.parse_time(ast_node.value)
    return graphql.INVALID


GraphQLTime = graphql.GraphQLScalarType(
    name="Time",
    description="The `Time` scalar type represents ISO 8601 time.",
    serialize=serialize,
    parse_value=coerce,
    parse_literal=parse_literal,
)
Beispiel #9
0
from uuid import UUID as PyUUID

import graphql
from graphql.language import ast


def serialize(value: PyUUID):
    if not isinstance(value, PyUUID):
        value = PyUUID(value)
    return str(value)


def coerce(value):
    return PyUUID(value)


def parse_literal(ast_node, _variables=None):
    if isinstance(ast_node, ast.StringValueNode):
        return PyUUID(ast_node.value)
    return graphql.INVALID


GraphQLUUID = graphql.GraphQLScalarType(
    name="UUID",
    description="The `UUID` scalar type.",
    serialize=serialize,
    parse_value=coerce,
    parse_literal=parse_literal,
)
Beispiel #10
0
from decimal import Decimal as PyDecimal

import graphql
from graphql.language import ast


def serialize(value):
    if not isinstance(value, PyDecimal):
        value = PyDecimal(value)
    return str(value)


def coerce(value):
    return PyDecimal(value)


def parse_literal(ast_node, _variables=None):
    if isinstance(ast_node,
                  (ast.FloatValueNode, ast.IntValueNode, ast.StringValueNode)):
        return PyDecimal(ast_node.value)
    return graphql.INVALID


GraphQLDecimal = graphql.GraphQLScalarType(
    name="Decimal",
    description="The `Decimal` scalar type.",
    serialize=serialize,
    parse_value=coerce,
    parse_literal=parse_literal,
)
Beispiel #11
0
import graphql
from graphql.language import ast

from ..utils import NoneType


def serialize(value: NoneType):
    return None


def coerce(value: NoneType):
    return None


def parse_literal(ast_node, _variables=None):
    return graphql.INVALID


GraphQLNothing = graphql.GraphQLScalarType(
    name="Nothing",
    description="The `Nothing` scalar type represents NoneType.",
    serialize=serialize,
    parse_value=coerce,
    parse_literal=parse_literal,
)
Beispiel #12
0
        parts.append(f"{minutes:.0f}M")
    if seconds:
        if seconds.is_integer():
            seconds = int(seconds)
        parts.append(f"{seconds}S")

    return "".join(parts)


def serialize(value: PyDuration):
    return format_simple_iso8601_duration(value)


def coerce(value: str):
    return aniso8601.parse_duration(value)


def parse_literal(ast_node, _variables=None):
    if isinstance(ast_node, ast.StringValueNode):
        return aniso8601.parse_duration(ast_node.value)
    return graphql.INVALID


GraphQLDuration = graphql.GraphQLScalarType(
    name="Duration",
    description="The `Duration` scalar type represents ISO8601 duration.",
    serialize=serialize,
    parse_value=coerce,
    parse_literal=parse_literal,
)