def define_generic_order_types(self): self._gql_ordertypes['directionEnum'] = GraphQLEnumType( 'directionEnum', values=OrderedDict( ASC=GraphQLEnumValue(), DESC=GraphQLEnumValue() ) ) self._gql_ordertypes['nullsOrderingEnum'] = GraphQLEnumType( 'nullsOrderingEnum', values=OrderedDict( SMALLEST=GraphQLEnumValue(), BIGGEST=GraphQLEnumValue(), ) ) self._gql_ordertypes['Ordering'] = GraphQLInputObjectType( 'Ordering', fields=OrderedDict( dir=GraphQLInputObjectField( GraphQLNonNull(self._gql_ordertypes['directionEnum']), ), nulls=GraphQLInputObjectField( self._gql_ordertypes['nullsOrderingEnum'], default_value='SMALLEST', ), ) )
def get_filter_fields(self, typename): selftype = self._gql_inobjtypes[typename] fields = OrderedDict() fields['and'] = GraphQLInputObjectField( GraphQLList(GraphQLNonNull(selftype))) fields['or'] = GraphQLInputObjectField( GraphQLList(GraphQLNonNull(selftype))) fields['not'] = GraphQLInputObjectField(selftype) edb_type = self.edb_schema.get(typename) for name in sorted(edb_type.pointers, key=lambda x: x.name): if name.name == '__type__': continue if name.name in fields: raise GraphQLCoreError( f"{name.name!r} of {typename} clashes with special " "reserved fields required for GraphQL conversion" ) ptr = edb_type.resolve_pointer(self.edb_schema, name) if not isinstance(ptr.target, ScalarType): continue target = self._convert_edb_type(ptr.target) intype = self._gql_inobjtypes.get(f'Filter{target.name}') if intype: fields[name.name] = GraphQLInputObjectField(intype) return fields
def get_update_fields(self, typename): fields = OrderedDict() edb_type = self.edb_schema.get(typename) pointers = edb_type.get_pointers(self.edb_schema) names = sorted(pointers.keys(self.edb_schema)) for name in names: if name == '__type__': continue ptr = edb_type.getptr(self.edb_schema, name) edb_target = ptr.get_target(self.edb_schema) if edb_target.is_object_type(): intype = self._gql_inobjtypes.get( f'UpdateOp{typename}__{name}') if intype is None: # the links can only be updated by selecting some # objects, meaning that the basis is the same as for # query of whatever is the link type intype = self._gql_inobjtypes.get( f'NestedUpdate{edb_target.get_name(self.edb_schema)}') if intype is None: # construct a nested insert type intype = self._make_generic_nested_update_type( edb_target) # depending on whether this is a multilink or not wrap # it in a List intype = self._wrap_target( ptr, intype, ignore_required=True) # wrap into additional layer representing update ops intype = self._make_generic_update_op_type( ptr, name, edb_type, intype) fields[name] = GraphQLInputObjectField(intype) elif edb_target.is_scalar() or edb_target.is_array(): target = self._convert_edb_type(edb_target) if target is None or ptr.get_readonly(self.edb_schema): # don't expose this continue intype = self._gql_inobjtypes.get( f'UpdateOp{typename}__{name}') if intype is None: # construct a nested insert type target = self._wrap_target( ptr, target, ignore_required=True) intype = self._make_generic_update_op_type( ptr, name, edb_type, target) if intype: fields[name] = GraphQLInputObjectField(intype) else: continue return fields
def create_type(): return GraphQLInputObjectType( name='WorksheetEntryInput', fields=lambda: { 'line': GraphQLInputObjectField(type=req(GraphQLString)), 'column': GraphQLInputObjectField(type=req(GraphQLString)), 'value': GraphQLInputObjectField(type=req(GraphQLString)), }, )
def get_filter_fields(self, typename, nested=False): selftype = self._gql_inobjtypes[typename] fields = OrderedDict() if not nested: fields['and'] = GraphQLInputObjectField( GraphQLList(GraphQLNonNull(selftype))) fields['or'] = GraphQLInputObjectField( GraphQLList(GraphQLNonNull(selftype))) fields['not'] = GraphQLInputObjectField(selftype) edb_type = self.edb_schema.get(typename) pointers = edb_type.get_pointers(self.edb_schema) names = sorted(pointers.keys(self.edb_schema)) for name in names: if name == '__type__': continue if name in fields: raise g_errors.GraphQLCoreError( f"{name!r} of {typename} clashes with special " "reserved fields required for GraphQL conversion" ) ptr = edb_type.getptr(self.edb_schema, name) edb_target = ptr.get_target(self.edb_schema) if edb_target.is_object_type(): t_name = edb_target.get_name(self.edb_schema) gql_name = self.get_input_name( 'NestedFilter', self.get_gql_name(t_name)) intype = self._gql_inobjtypes.get(gql_name) if intype is None: # construct a nested insert type intype = GraphQLInputObjectType( name=gql_name, fields=partial(self.get_filter_fields, t_name, True), ) self._gql_inobjtypes[gql_name] = intype elif not edb_target.is_scalar(): continue else: target = self._convert_edb_type(edb_target) if target is None: # don't expose this continue intype = self._gql_inobjtypes.get(f'Filter{target.name}') if intype: fields[name] = GraphQLInputObjectField(intype) return fields
def test_merged_input_object_type_has_name_of_original_type(self): self._assert_merge( [ GraphQLInputObjectType("Object", fields={ "id": GraphQLInputObjectField(type=GraphQLInt), }), GraphQLInputObjectType("Object", fields={ "id": GraphQLInputObjectField(type=GraphQLInt), }), ], has_properties(name="Object"), )
def create_type(): return GraphQLInputObjectType( name='CreateWorksheetInstanceInput', fields=lambda: { 'reportRecordNumber': GraphQLInputObjectField(type=req(GraphQLInt)), 'worksheetCode': GraphQLInputObjectField(type=req(GraphQLString)), 'worksheetEntries': GraphQLInputObjectField(type=req( list_of(req(GraphQLWorksheetEntryInput.type())))), }, )
def get_insert_fields(self, typename): fields = OrderedDict() edb_type = self.edb_schema.get(typename) pointers = edb_type.get_pointers(self.edb_schema) names = sorted(pointers.keys(self.edb_schema)) for name in names: if name == '__type__': continue ptr = edb_type.getptr(self.edb_schema, name) edb_target = ptr.get_target(self.edb_schema) if edb_target.is_object_type(): typename = edb_target.get_name(self.edb_schema) intype = self._gql_inobjtypes.get(f'NestedInsert{typename}') if intype is None: # construct a nested insert type intype = self._make_generic_nested_insert_type(edb_target) intype = self._wrap_target(ptr, intype, for_input=True) fields[name] = GraphQLInputObjectField(intype) elif edb_target.is_scalar() or edb_target.is_array(): target = self._convert_edb_type(edb_target) if target is None: # don't expose this continue if edb_target.is_array(): intype = self._gql_inobjtypes.get( f'Insert{target.of_type.of_type.name}') intype = GraphQLList(GraphQLNonNull(intype)) elif edb_target.is_enum(self.edb_schema): typename = edb_target.get_name(self.edb_schema) intype = self._gql_inobjtypes.get(f'Insert{typename}') else: intype = self._gql_inobjtypes.get(f'Insert{target.name}') intype = self._wrap_target(ptr, intype, for_input=True) if intype: fields[name] = GraphQLInputObjectField(intype) else: continue return fields
def test_field_type_is_common_supertype_of_field_types(self): self._assert_merge( [ GraphQLInputObjectType("Object", fields={ "id": GraphQLInputObjectField(type=GraphQLNonNull(GraphQLInt)), }), GraphQLInputObjectType("Object", fields={ "id": GraphQLInputObjectField(type=GraphQLInt), }), ], is_input_object_type(fields=has_entries({ "id": is_input_field(type=is_int), })), )
def test_input_object_types_are_merged_to_input_object_type_with_union_of_fields(self): self._assert_merge( [ GraphQLInputObjectType("Object", fields={ "id": GraphQLInputObjectField(type=GraphQLInt), }), GraphQLInputObjectType("Object", fields={ "name": GraphQLInputObjectField(type=GraphQLString), }), ], is_input_object_type(fields=has_entries({ "id": is_input_field(type=is_int), "name": is_input_field(type=is_string), })), )
def test_types_within_list_types_are_merged(self): self._assert_merge( [ GraphQLList(GraphQLInputObjectType("Object", fields={ "id": GraphQLInputObjectField(type=GraphQLInt), })), GraphQLList(GraphQLInputObjectType("Object", fields={ "name": GraphQLInputObjectField(type=GraphQLString), })), ], is_list_type(is_input_object_type(fields=has_entries({ "id": is_input_field(type=is_int), "name": is_input_field(type=is_string), }))), )
def define_generic_order_types(self): self._gql_ordertypes['directionEnum'] = \ self._gql_enums['directionEnum'] self._gql_ordertypes['nullsOrderingEnum'] = \ self._gql_enums['nullsOrderingEnum'] self._gql_ordertypes['Ordering'] = GraphQLInputObjectType( 'Ordering', fields=OrderedDict( dir=GraphQLInputObjectField( GraphQLNonNull(self._gql_enums['directionEnum']), ), nulls=GraphQLInputObjectField( self._gql_enums['nullsOrderingEnum'], default_value='SMALLEST', ), ))
def get_order_fields(self, typename): fields = OrderedDict() edb_type = self.edb_schema.get(typename) pointers = edb_type.get_pointers(self.edb_schema) names = sorted(pointers.keys(self.edb_schema)) for name in names: if name == '__type__': continue ptr = edb_type.getptr(self.edb_schema, name) if not ptr.get_target(self.edb_schema).is_scalar(): continue target = self._convert_edb_type(ptr.get_target(self.edb_schema)) if target is None: # don't expose this continue # this makes sure that we can only order by properties # that can be reflected into GraphQL intype = self._gql_inobjtypes.get(f'Filter{target.name}') if intype: fields[name] = GraphQLInputObjectField( self._gql_ordertypes['Ordering']) return fields
def _make_generic_input_type(self, base, ops): name = f'Filter{base.name}' self._gql_inobjtypes[name] = GraphQLInputObjectType( name=name, fields={op: GraphQLInputObjectField(base) for op in ops}, )
def create_type(): return GraphQLInputObjectType( name='TodoUserInput', fields=lambda: { 'name': GraphQLInputObjectField(type=req(GraphQLString)), }, )
def _common_superfield(left, right): if left is None: return right elif right is None: return left else: type = _common_supertype(left.type, right.type) return GraphQLInputObjectField(type=type)
def _make_generic_nested_insert_type(self, edb_base): typename = edb_base.get_name(self.edb_schema) name = f'NestedInsert{typename}' fields = { 'filter': GraphQLInputObjectField(self._gql_inobjtypes[typename]), 'order': GraphQLInputObjectField(self._gql_ordertypes[typename]), 'first': GraphQLInputObjectField(GraphQLInt), 'last': GraphQLInputObjectField(GraphQLInt), # before and after are supposed to be opaque values # serialized to string 'before': GraphQLInputObjectField(GraphQLString), 'after': GraphQLInputObjectField(GraphQLString), } # The data can only be a specific non-interface type, if no # such type exists, skip it as we cannot accept unambiguous # data input. It's still possible to just select some existing # data. data_t = self._gql_inobjtypes.get(f'Insert{typename}') if data_t: fields['data'] = GraphQLInputObjectField(data_t) nitype = GraphQLInputObjectType( name=self.get_input_name('NestedInsert', self.get_gql_name(typename)), fields=fields, ) self._gql_inobjtypes[name] = nitype return nitype
def _make_generic_nested_insert_type(self, edb_base): typename = edb_base.get_name(self.edb_schema) name = f'NestedInsert{typename}' nitype = GraphQLInputObjectType( name=self.get_input_name('NestedInsert', self.get_gql_name(typename)), fields={ 'data': GraphQLInputObjectField( self._gql_inobjtypes[f'Insert{typename}']), 'filter': GraphQLInputObjectField(self._gql_inobjtypes[typename]), 'order': GraphQLInputObjectField(self._gql_ordertypes[typename]), 'first': GraphQLInputObjectField(GraphQLInt), 'last': GraphQLInputObjectField(GraphQLInt), # before and after are supposed to be opaque values # serialized to string 'before': GraphQLInputObjectField(GraphQLString), 'after': GraphQLInputObjectField(GraphQLString), }, ) self._gql_inobjtypes[name] = nitype return nitype
def _make_generic_update_op_type(self, ptr, fname, edb_base, target): typename = edb_base.get_name(self.edb_schema) name = f'UpdateOp{typename}__{fname}' edb_target = ptr.get_target(self.edb_schema) fields = { 'set': GraphQLInputObjectField(target) } # get additional commands based on the pointer type if not ptr.get_required(self.edb_schema): fields['clear'] = GraphQLInputObjectField(GraphQLBoolean) if edb_target.is_scalar(): base_target = edb_target.get_topmost_concrete_base(self.edb_schema) bt_name = base_target.get_name(self.edb_schema) else: bt_name = None # first check for this being a multi-link if not ptr.singular(self.edb_schema): fields['add'] = GraphQLInputObjectField(target) fields['remove'] = GraphQLInputObjectField(target) elif target in {GraphQLInt, GraphQLInt64, GraphQLBigint, GraphQLFloat, GraphQLDecimal}: # anything that maps onto the numeric types is a fair game fields['increment'] = GraphQLInputObjectField(target) fields['decrement'] = GraphQLInputObjectField(target) elif bt_name == 'std::str' or edb_target.is_array(): # only actual strings and arrays have append, prepend and # slice ops fields['prepend'] = GraphQLInputObjectField(target) fields['append'] = GraphQLInputObjectField(target) # slice [from, to] fields['slice'] = GraphQLInputObjectField( GraphQLList(GraphQLNonNull(GraphQLInt)) ) nitype = GraphQLInputObjectType( name=self.get_input_name( f'UpdateOp_{fname}_', self.get_gql_name(typename)), fields=fields, ) self._gql_inobjtypes[name] = nitype return nitype
def map_input_fields(self, cls: Type) -> Dict[str, GraphQLInputObjectField]: fields = {} hints = types.get_annotations(cls) for field in dataclasses.fields(cls): if field.name not in hints: raise SchemaError(f"""No type hint found for {cls}.{field}. Suggestion: add a type hint (e.g., ': {field.type or '<type>'} = ...' to your declaration.""" ) fields[field.name] = GraphQLInputObjectField( type=self.translate_annotation(hints[field.name])) return fields
def get_filter_fields(self, typename): selftype = self._gql_inobjtypes[typename] fields = OrderedDict() fields['and'] = GraphQLInputObjectField( GraphQLList(GraphQLNonNull(selftype))) fields['or'] = GraphQLInputObjectField( GraphQLList(GraphQLNonNull(selftype))) fields['not'] = GraphQLInputObjectField(selftype) edb_type = self.edb_schema.get(typename) pointers = edb_type.get_pointers(self.edb_schema) names = sorted(pointers.keys(self.edb_schema)) for name in names: if name == '__type__': continue if name in fields: raise g_errors.GraphQLCoreError( f"{name!r} of {typename} clashes with special " "reserved fields required for GraphQL conversion" ) ptr = edb_type.getptr(self.edb_schema, name) if not isinstance(ptr.get_target(self.edb_schema), s_scalars.ScalarType): continue target = self._convert_edb_type(ptr.get_target(self.edb_schema)) if target is None: # don't expose this continue intype = self._gql_inobjtypes.get(f'Filter{target.name}') if intype: fields[name] = GraphQLInputObjectField(intype) return fields
def mutation(name, input_fields, output_fields, mutate_and_get_payload, description=None): # https://github.com/graphql/graphql-relay-js/blob/master/src/mutation/mutation.js augmented_input_fields = { **input_fields, 'clientMutationId': GraphQLInputObjectField(type=GraphQLBoolean), } augmented_output_fields = { **output_fields, 'clientMutationId': GraphQLField(type=GraphQLBoolean), } output_type = GraphQLObjectType(name=name + 'Payload', fields=augmented_output_fields) input_type = GraphQLInputObjectType(name=name + 'Input', fields=augmented_input_fields) def sync_resolve(parent, info, *, input): logger.info('sync_resolver(%r, %r, %r)', parent, info, input) assert isinstance(input, dict) cmi = input.get('clientMutationId') result = mutate_and_get_payload(info, **input) result.clientMutationId = cmi return result async def async_resolve(parent, info, *, input): logger.info('async_resolver(%r, %r, %r)', parent, info, input) assert isinstance(input, dict) cmi = input.get('clientMutationId') result = await mutate_and_get_payload(info, **input) result.clientMutationId = cmi return result if asyncio.iscoroutinefunction(mutate_and_get_payload): resolve = async_resolve else: resolve = sync_resolve return GraphQLField( description=description, type=output_type, args={ 'input': GraphQLArgument(type=GraphQLNonNull(type=input_type)), }, resolver=resolve)
def construct_fields_for_type(self, map, type, is_input_type=False): fields = OrderedDict() for name, field in type._meta.fields.items(): if isinstance(field, Dynamic): field = get_field_as(field.get_type(self.schema), _as=Field) if not field: continue map = self.reducer(map, field.type) field_type = self.get_field_type(map, field.type) if is_input_type: _field = GraphQLInputObjectField( field_type, default_value=field.default_value, out_name=name, description=field.description) else: args = OrderedDict() for arg_name, arg in field.args.items(): map = self.reducer(map, arg.type) arg_type = self.get_field_type(map, arg.type) processed_arg_name = arg.name or self.get_name(arg_name) args[processed_arg_name] = GraphQLArgument( arg_type, out_name=arg_name, description=arg.description, default_value=arg.default_value) _field = GraphQLField( field_type, args=args, resolver=field.get_resolver( self.get_resolver_for_type( type, name, field.default_value ) ), deprecation_reason=field.deprecation_reason, description=field.description) field_name = field.name or self.get_name(name) fields[field_name] = _field return fields
def get_order_fields(self, typename): fields = OrderedDict() edb_type = self.edb_schema.get(typename) for name in sorted(edb_type.pointers, key=lambda x: x.name): if name.name == '__type__': continue ptr = edb_type.resolve_pointer(self.edb_schema, name) if not isinstance(ptr.target, ScalarType): continue target = self._convert_edb_type(ptr.target) # this makes sure that we can only order by properties # that can be reflected into GraphQL intype = self._gql_inobjtypes.get(f'Filter{target.name}') if intype: fields[name.name] = GraphQLInputObjectField( self._gql_ordertypes['Ordering'] ) return fields
def create_type(): return GraphQLInputObjectType( name='ProviderCsvRow', fields=lambda: { 'provider': GraphQLInputObjectField(type=req(GraphQLString)), 'fyb': GraphQLInputObjectField(type=req(GraphQLString)), 'fye': GraphQLInputObjectField(type=req(GraphQLString)), 'status': GraphQLInputObjectField(type=req(GraphQLString)), 'ctrl_type': GraphQLInputObjectField(type=req(GraphQLString)), 'hosp_name': GraphQLInputObjectField(type=req(GraphQLString)), 'street_addr': GraphQLInputObjectField(type=GraphQLString), 'po_box': GraphQLInputObjectField(type=GraphQLString), 'city': GraphQLInputObjectField(type=req(GraphQLString)), 'state': GraphQLInputObjectField(type=req(GraphQLString)), 'zip_code': GraphQLInputObjectField(type=req(GraphQLString)), 'county': GraphQLInputObjectField(type=GraphQLString), }, )
def create_type(): return GraphQLInputObjectType( name='ReportCsvRow', fields=lambda: { 'rpt_rec_num': GraphQLInputObjectField(type=req(GraphQLString)), 'prvdr_ctrl_type_cd': GraphQLInputObjectField(type=req(GraphQLString)), 'prvdr_num': GraphQLInputObjectField(type=req(GraphQLString)), 'rpt_stus_cd': GraphQLInputObjectField(type=req(GraphQLString)), 'initl_rpt_sw': GraphQLInputObjectField(type=req(GraphQLString)), 'last_rpt_sw': GraphQLInputObjectField(type=req(GraphQLString)), 'trnsmtl_num': GraphQLInputObjectField(type=req(GraphQLString)), 'fi_num': GraphQLInputObjectField(type=req(GraphQLString)), 'adr_vndr_cd': GraphQLInputObjectField(type=req(GraphQLString)), 'util_cd': GraphQLInputObjectField(type=req(GraphQLString)), 'spec_ind': GraphQLInputObjectField(type=GraphQLString), 'npi': GraphQLInputObjectField(type=GraphQLString), 'fy_bgn_dt': GraphQLInputObjectField(type=req(GraphQLString)), 'fy_end_dt': GraphQLInputObjectField(type=req(GraphQLString)), 'proc_dt': GraphQLInputObjectField(type=req(GraphQLString)), 'fi_creat_dt': GraphQLInputObjectField(type=req(GraphQLString)), 'npr_dt': GraphQLInputObjectField(type=GraphQLString), 'fi_rcpt_dt': GraphQLInputObjectField(type=req(GraphQLString)), }, )
logger.info('handle_post_reply(%r, **%r)', info, kwargs) model = info.context['request'].app['model'] reply_post = await model.create_reply_post(kwargs['postId'], kwargs['bodyMarkdown']) for event in conversation_update_events[reply_post.conversation_id]: logger.info('Notifying event %r for conversation %r', event, reply_post.conversation_id) event.set() return reply_post PostReplyMutation = mutation( name='PostReply', input_fields={ 'postId': GraphQLInputObjectField(type=GraphQLNonNull(GraphQLID)), 'bodyMarkdown': GraphQLInputObjectField(type=GraphQLNonNull(GraphQLString)), }, output_fields={ 'newReplyPost': GraphQLField(type=ReplyPost), }, mutate_and_get_payload=handle_post_reply) async def resolve_count_seconds(root, info): from asyncio import sleep for i in range(100): yield i await sleep(1)
GraphQLDeleteTodoItemPayload = GraphQLObjectType( name='DeleteTodoItemPayload', fields=lambda: { 'deletedId': GraphQLField( type=GraphQLUUID, # type: ignore resolver=define_default_resolver('deleted_id'), ), }, ) GraphQLCreateTodoUserData = GraphQLInputObjectType( name='CreateTodoUserData', fields=lambda: { 'name': GraphQLInputObjectField(type=req(GraphQLString) ), # type: ignore 'username': GraphQLInputObjectField(type=req(GraphQLString) ), # type: ignore }, ) GraphQLUpdateTodoUserData = GraphQLInputObjectType( name='UpdateTodoUserData', fields=lambda: { 'name': GraphQLInputObjectField(type=GraphQLString), # type: ignore }, ) GraphQLCreateTodoListData = GraphQLInputObjectType( name='CreateTodoListData', fields=lambda: {
def to_graphql_input_field(self): return GraphQLInputObjectField(type=self.type)
from graphql import (GraphQLInputObjectType, GraphQLInputObjectField, GraphQLField, GraphQLNonNull, GraphQLString, GraphQLArgument) from ..types.contest_type import ContestType from ...utils.resolver import resolver_wrapper from ...database import pgdb ContestInputType = GraphQLInputObjectType( name='ContestInput', fields=lambda: { 'apiKey': GraphQLInputObjectField(GraphQLNonNull(GraphQLString)), 'title': GraphQLInputObjectField(GraphQLNonNull(GraphQLString)), 'description': GraphQLInputObjectField(GraphQLString) }) AddContestMutation = GraphQLField( ContestType, args={'input': GraphQLArgument(GraphQLNonNull(ContestInputType))}, resolver=lambda _, info, **kwargs: resolver_wrapper( pgdb.add_new_contest, info.context['pg_pool'], kwargs.get('input', {}) ))