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'))
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
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)
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
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)
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)
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
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)
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)
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)