Ejemplo n.º 1
0
    def __init_subclass_with_meta__(cls, resolver=None, **options):
        if not resolver:
            mutate = getattr(cls, 'mutate', None)
            assert mutate, 'All mutations must define a mutate method in it'
            resolver = get_unbound_function(mutate)
            resolver = wrap_resolver(cls, resolver)

        super().__init_subclass_with_meta__(resolver, **options)
        cls._meta.fields['errors'] = (Field(String, name='errors'))
Ejemplo n.º 2
0
def get_custom_resolver(obj_type, orm_field_name):
    """
    Since `graphene` will call `resolve_<field_name>` on a field only if it
    does not have a `resolver`, we need to re-implement that logic here so
    users are able to override the default resolvers that we provide.
    """
    resolver = getattr(obj_type, 'resolve_{}'.format(orm_field_name), None)
    if resolver:
        return get_unbound_function(resolver)

    return None
Ejemplo n.º 3
0
def resolve_bound_resolver(resolver, root, info, **args):
    """
    Resolve provided resolver
    :param resolver: Explicit field resolver
    :param root: Schema root
    :param info: Schema info
    :param args: Schema args
    :return: Resolved field
    """
    resolver = get_unbound_function(resolver)
    return resolver(root, info, **args)
Ejemplo n.º 4
0
    def __new__(cls, name, bases, attrs):

        # Also ensure initialization is only performed for subclasses of
        # Mutation
        if not is_base_type(bases, DeleteMutationMeta):
            return type.__new__(cls, name, bases, attrs)

        cls = ObjectTypeMeta.__new__(cls, name, bases, attrs)
        input_class = getattr(cls, 'input_class', None)()

        field_args = props(input_class) if input_class else {}
        resolver = getattr(cls, 'mutate', None)
        assert resolver, 'All mutations must define a mutate method in it'
        resolver = get_unbound_function(resolver)
        cls.Field = partial(Field, cls, args=field_args, resolver=resolver)
        return cls
Ejemplo n.º 5
0
    def __init_subclass_with_meta__(
        cls,
        interfaces: Iterable[Type[Interface]] = (),
        resolver: Callable = None,
        arguments: Dict[str, "Argument"] = None,
        _meta: Optional[ObjectTypeOptions] = None,
        **options: Any,
    ) -> None:
        if not _meta:
            _meta = MutationOptions(cls)

        fields = {}

        for interface in interfaces:
            assert issubclass(interface, Interface), (
                'All interfaces of {} must be a subclass of Interface. Received "{}".'
            ).format(cls.__name__, interface)
            fields.update(interface._meta.fields)

        fields = OrderedDict()
        for base in reversed(cls.__mro__):
            fields.update(yank_fields_from_attrs(base.__dict__, _as=Field))

        if not arguments:
            input_class = getattr(cls, "Arguments", None)

            if input_class:
                arguments = props(input_class)
            else:
                arguments = {}

        if not resolver:
            mutate = getattr(cls, "mutate", None)
            assert mutate, "All mutations must define a mutate method in it"
            resolver = get_unbound_function(mutate)

        if _meta.fields:
            _meta.fields.update(fields)
        else:
            _meta.fields = fields

        _meta.interfaces = interfaces
        _meta.resolver = resolver
        _meta.arguments = arguments

        super(SQLAlchemyMutation, cls).__init_subclass_with_meta__(_meta=_meta,
                                                                   **options)
Ejemplo n.º 6
0
def _get_field_resolver(obj_type, orm_field_name, model_attr):
    """
    In order to support field renaming via `ORMField.model_attr`,
    we need to define resolver functions for each field.

    :param SQLAlchemyObjectType obj_type:
    :param model: the SQLAlchemy model
    :param str model_attr: the name of SQLAlchemy of the attribute used to resolve the field
    :rtype: Callable
    """
    # Since `graphene` will call `resolve_<field_name>` on a field only if it
    # does not have a `resolver`, we need to re-implement that logic here.
    resolver = getattr(obj_type, "resolve_{}".format(orm_field_name), None)
    if resolver:
        return get_unbound_function(resolver)

    return lambda root, _info: getattr(root, model_attr, None)
Ejemplo n.º 7
0
    def get_resolver(self, parent_resolver):
        """Intercept resolver to analyse permissions"""

        if getattr(parent_resolver, "func", None) != auth_resolver:
            parent_resolver = super(DjangoField,
                                    self).get_resolver(parent_resolver)

        if self.permissions:
            return partial(
                get_unbound_function(self.permissions_resolver),
                parent_resolver,
                self.permissions,
                None,
                None,
                True,
            )
        return parent_resolver
Ejemplo n.º 8
0
    def __init_subclass_with_meta__(cls,
                                    resolver=None,
                                    output=None,
                                    arguments=None,
                                    _meta=None,
                                    **options):
        if not _meta:
            _meta = FieldResolverOptions(cls)

        output = output or getattr(cls, 'Output', None)
        fields = {}
        if not output:
            # If output is defined, we don't need to get the fields
            fields = OrderedDict()
            for base in reversed(cls.__mro__):
                fields.update(yank_fields_from_attrs(base.__dict__, _as=Field))
            output = cls

        if not arguments:
            input_class = getattr(cls, 'Arguments', None)
            if input_class:
                arguments = props(input_class)
            else:
                arguments = {}

        if not resolver:
            _resolver = getattr(cls, 'resolve', None)
            assert _resolver, 'All field resolvers must define a resolve method'
            resolver = get_unbound_function(_resolver)

        if _meta.fields:
            _meta.fields.update(fields)
        else:
            _meta.fields = fields

        _meta.output = output
        _meta.resolver = resolver
        _meta.arguments = arguments

        super(FieldResolver, cls).__init_subclass_with_meta__(_meta=_meta,
                                                              **options)
Ejemplo n.º 9
0
    def __init_subclass_with_meta__(cls, serializer_class=None, only_fields=(), exclude_fields=(),
                                    save_resolver=None, delete_resolver=None,
                                    input_field_name=None, output_field_name=None, description='',
                                    nested_fields=False, **options):

        if not serializer_class:
            raise Exception('serializer_class is required on all DjangoSerializerMutation')

        model = serializer_class.Meta.model

        description = description or 'SerializerMutation for {} model'.format(model.__name__)

        input_field_name = input_field_name or 'new_{}'.format(model._meta.model_name)
        output_field_name = output_field_name or model._meta.model_name

        input_class = getattr(cls, 'Arguments', None)
        if not input_class:
            input_class = getattr(cls, 'Input', None)
            if input_class:
                warn_deprecation(("Please use {name}.Arguments instead of {name}.Input."
                                  "Input is now only used in ClientMutationID.\nRead more: "
                                  "https://github.com/graphql-python/graphene/blob/2.0/UPGRADE-v2.0.md#mutation-input").
                                 format(name=cls.__name__))
        if input_class:
            arguments = props(input_class)
        else:
            arguments = {}

        registry = get_global_registry()

        factory_kwargs = {
            'model': model,
            'only_fields': only_fields,
            'exclude_fields': exclude_fields,
            'nested_fields': nested_fields,
            'registry': registry,
            'skip_registry': False
        }

        output_type = registry.get_type_for_model(model)

        if not output_type:
            output_type = factory_type('output', DjangoObjectType, **factory_kwargs)

        django_fields = OrderedDict({output_field_name: Field(output_type)})

        global_arguments = {}
        for operation in ('create', 'delete', 'update'):
            global_arguments.update({operation: OrderedDict()})

            if operation != 'delete':
                input_type = registry.get_type_for_model(model, for_input=operation)

                if not input_type:
                    factory_kwargs.update({'skip_registry': True})
                    input_type = factory_type('input', DjangoInputObjectType, operation, **factory_kwargs)

                global_arguments[operation].update({
                    input_field_name: Argument(input_type, required=True)
                })
            else:
                global_arguments[operation].update({
                    'id': Argument(ID, required=True, description='Django object unique identification field')
                })
            global_arguments[operation].update(arguments)

        if not save_resolver:
            save_mutation = getattr(cls, 'save_mutation', None)
            save_resolver = get_unbound_function(save_mutation) if save_mutation else None

        if not delete_resolver:
            delete_mutation = getattr(cls, 'delete_mutation', None)
            delete_resolver = get_unbound_function(delete_mutation) if delete_mutation else None

        assert (save_resolver or delete_resolver), \
            'All the SerializerMutations must define at least one of this class  methods: ' \
            '\'save_mutation\' or \'delete_mutation\''

        _meta = SerializerMutationOptions(cls)
        _meta.output = cls
        _meta.arguments = global_arguments
        _meta.fields = django_fields
        _meta.output_type = output_type
        _meta.save_resolver = save_resolver
        _meta.delete_resolver = delete_resolver
        _meta.model = model
        _meta.serializer_class = serializer_class
        _meta.input_field_name = input_field_name
        _meta.output_field_name = output_field_name

        super(DjangoSerializerMutation, cls).__init_subclass_with_meta__(_meta=_meta, description=description,
                                                                         **options)
Ejemplo n.º 10
0
    def __init_subclass_with_meta__(cls,
                                    serializer_class=None,
                                    only_fields=(),
                                    exclude_fields=(),
                                    save_resolver=None,
                                    delete_resolver=None,
                                    input_field_name=None,
                                    output_field_name=None,
                                    description='',
                                    nested_fields=False,
                                    **options):

        if not serializer_class:
            raise Exception(
                'serializer_class is required on all DjangoSerializerMutation')

        model = serializer_class.Meta.model

        description = description or 'SerializerMutation for {} model'.format(
            model.__name__)

        input_field_name = input_field_name or 'new_{}'.format(
            model._meta.model_name)
        output_field_name = output_field_name or model._meta.model_name

        input_class = getattr(cls, 'Arguments', None)
        if not input_class:
            input_class = getattr(cls, 'Input', None)
            if input_class:
                warn_deprecation((
                    "Please use {name}.Arguments instead of {name}.Input."
                    "Input is now only used in ClientMutationID.\nRead more: "
                    "https://github.com/graphql-python/graphene/blob/2.0/UPGRADE-v2.0.md#mutation-input"
                ).format(name=cls.__name__))
        if input_class:
            arguments = props(input_class)
        else:
            arguments = {}

        registry = get_global_registry()

        factory_kwargs = {
            'model': model,
            'only_fields': only_fields,
            'exclude_fields': exclude_fields,
            'nested_fields': nested_fields,
            'registry': registry,
            'skip_registry': False
        }

        output_type = registry.get_type_for_model(model)

        if not output_type:
            output_type = factory_type('output', DjangoObjectType,
                                       **factory_kwargs)

        django_fields = OrderedDict({output_field_name: Field(output_type)})

        global_arguments = {}
        for operation in ('create', 'delete', 'update'):
            global_arguments.update({operation: OrderedDict()})

            if operation != 'delete':
                input_type = registry.get_type_for_model(model,
                                                         for_input=operation)

                if not input_type:
                    factory_kwargs.update({'skip_registry': True})
                    input_type = factory_type('input', DjangoInputObjectType,
                                              operation, **factory_kwargs)

                global_arguments[operation].update(
                    {input_field_name: Argument(input_type, required=True)})
            else:
                global_arguments[operation].update({
                    'id':
                    Argument(
                        ID,
                        required=True,
                        description='Django object unique identification field'
                    )
                })
            global_arguments[operation].update(arguments)

        if not save_resolver:
            save_mutation = getattr(cls, 'save_mutation', None)
            save_resolver = get_unbound_function(
                save_mutation) if save_mutation else None

        if not delete_resolver:
            delete_mutation = getattr(cls, 'delete_mutation', None)
            delete_resolver = get_unbound_function(
                delete_mutation) if delete_mutation else None

        assert (save_resolver or delete_resolver), \
            'All the SerializerMutations must define at least one of this class  methods: ' \
            '\'save_mutation\' or \'delete_mutation\''

        _meta = SerializerMutationOptions(cls)
        _meta.output = cls
        _meta.arguments = global_arguments
        _meta.fields = django_fields
        _meta.output_type = output_type
        _meta.save_resolver = save_resolver
        _meta.delete_resolver = delete_resolver
        _meta.model = model
        _meta.serializer_class = serializer_class
        _meta.input_field_name = input_field_name
        _meta.output_field_name = output_field_name

        super(DjangoSerializerMutation,
              cls).__init_subclass_with_meta__(_meta=_meta,
                                               description=description,
                                               **options)