def __init_subclass__(cls, **meta_options): _Meta = getattr(cls, "Meta", None) _meta_props = {} if _Meta: if isinstance(_Meta, dict): _meta_props = _Meta elif isclass(_Meta): _meta_props = props(_Meta) else: raise Exception( "Meta have to be either a class or a dict. Received {}".format( _Meta ) ) options = dict(meta_options, **_meta_props) abstract = options.pop("abstract", False) if abstract: assert not options, ( "Abstract types can only contain the abstract attribute. " "Received: abstract, {option_keys}" ).format(option_keys=", ".join(options.keys())) else: super_class = super(cls, cls) if hasattr(super_class, "__init_subclass_with_meta__"): super_class.__init_subclass_with_meta__(**options)
def __new__(cls, name, bases, attrs): input_class = attrs.pop('Input', None) if input_class: input_attrs = props(input_class) attrs['Input'] = type('Input', (input_class, MutationRevisionMessage), input_attrs) cls.Input = attrs['Input'] return super().__new__(cls, name, bases, attrs)
def _get_argument_fields(cls): 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__)) arguments_props = {} if input_class: arguments_props = props(input_class) return arguments_props
def __init_subclass_with_meta__(cls, model=None, registry=None, optional_fields=[], only_fields=(), exclude_fields=None, **options): meta = SQLAlchemyMutationOptions(cls) meta.model = model model_inspect = sqlalchemyinspect(model) cls._model_inspect = model_inspect if not isinstance(exclude_fields, list): if exclude_fields: exclude_fields = list(exclude_fields) else: exclude_fields = [] for primary_key_column in model_inspect.primary_key: if primary_key_column.autoincrement: exclude_fields.append(primary_key_column.name) for relationship in model_inspect.relationships: exclude_fields.append(relationship.key) for field in model_inspect.all_orm_descriptors: if type(field) == hybrid_property: exclude_fields.append(field.__name__) if not registry: registry = get_global_registry() fields = construct_fields(model, registry, only_fields, exclude_fields) for field_name in optional_fields: if field_name in fields: fields[field_name].kwargs["required"] = False argument_cls = getattr(cls, "Arguments", None) if argument_cls: fields.update(props(argument_cls)) arguments = yank_fields_from_attrs(fields, _as=Argument) super(SQLAlchemyMutation, cls).__init_subclass_with_meta__(_meta=meta, arguments=arguments, **options)
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 __init_subclass_with_meta__(cls, resolver=None, output=None, arguments=None, _meta=None, **options): if not _meta: _meta = SubscriptionOptions(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: assert hasattr( cls, 'next'), 'All subscriptions must define a next method in it' resolver = get_unbound_function(getattr(cls, 'subscribe')) if _meta.fields: _meta.fields.update(fields) else: _meta.fields = fields _meta.output = output _meta.resolver = resolver _meta.arguments = arguments super(Subscription, cls).__init_subclass_with_meta__(_meta=_meta, **options)
def __init_subclass_with_meta__( cls, serializer_class=None, queryset=None, only_fields=(), include_fields=(), exclude_fields=(), pagination=None, input_field_name=None, output_field_name=None, results_field_name=None, nested_fields=(), filter_fields=None, description="", filterset_class=None, **options, ): if not serializer_class: raise Exception( "serializer_class is required on all ModelSerializerType") model = serializer_class.Meta.model description = description or "ModelSerializerType 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, "include_fields": include_fields, "exclude_fields": exclude_fields, "filter_fields": filter_fields, "pagination": pagination, "queryset": queryset, "nested_fields": nested_fields, "registry": registry, "skip_registry": False, "filterset_class": filterset_class, "results_field_name": results_field_name, } output_type = registry.get_type_for_model(model) if not output_type: output_type = factory_type("output", DjangoObjectType, **factory_kwargs) output_list_type = factory_type("list", DjangoListObjectType, **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) _meta = DjangoSerializerOptions(cls) _meta.mutation_output = cls _meta.arguments = global_arguments _meta.fields = django_fields _meta.output_type = output_type _meta.output_list_type = output_list_type _meta.model = model _meta.queryset = queryset or model._default_manager _meta.serializer_class = serializer_class _meta.input_field_name = input_field_name _meta.output_field_name = output_field_name _meta.nested_fields = nested_fields super(DjangoSerializerType, cls).__init_subclass_with_meta__(_meta=_meta, description=description, **options)
def __init_subclass_with_meta__(cls, serializer_class=None, queryset=None, only_fields=(), exclude_fields=(), pagination=None, input_field_name=None, output_field_name=None, results_field_name=None, nested_fields=False, filter_fields=None, description='', **options): if not serializer_class: raise Exception('serializer_class is required on all ModelSerializerType') model = serializer_class.Meta.model description = description or 'ModelSerializerType 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() outputType = registry.get_type_for_model(model) if not outputType: outputType = object_type_factory(DjangoObjectType, new_model=model, new_only_fields=only_fields, new_exclude_fields=exclude_fields, new_filter_fields=filter_fields, new_registry=registry) outputListType = object_list_type_factory(DjangoListObjectType, model, new_only_fields=only_fields, new_exclude_fields=exclude_fields, new_queryset=queryset, new_results_field_name=results_field_name, new_filter_fields=filter_fields, new_pagination=pagination) django_fields = OrderedDict({output_field_name: Field(outputType)}) global_arguments = {} for operation in ('create', 'delete', 'update'): global_arguments.update({operation: OrderedDict()}) if operation != 'delete': inputType = registry.get_type_for_model(model, for_input=operation) if not inputType: inputType = input_object_type_factory(DjangoInputObjectType, new_model=model, new_only_fields=only_fields, new_input_for=operation, new_exclude_fields=exclude_fields, new_registry=registry, new_skip_registry=True, new_nested_fields=nested_fields) global_arguments[operation].update({ input_field_name: Argument(inputType, required=True) }) else: global_arguments[operation].update({ 'id': Argument(ID, required=True, description='Django object unique identification field') }) global_arguments[operation].update(arguments) _meta = DjangoSerializerOptions(cls) _meta.mutation_output = cls _meta.arguments = global_arguments _meta.fields = django_fields _meta.output_type = outputType _meta.output_list_type = outputListType _meta.model = model _meta.queryset = queryset or model._default_manager _meta.serializer_class = serializer_class _meta.input_field_name = input_field_name _meta.output_field_name = output_field_name super(DjangoSerializerType, 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)
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 __new__(cls, name, bases, attrs): # Also ensure initialization is only performed for subclasses of # Mutation if not is_base_type(bases, ClientIDMutationMeta): return type.__new__(cls, name, bases, attrs) defaults = dict( name=name, description=attrs.pop('__doc__', None), interfaces=(), local_fields=None, permission_classes=(), throttle_classes=(), # for Django Model Permissions model=None, # for permissions method=None, # 'CREATE', 'UPDATE', 'DELETE' only this 3 accepted form_class=None, lookup_field='pk', lookup_kwarg=None ) options = Options( attrs.pop('Config', None), **defaults ) if options.model is not None: assert is_valid_django_model(options.model), ( 'You need to pass a valid Django Model in {}.Meta, received "{}".' ).format(name, options.model) input_class = attrs.pop('Input', None) base_name = re.sub('Payload$', '', name) if 'client_mutation_id' not in attrs: attrs['client_mutation_id'] = String(name='clientMutationId') cls = ObjectTypeMeta.__new__(cls, '{}Payload'.format(base_name), bases, dict(attrs, _meta=options)) mutate_and_get_payload = getattr(cls, 'mutate_and_get_payload', None) if cls.mutate and cls.mutate.__func__ == ClientIDMutation.mutate.__func__: assert mutate_and_get_payload, ( "{}.mutate_and_get_payload method is required" " in a ClientIDMutation." ).format(name) input_attrs = {} bases = () if not input_class: input_attrs = {} elif not issubclass(input_class, AbstractType): input_attrs = props(input_class) else: bases += (input_class, ) input_attrs['client_mutation_id'] = String(name='clientMutationId') # If method is update and delete add id to input attrs if options.method is not None and options.method.upper() in ['UPDATE', 'DELETE']: input_attrs['id'] = String(name='id', required=True) cls.Input = type('{}Input'.format(base_name), bases + (InputObjectType,), input_attrs) cls.Field = partial(Field, cls, resolver=cls.mutate, input=Argument(cls.Input, required=True)) return cls
def __init_subclass_with_meta__(cls, serializer_class=None, queryset=None, only_fields=(), exclude_fields=(), pagination=None, input_field_name=None, output_field_name=None, results_field_name=None, nested_fields=False, filter_fields=None, description='', filterset_class=None, **options): if not serializer_class: raise Exception('serializer_class is required on all ModelSerializerType') model = serializer_class.Meta.model description = description or 'ModelSerializerType 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, 'filter_fields': filter_fields, 'pagination': pagination, 'queryset': queryset, 'nested_fields': nested_fields, 'registry': registry, 'skip_registry': False, 'filterset_class': filterset_class } output_type = registry.get_type_for_model(model) if not output_type: output_type = factory_type('output', DjangoObjectType, **factory_kwargs) output_list_type = factory_type('list', DjangoListObjectType, **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) _meta = DjangoSerializerOptions(cls) _meta.mutation_output = cls _meta.arguments = global_arguments _meta.fields = django_fields _meta.output_type = output_type _meta.output_list_type = output_list_type _meta.model = model _meta.queryset = queryset or model._default_manager _meta.serializer_class = serializer_class _meta.input_field_name = input_field_name _meta.output_field_name = output_field_name super(DjangoSerializerType, cls).__init_subclass_with_meta__(_meta=_meta, description=description, **options)
def __init_subclass_with_meta__(cls, model=None, name=None, description=None, interfaces=(), resolver=None, output=None, _meta=None, arguments=None, **options): assert model, "All Objects must define a Meta class with the model in it" assert issubclass( model, models.Model), "Model value must be a valid Django model" assert output, "Output Type must be defined in the Meta class" assert issubclass( output, ObjectType), "Outout Type must be a valid graphene object type" if not _meta: _meta = SubscriptionOptions(cls) output = output or getattr(cls, "Output", None) fields = {} for interface in interfaces: assert issubclass( interface, Interface ), f'All interfaces of {cls.__name__} must be a subclass of Interface. Received "{interface}".' fields.update(interface._meta.fields) if not arguments: input_class = getattr(cls, "Arguments", None) if input_class: arguments = props(input_class) else: arguments = {} if not resolver: resolver = cls._resolver assert hasattr( cls, "subscribe" ), "All subscribtions must define a subscribe method in it" post_save.connect(DjangoObjectSubscription.post_save_subscription, sender=model) post_delete.connect(DjangoObjectSubscription.post_delete_subscription, sender=model) if _meta.fields: _meta.fields.update(fields) else: _meta.fields = fields _meta.interfaces = interfaces _meta.output = output _meta.resolver = resolver _meta.arguments = arguments _meta.name = name _meta.model = model _meta.description = description super(DjangoObjectSubscription, cls).__init_subclass_with_meta__(_meta=_meta, name=name, description=description, **options)