예제 #1
0
 async def the_resolver(obj: Any, args: Dict[str, Any], *_: Any):
     if args:
         if 'id' in args:
             args['obj_id'] = args['id']
             del args['id']
         args = pythonify_dict(args)
     prop = getattr(obj, python_name)
     check.invariant(callable(prop), 'must be async function')
     return await prop(**args)
예제 #2
0
 async def mutation_resolver(obj: Any, args: Dict[str, Any],
                             context: PentContext, *_: Any) -> Any:
     args = process_args(args)
     pent_data_cls = context.cls_from_name(pent_data_cls_name)
     pent_data = pent_data_cls(**args['data'])
     args['data'] = pent_data
     prop = getattr(obj, python_name)
     check.invariant(callable(prop), 'must be async function')
     return await prop(**args)
예제 #3
0
파일: parser.py 프로젝트: savil/graphscale
def create_grapple_type_definition(type_ast: TypeDefinition) -> GrappleTypeDef:
    check.isinst(type_ast, TypeDefinition)
    if isinstance(type_ast, ObjectTypeDefinition):
        return create_grapple_object_type(type_ast)
    elif isinstance(type_ast, InputObjectTypeDefinition):
        return create_grapple_input_type(type_ast)
    elif isinstance(type_ast, EnumTypeDefinition):
        return create_grapple_enum_type(type_ast)
    check.invariant(False, 'node not supported: ' + str(type_ast))
    return None
예제 #4
0
def print_generated_pent_payload(writer: CodeWriter,
                                 payload_type: GrappleTypeDef) -> None:
    check.invariant(payload_type.type_varietal == TypeVarietal.OBJECT,
                    'must be object')
    check.invariant(
        len(payload_type.fields) == 1,
        'Payload type should only have one field')
    out_field = payload_type.fields[0]
    payload_class_text = PENT_PAYLOAD_DATA_TEMPLATE.format(
        name=payload_type.name, field_name=out_field.python_name)
    writer.line(payload_class_text)
예제 #5
0
def print_generated_enum(writer: CodeWriter,
                         enum_type: GrappleTypeDef) -> None:
    check.invariant(enum_type.type_varietal == TypeVarietal.ENUM,
                    'must be enum')

    writer.line('class {name}(Enum):'.format(name=enum_type.name))
    writer.increase_indent()
    for value in enum_type.values:
        writer.line("{value} = '{value}'".format(value=value))
    writer.decrease_indent()
    writer.blank_line()
예제 #6
0
def get_mutation_classes(document_ast: GrappleDocument,
                         field: GrappleField) -> Tuple[str, str, str]:
    data_cls = get_data_arg_in_pent(field)
    payload_cls = field.type_ref.python_typename

    payload_type = document_ast.type_named(payload_cls)
    check.invariant(
        len(payload_type.fields) == 1,
        'payload class for vanilla crud should only have one field')
    data_field = payload_type.fields[0]
    pent_cls = data_field.type_ref.python_typename
    return (pent_cls, data_cls, payload_cls)
예제 #7
0
def print_create_pent_field(writer: CodeWriter, document_ast: GrappleDocument,
                            field: GrappleField) -> None:
    check.invariant(len(field.args) == 1, 'createPent should only have 1 arg')

    pent_cls, data_cls, payload_cls = get_mutation_classes(document_ast, field)

    writer.line('async def %s(self, data):' % field.python_name)
    writer.increase_indent()  # begin implemenation
    writer.line(
        "return await gen_create_pent_dynamic"
        "(self.context, '{pent_cls}', '{data_cls}', '{payload_cls}', data)".
        format(pent_cls=pent_cls, data_cls=data_cls, payload_cls=payload_cls))
    writer.decrease_indent()  # end implemenation
    writer.blank_line()
예제 #8
0
def print_create_pent_field(writer: CodeWriter, document_ast: GrappleDocument,
                            field: GrappleField) -> None:
    check.invariant(len(field.args) == 1, 'createPent should only have 1 arg')

    pent_cls, data_cls, payload_cls = get_mutation_classes(document_ast, field)

    writer.line(
        "async def {name}(self, data: '{data_cls}') -> Pent: # mypy circ {typing}"
        .format(name=field.python_name,
                data_cls=data_cls,
                typing=python_typing_string(field.type_ref)))
    writer.increase_indent()  # begin implemenation
    writer.line(
        "return await gen_create_pent_dynamic"
        "(self.context, '{pent_cls}', '{data_cls}', '{payload_cls}', data) # type: ignore"
        .format(pent_cls=pent_cls, data_cls=data_cls, payload_cls=payload_cls))
    writer.decrease_indent()  # end implemenation
    writer.blank_line()
예제 #9
0
def print_update_pent_field(writer: CodeWriter, document_ast: GrappleDocument,
                            field: GrappleField) -> None:
    check.invariant(len(field.args) == 2, 'updatePent should have 2 args')
    check_required_id_arg(field)
    pent_cls, data_cls, payload_cls = get_mutation_classes(document_ast, field)

    writer.line(("async def {name}(self, obj_id: UUID, data: '{data_cls}')"
                 " -> PentMutationPayload: # mypy circ {typing}").format(
                     name=field.python_name,
                     data_cls=data_cls,
                     typing=python_typing_string(field.type_ref)))
    writer.increase_indent()  # begin implemenation
    writer.line(
        "return await gen_update_pent_dynamic"
        "(self.context, obj_id, '{pent_cls}', '{data_cls}', '{payload_cls}', data) # type: ignore"
        .format(pent_cls=pent_cls, data_cls=data_cls, payload_cls=payload_cls))
    writer.decrease_indent()  # end implementation
    writer.blank_line()
예제 #10
0
def get_stored_on_type(field: GrappleField) -> str:
    check.invariant(field.type_ref.varietal == TypeRefVarietal.NONNULL, 'outer non null')
    check.invariant(field.type_ref.inner_type.varietal == TypeRefVarietal.LIST, 'then list')
    check.invariant(
        field.type_ref.inner_type.inner_type.varietal == TypeRefVarietal.NONNULL, 'then nonnull'
    )
    check.invariant(
        field.type_ref.inner_type.inner_type.inner_type.varietal == TypeRefVarietal.NAMED,
        'then named'
    )
    return field.type_ref.inner_type.inner_type.inner_type.python_typename
예제 #11
0
def print_gen_from_stored_id_field(writer: CodeWriter,
                                   field: GrappleField) -> None:
    check.invariant(
        len(field.args) == 0, 'genFromStoredId should have no args')
    check.invariant(field.type_ref.varietal == TypeRefVarietal.NAMED,
                    'only supports bare types for now')

    cls_name = field.type_ref.python_typename
    # very hard coded for now. should be configurable via argument to directive optionally
    prop = to_snake_case(field.name) + '_id'

    writer.line("async def %s(self) -> Pent: # mypy circ %s" %
                (field.python_name, python_typing_string(field.type_ref)))
    writer.increase_indent()  # begin implemenation
    writer.line("return await self.gen_from_stored_id_dynamic"
                "('{cls_name}', '{prop}') # type: ignore".format(
                    cls_name=cls_name, prop=prop))
    writer.decrease_indent()  # end implementation
    writer.blank_line()
예제 #12
0
def print_delete_pent_field(writer: CodeWriter, field: GrappleField) -> None:
    check.invariant(len(field.args) == 1, 'deletePent should only have 1 arg')
    check_required_id_arg(field)

    if not isinstance(field.field_varietal_data, DeletePentData):
        check.failed('must be DeletePentData')

    payload_cls = field.type_ref.python_typename
    pent_cls = field.field_varietal_data.type

    writer.line(
        "async def %s(self, obj_id: UUID) -> PentMutationPayload: # mypy circ %s"
        % (field.python_name, python_typing_string(field.type_ref)))
    writer.increase_indent()  # begin implemenation
    writer.line(
        ("return await gen_delete_pent_dynamic(self.context"
         ", '{pent_cls}', '{payload_cls}', obj_id) # type: ignore").format(
             pent_cls=pent_cls, payload_cls=payload_cls))
    writer.decrease_indent()  # end implementation
    writer.blank_line()
예제 #13
0
def print_graphql_field(writer: CodeWriter, _document_ast: GrappleDocument,
                        grapple_field: GrappleField) -> None:
    type_ref_str = type_ref_string(grapple_field.type_ref)

    writer.line("'%s': GraphQLField(" % grapple_field.name)
    writer.increase_indent()  # begin args to GraphQLField .ctor
    writer.line('type=%s, # type: ignore' % type_ref_str)

    if grapple_field.args:
        writer.line('args={')
        writer.increase_indent()  # begin entries in args dictionary
        for grapple_arg in grapple_field.args:
            arg_type_ref_str = type_ref_string(grapple_arg.type_ref)
            if grapple_arg.default_value is None:
                writer.line("'%s': GraphQLArgument(type=%s), # type: ignore" %
                            (grapple_arg.name, arg_type_ref_str))
            else:
                writer.line(
                    "'%s': GraphQLArgument(type=%s, default_value=%s), # type: ignore"
                    % (grapple_arg.name, arg_type_ref_str,
                       grapple_arg.default_value))

        writer.decrease_indent()  # end entries in args dictionary
        writer.line('},')  # close args dictionary

    python_name = grapple_field.python_name
    if grapple_field.field_varietal.is_mutation:
        data_arg = None
        for arg in grapple_field.args:
            if arg.name == 'data':
                data_arg = arg
                break

        check.invariant(data_arg, 'mutations must have an arg named data')
        check.invariant(data_arg.name == 'data',
                        'mutation argument name must be data')
        check.invariant(data_arg.type_ref.varietal == TypeRefVarietal.NONNULL,
                        'data argument must be required')

        data_cls = data_arg.type_ref.inner_type.python_typename
        writer.line("resolver=define_pent_mutation_resolver('%s', '%s')," %
                    (python_name, data_cls))
    elif grapple_field.field_varietal.is_gen_varietal:
        writer.line("resolver=define_default_gen_resolver('%s')," %
                    python_name)
    else:
        writer.line("resolver=define_default_resolver('%s')," % python_name)

    writer.decrease_indent()  # end args to GraphQLField .ctor
    writer.line('),')  # close GraphQLField .ctor
예제 #14
0
def check_required_id_arg(field: GrappleField) -> None:
    id_arg = get_required_arg(field.args, 'id')
    check.invariant(id_arg.type_ref.varietal == TypeRefVarietal.NONNULL,
                    'arg must be non null')
    check.invariant(id_arg.type_ref.inner_type.graphql_typename == 'UUID',
                    'arg must be UUID')
예제 #15
0
def get_data_arg_in_pent(field: GrappleField) -> str:
    data_arg = get_required_arg(field.args, 'data')
    check.invariant(data_arg.type_ref.varietal == TypeRefVarietal.NONNULL,
                    'input argument must be non null')

    return data_arg.type_ref.inner_type.python_typename
예제 #16
0
def get_first_after_args(
    field: GrappleField
) -> Tuple[GrappleFieldArgument, GrappleFieldArgument, str]:
    check.invariant(len(field.args) == 2, 'browse/conn should have 2 args')
    first_arg = get_required_arg(field.args, 'first')
    check.invariant(first_arg.default_value, 'must have default value')

    after_arg = get_required_arg(field.args, 'after')
    check.invariant(after_arg.type_ref.graphql_typename == 'UUID',
                    'arg must be UUID')

    check.invariant(field.type_ref.varietal == TypeRefVarietal.NONNULL,
                    'outer non null')
    check.invariant(field.type_ref.inner_type.varietal == TypeRefVarietal.LIST,
                    'then list')
    check.invariant(
        field.type_ref.inner_type.inner_type.varietal ==
        TypeRefVarietal.NONNULL, 'then nonnull')
    check.invariant(
        field.type_ref.inner_type.inner_type.inner_type.varietal ==
        TypeRefVarietal.NAMED, 'then named')
    target_type = field.type_ref.inner_type.inner_type.inner_type.python_typename
    return (first_arg, after_arg, target_type)