def add_scalar_type(scalar): result[scalar.t] = GraphQLScalarType( name=scalar.__name__, description=scalar.__doc__, serialize=scalar.serialize, parse_value=lambda val: scalar.parse(val), parse_literal=lambda node: scalar.parse(ast_to_value(node)))
def _make_scalar_type(definition: ScalarDefinition) -> GraphQLScalarType: return GraphQLScalarType( name=definition.name, description=definition.description, serialize=definition.serialize, parse_value=definition.parse_value, parse_literal=definition.parse_literal, )
def map_custom_scalar(self, name: str, supertype: GraphQLScalarType) -> GraphQLScalarType: return GraphQLScalarType( name=name, serialize=supertype.serialize, parse_literal=supertype.parse_literal, parse_value=supertype.parse_value, )
def graphql_type(cls): return GraphQLScalarType( name=cls.__name__, description=cls.__doc__, serialize=cls.serialize, parse_value=cls.parse_value, parse_literal=cls.parse_literal, )
def test_deleted_doc_resolution(self): d = frappe.get_doc( dict(doctype="User", first_name="Example A", email="*****@*****.**", send_welcome_email=0, roles=[{ "role": "System Manager" }])).insert() d.delete() # We cannot call Query.User(name: d.name) now since its deleted schema = get_schema() schema.type_map["UserDocInput"] = GraphQLScalarType( name="UserDocInput") schema.query_type.fields["EchoUser"] = GraphQLField( type_=schema.type_map["User"], args=dict(user=GraphQLArgument( type_=schema.type_map["UserDocInput"])), resolve=lambda obj, info, **kwargs: kwargs.get("user")) r = execute(query=""" query EchoUser($user: UserDocInput!) { EchoUser(user: $user) { doctype name email full_name roles { role__name } } } """, variables={"user": d}) resolved_doc = frappe._dict(r.get("data").get("EchoUser")) self.assertEqual(resolved_doc.doctype, d.doctype) self.assertEqual(resolved_doc.name, d.name) self.assertEqual(resolved_doc.email, d.email) self.assertEqual(resolved_doc.full_name, d.full_name) self.assertEqual(len(resolved_doc.roles), 1) self.assertEqual(resolved_doc.roles[0].get("role__name"), "System Manager")
def _extend_query_type(self): @type(name="_Service") class Service: sdl: str Any = GraphQLScalarType("_Any") fields = { "_service": GraphQLField( GraphQLNonNull(Service.graphql_type), resolve=lambda _, info: Service(sdl=print_schema(info.schema)), ) } entities_type = self._get_entity_type() if entities_type: self.type_map[entities_type.name] = entities_type fields["_entities"] = GraphQLField( GraphQLNonNull(GraphQLList(entities_type)), args={ "representations": GraphQLNonNull(GraphQLList(GraphQLNonNull(Any))) }, resolve=entities_resolver, ) fields.update(self.query_type.fields) self.query_type = GraphQLObjectType( name=self.query_type.name, description=self.query_type.description, fields=fields, ) self.type_map["_Any"] = Any self.type_map["_Service"] = Service.graphql_type self.type_map[self.query_type.name] = self.query_type
else: raise ValueError( f"Expected a timezone-naive datetime or an ISO-8601 string representation parseable " f"by the ciso8601 library. Got {value} of type {type(value)} instead." ) GraphQLDate = GraphQLScalarType( name="Date", description=( "The `Date` scalar type represents day-accuracy date objects." "Values are serialized following the ISO-8601 datetime format specification, " 'for example "2017-03-21". Serialization and parsing support is guaranteed for the format ' "described here, with the year, month and day fields included and separated by dashes as " "in the example. Implementations are allowed to support additional serialization formats, " "if they so choose." # GraphQL compiler's implementation of GraphQL-based querying uses the ciso8601 library # for date and datetime parsing, so it additionally supports the subset of the ISO-8601 # standard supported by that library. ), serialize=_serialize_date, parse_value=_parse_date_value, parse_literal= _unused_function, # We don't yet support parsing Date objects in literals. ) GraphQLDateTime = GraphQLScalarType( name="DateTime", description=( "The `DateTime` scalar type represents timezone-naive timestamps with up to microsecond " "accuracy. Values are serialized following the ISO-8601 datetime format specification, " 'for example "2017-03-21T12:34:56.012345" or "2017-03-21T12:34:56". Serialization and '
'DateTime cannot represent non-datetime/date/Arrow/str type') dt = arrow.get(value).astimezone(timezone.utc) return dt.isoformat() def parse_value(value: str) -> datetime: if not isinstance(value, str): raise TypeError('DateTime cannot be represented by non-str type') dt = arrow.get(value) # A datetime string without timezone is not allowed! # A datetime string must be separated by 'T'. # A timezone mark is one of ['+', '-', 'Z']. if (sep_index := value.find('T')) != -1 and not { '+', '-', 'Z' }.intersection(value[sep_index:]): raise ValueError( 'DateTime cannot be represented by a no-timezone format') return dt.astimezone(timezone.utc) GraphQLDateTime = GraphQLScalarType( name='DateTime', description=( 'A date-time string at UTC, such as 2007-12-03T10:15:30Z, ' + 'compliant with the `date-time` format outlined in section 5.6 of ' + 'the RFC 3339 profile of the ISO 8601 standard for representation ' + 'of dates and times using the Gregorian calendar.'), serialize=serialize, parse_value=parse_value, )
elif isinstance(value, datetime): return value.date() elif isinstance(value, int): return date.utcfromtimestamp(value) else: return datetime.strptime(str(value), '%Y-%m-%d').date() def serialize_date(value): return datetime.strptime(value, '%Y-%m-%d').strftime('%Y-%m-%d') def parse_date_literal(ast): return datetime.strptime(ast.value, '%Y-%m-%d') SpotDateType = GraphQLScalarType( name='SpotDateType', description='The `Date` scalar type represents date values in the format yyyy-mm-dd.', serialize=serialize_date, parse_value=coerce_date, parse_literal=parse_date_literal) def coerce_datetime(value): if isinstance(value, int): value = datetime.utcfromtimestamp(value) elif not isinstance(value, datetime): value = datetime.strptime(str(value), '%Y-%m-%d %H:%M:%S') return value def serialize_datetime(value): if not isinstance(value, datetime): value = datetime.strptime(str(value), '%Y-%m-%d %H:%M:%S')
from .schema.subscription.run_cmd import subscribe_run_cmd, subscribe_run_service_cmd from .schema.subscription.get_logs import subscribe_get_logs from .schema.query.worker import resolve_list_workers from .schema.query.stack import resolve_all_stacks, resolve_one_stack from .schema.query.template import resolve_get_template, all_templates_resolver from .schema.mutation.worker import resolve_force_worker from .schema.mutation.stack import resolve_delete_stack, resolve_create_stack async def resolve_meta(tpl, info): return (await tpl.get_other()).get('meta', {}) TemplateVarsType = GraphQLScalarType(name="template_vars", serialize=lambda x: x) TemplateType = GraphQLObjectType( name="template", fields={ "name": GraphQLField(GraphQLString, resolve=lambda x, y: x.path.name), "vars": GraphQLField(TemplateVarsType, resolve=lambda x, y: x.get_vars(y.context['app'])), "meta": GraphQLField(TemplateVarsType, resolve=resolve_meta), }) schema = GraphQLSchema( query=GraphQLObjectType(
from graphql import GraphQLScalarType def anyvalue_parse_literal(node): # TODO: pass through parsed object if JSON? raise NotImplementedError() AnyValue = GraphQLScalarType( name='AnyValue', description='JSON data with no fixed schema', serialize=lambda x: x, parse_literal=anyvalue_parse_literal, parse_value=lambda x: x)
if isinstance(node, ast.StringValueNode): return datetime_parse_value(node.value) def datetime_parse_value(value): try: return aniso8601.parse_datetime(value) except ValueError: return None GraphQLDateTime = GraphQLScalarType( name="DateTime", description="The `DateTime` scalar type represents a DateTime" "value as specified by" "[iso8601](https://en.wikipedia.org/wiki/ISO_8601).", serialize=datetime_serialize, parse_literal=datetime_parse_literal, parse_value=datetime_parse_value, ) def date_serialize(date): if isinstance(date, datetime.datetime): date = date.date() assert isinstance( date, datetime.date), 'Received not compatible date "{}"'.format(repr(date)) return date.isoformat()
def _parse_datetime_value(value): """Deserialize a DateTime object from its proper ISO-8601 representation.""" # attempt to parse with microsecond information try: return arrow.get(value, "YYYY-MM-DDTHH:mm:ss.SZZ").datetime except arrow.parser.ParserMatchError: return arrow.get(value, "YYYY-MM-DDTHH:mm:ssZZ").datetime GraphQLDate = GraphQLScalarType( name="Date", description= ("The `Date` scalar type represents day-accuracy date objects." "Values are serialized following the ISO-8601 datetime format specification, " 'for example "2017-03-21". The year, month and day fields must be included, ' "and the format followed exactly, or the behavior is undefined."), serialize=_serialize_date, parse_value=_parse_date_value, parse_literal= _unused_function, # We don't yet support parsing Date objects in literals. ) GraphQLDateTime = GraphQLScalarType( name="DateTime", description= ("The `DateTime` scalar type represents timezone-aware second-accuracy timestamps." "Values are serialized following the ISO-8601 datetime format specification, " 'for example "2017-03-21T12:34:56+00:00". All of these fields must be included, ' "including the seconds and the time zone, and the format followed exactly, " "or the behavior is undefined."), serialize=_serialize_datetime,
elif node.kind == StringValueNode.kind: node = cast(StringValueNode, node) return node.value elif node.kind == BooleanValueNode.kind: node = cast(BooleanValueNode, node) return node.value elif node.kind == NullValueNode.kind: return None elif node.kind == VariableNode.kind: node = cast(VariableNode, node) return variables[node.name.value] if variables is not None else None elif node.kind == ListValueNode.kind: node = cast(ListValueNode, node) return [parse_literal(item, variables) for item in node.values] elif node.kind == ObjectValueNode.kind: node = cast(ObjectValueNode, node) return { field.name.value: parse_literal(field.value, variables) for field in node.fields } GraphQLJSON = GraphQLScalarType( name='JSON', description= 'The `JSON` scalar type represents JSON values as specified by ECMA-404.', serialize=serialize, parse_value=parse_value, parse_literal=parse_literal, )
def __init__(self): super(ParamSchema, self).__init__(self) self.parameter_data = {} self.parameter_meta = {} # the trick with parameters is that they are either floats or ints # a custom type is required... GraphQLParamValue = GraphQLScalarType( name="ParamValue", description="", serialize=serialize_param_value, parse_value=coerce_param_value, parse_literal=parse_param_value_literal, ) self.parameter_meta_input = GraphQLInputObjectType( "MetaInput", lambda: { "humanName": GraphQLInputField(GraphQLString), "humanGroup": GraphQLInputField(GraphQLString), "documentation": GraphQLInputField(GraphQLString), "group": GraphQLInputField(GraphQLString), "increment": GraphQLInputField(GraphQLParamValue), "min": GraphQLInputField(GraphQLParamValue), "max": GraphQLInputField(GraphQLParamValue), "decimal": GraphQLInputField(GraphQLParamValue), "rebootRequired": GraphQLInputField(GraphQLBoolean), "unitText": GraphQLInputField(GraphQLString), "units": GraphQLInputField(GraphQLString), "bitmask": GraphQLInputField(GraphQLString), "values": GraphQLInputField(GraphQLString), "type": GraphQLInputField(GraphQLString), }, ) self.parameter_meta_type = GraphQLObjectType( "Meta", lambda: { "humanName": GraphQLField(GraphQLString, description=""), "humanGroup": GraphQLField(GraphQLString, description=""), "documentation": GraphQLField(GraphQLString, description=""), "group": GraphQLField(GraphQLString, description=""), "increment": GraphQLField(GraphQLParamValue, description=""), "min": GraphQLField(GraphQLParamValue, description=""), "max": GraphQLField(GraphQLParamValue, description=""), "decimal": GraphQLField(GraphQLParamValue, description=""), "rebootRequired": GraphQLField(GraphQLBoolean, description=""), "unitText": GraphQLField(GraphQLString, description=""), "units": GraphQLField(GraphQLString, description=""), "bitmask": GraphQLField(GraphQLString, description=""), "values": GraphQLField(GraphQLString, description=""), "type": GraphQLField(GraphQLString, description=""), }, ) self.parameter_type = GraphQLObjectType( "Parameter", lambda: { "id": GraphQLField(GraphQLString, description="The id of the parameter"), "value": GraphQLField(GraphQLParamValue, description="The value of the parameter"), "meta": GraphQLField(self.parameter_meta_type), }, description="Parameter item", ) self.parameter_list_type = GraphQLObjectType( "ParameterList", lambda: {"parameters": GraphQLField(GraphQLList(self.parameter_type))}, ) self.parameter_input_type = GraphQLInputObjectType( "ParameterInput", { "id": GraphQLInputField(GraphQLNonNull(GraphQLString)), "value": GraphQLInputField(GraphQLNonNull(GraphQLParamValue)), }, ) self.q = { "Parameter": GraphQLField( self.parameter_type, args={ "id": GraphQLArgument( GraphQLNonNull(GraphQLString), description="The id of the desired parameter.", ) }, resolve=self.get_parameter, ), "ParameterList": GraphQLField( self.parameter_list_type, args={ "query": GraphQLArgument( GraphQLNonNull(GraphQLString), description= "The query used to match desired parameters. * can be used as a wildcard.", ) }, resolve=self.get_parameter_list, ), } self.m = { "Parameter": GraphQLField( self.parameter_type, args={ "id": GraphQLArgument(GraphQLNonNull(GraphQLString)), "value": GraphQLArgument(GraphQLNonNull(GraphQLParamValue)), "meta": GraphQLArgument(self.parameter_meta_input), }, resolve=self.update_parameter, ), "ParameterList": GraphQLField( self.parameter_list_type, args={ "parameters": GraphQLArgument( GraphQLNonNull(GraphQLList(self.parameter_input_type))) }, resolve=self.update_parameter_list, ), } self.s = { "Parameter": GraphQLField(self.parameter_type, subscribe=self.sub_parameter, resolve=None) }
def _mssql_xml_path_string_to_list( xml_path_result: str, list_entry_type: GraphQLScalarType) -> List[Any]: """Convert the string result produced with XML PATH for MSSQL folds to a list. Args: xml_path_result: str, result from an XML PATH folded output list_entry_type: GraphQLScalarType, type the results should be output as Returns: list representation of the result with all XML and GraphQL Compiler escaping reversed """ # Return an empty list if the XML PATH result is "". if xml_path_result == "": return [] # Some of the special characters involved in XML path array aggregation. delimiter = "|" null = "~" # Remove the "|" from the first result in the string representation of the list. if xml_path_result[0] != delimiter: raise AssertionError( f"Unexpected fold result. All XML path array aggregated lists must start with a " f"'{delimiter}'. Received a result beginning with '{xml_path_result[0]}': " f"{xml_path_result}") xml_path_result = xml_path_result[1:] # Split the XML path result on "|". list_result: Sequence[Optional[str]] = xml_path_result.split(delimiter) # Convert "~" to None. Note that this must be done before "^n" -> "~". list_result = [ None if result == null else result for result in list_result ] # Convert "^d" to "|". list_result = [ result.replace("^d", delimiter) if result is not None else None for result in list_result ] # Convert "^n" to "~". list_result = [ result.replace("^n", null) if result is not None else None for result in list_result ] # Convert "^e" to "^". Note that this must be done after the caret escaped characters i.e. # after "^n" -> "~" and "^d" -> "|". list_result = [ result.replace("^e", "^") if result is not None else None for result in list_result ] # Convert "&#x{2 digit HEX};" to unicode character. new_list_result: List[Optional[str]] = [] for result in list_result: if result is not None: split_result = re.split("&#x([A-Fa-f0-9][A-Fa-f0-9]);", result) new_result = split_result[0] for hex_value, next_substring in zip(split_result[1::2], split_result[2::2]): new_result += chr(int(hex_value, 16)) + next_substring new_list_result.append(new_result) else: new_list_result.append(None) # Convert "&" to "&", ">" to ">", "<" to "<". Note that the ampersand conversion # must be done after the ampersand escaped HEX values. list_result = [ html.unescape(result) if result is not None else None for result in new_list_result ] # Convert to the appropriate return type. list_result_to_return: List[Optional[Any]] = [ list_entry_type.parse_value(result) if result is not None else None for result in list_result ] return list_result_to_return
def create_type(): return GraphQLScalarType(name='Date', description='ISO-8601 Date', serialize=serialize_date, parse_value=coerce_date, parse_literal=parse_date_literal)
from typing import Any, Optional from uuid import UUID from graphql.language.ast import StringValue, Value from graphql import GraphQLScalarType def serialize_uuid(uuid: UUID) -> str: return str(uuid) def coerce_uuid(value: Any) -> Optional[UUID]: if isinstance(value, UUID): return value if isinstance(value, str): return UUID(hex=value) return None def parse_uuid_literal(ast: Value) -> Optional[UUID]: if isinstance(ast, StringValue): return UUID(hex=ast.value) return None GraphQLUUID = GraphQLScalarType( name='UUID', description='UUID', serialize=serialize_uuid, parse_value=coerce_uuid, parse_literal=parse_uuid_literal, )
def typed_parse_date(value: Any) -> datetime.datetime: return cast(datetime.datetime, iso8601.parse_date(value)) def serialize_date(value: datetime.datetime) -> str: return value.isoformat() def coerce_date(value: Any) -> Optional[datetime.datetime]: if isinstance(value, datetime.datetime): return value if isinstance(value, datetime.date): return datetime.datetime(value.year, value.month, value.day) if isinstance(value, str): return typed_parse_date(value) # let's see what we can do return None # should I throw? def parse_date_literal(ast: Value) -> Optional[datetime.datetime]: if isinstance(ast, StringValue): return typed_parse_date(ast.value) return None GraphQLDate = GraphQLScalarType( name='Date', description='ISO-8601 Date', serialize=serialize_date, parse_value=coerce_date, parse_literal=parse_date_literal, )
def _parse_datetime_value(value): """Deserialize a DateTime object from its proper ISO-8601 representation.""" if value.endswith('Z'): # Arrow doesn't support the "Z" literal to denote UTC time. # Strip the "Z" and add an explicit time zone instead. value = value[:-1] + '+00:00' return arrow.get(value, 'YYYY-MM-DDTHH:mm:ssZ').datetime GraphQLDate = GraphQLScalarType( name='Date', description='The `Date` scalar type represents day-accuracy date objects.' 'Values are serialized following the ISO-8601 datetime format specification, ' 'for example "2017-03-21". The year, month and day fields must be included, ' 'and the format followed exactly, or the behavior is undefined.', serialize=_serialize_date, parse_value=_parse_date_value, parse_literal=_unused_function, # We don't yet support parsing Date objects in literals. ) GraphQLDateTime = GraphQLScalarType( name='DateTime', description='The `DateTime` scalar type represents timezone-aware second-accuracy timestamps.' 'Values are serialized following the ISO-8601 datetime format specification, ' 'for example "2017-03-21T12:34:56+00:00". All of these fields must be included, ' 'including the seconds and the time zone, and the format followed exactly, ' 'or the behavior is undefined.', serialize=_serialize_datetime, parse_value=_parse_datetime_value,
def serialize_json(value: Any) -> Dict[str, Any]: return value def parse_json_value(value: Any) -> Any: return value def parse_json_literal(value_node: ValueNode, variables: Optional[Dict[str, Any]] = None) -> Any: return value_from_ast_untyped(value_node, variables) JsonScalar = GraphQLScalarType( name="JSON", serialize=serialize_json, parse_value=parse_json_value, parse_literal=parse_json_literal, ) root_value = { "players": [ { "name": "John", "level": 3, "is_connected": True, "score": 123.45, "friends": ["Alex", "Alicia"], }, { "name": "Alex", "level": 4,
from graphql import GraphQLObjectType, GraphQLField, GraphQLString, GraphQLInt, GraphQLList, GraphQLScalarType, \ GraphQLNonNull, GraphQLInputObjectType, GraphQLInputField from .query.service import ServiceType, resolve_services PortsType = GraphQLObjectType(name="Ports", fields={ "internal": GraphQLField(GraphQLString, resolve=lambda x, i: x[1]), "external": GraphQLField(GraphQLString, resolve=lambda x, i: x[0]) }) VarsType = GraphQLScalarType(name="Vars", serialize=lambda x: x) VarInputType = GraphQLInputObjectType(name="StackVar", fields={ "name": GraphQLInputField( GraphQLNonNull(GraphQLString)), "value": GraphQLInputField(GraphQLString), })
"""Utils This module defines the framework-agnostic logic for handling the multipart request spec """ from graphql import GraphQLScalarType import typing as t GraphQLFile = GraphQLScalarType( name="File", description="The `File` scalar type represents" " a file input as specified by" " https://github.com/jaydenseric" "/graphql-multipart-request-spec" "and as implemented in " "https://github.com/lmcgartland/" "graphene-file-upload/blob/master/" "graphene_file_upload/utils.py", serialize=lambda x: x, parse_value=lambda x: x, parse_literal=lambda x, _: x, ) def place_files_in_operations( operations: t.Any, files_map: t.Any, files: t.Any ) -> t.Any: """Replaces None placeholders in operations with file objects in the files dictionary, by following the files_map logic as specified within the 'map' request parameter in the multipart request spec""" path_to_key_iter = (
__all__ = ['serialize', 'parse_value', 'parse_literal', 'GraphQLVoid'] from graphql import GraphQLScalarType def serialize(*_) -> None: return None def parse_value(*_) -> None: return None def parse_literal(*_) -> None: return None GraphQLVoid = GraphQLScalarType( name='Void', description='A Representation of NULL values', serialize=serialize, parse_value=parse_value, parse_literal=parse_literal, )
from graphql import GraphQLString, GraphQLNonNull, GraphQLList, GraphQLObjectType, GraphQLField, GraphQLInt, GraphQLScalarType from .service import ServiceType from ..query.service import resolve_services ExtraValuesType = GraphQLScalarType(name="MetaData", serialize=lambda x: x) StackType = GraphQLObjectType( name="stack", fields={ "id": GraphQLField(GraphQLInt), "name": GraphQLField(GraphQLNonNull(GraphQLString)), "from_template": GraphQLField(GraphQLNonNull(GraphQLString)), "services": GraphQLField(GraphQLList(ServiceType, ), resolve=resolve_services), "meta": GraphQLField(ExtraValuesType, resolve=lambda stack, info: stack.meta), "links": GraphQLField(ExtraValuesType, resolve=lambda stack, info: stack.links) })
def _add_scalars(self): self.Any = GraphQLScalarType("_Any") self._schema.type_map["_Any"] = self.Any
def serialize(value: Union[datetime, date, Arrow, str]) -> int: if not isinstance(value, (datetime, date, Arrow, str)): raise TypeError( 'Timestamp cannot represent non-datetime/date/Arrow/str type') dt = arrow.get(value) return int(dt.timestamp() * 1000) def parse_value(value: Union[int, float]) -> datetime: # for historic reason, bool is a subclass of int, # so isinstance(True, int) is always True if type(value) in [int, float]: # the fact that arrow.get() can receive both seconds timestamp and ms/us timestamp # is not desired by us, so here uses datetime.fromtimestamp() dt = datetime.fromtimestamp(value / 1000, timezone.utc) return dt else: raise TypeError( 'Timestamp cannot be represented by non-int/float type') GraphQLTimestamp = GraphQLScalarType( name='Timestamp', description= 'A Epoch Unix timestamp integer in milliseconds, such as 1621998739087', serialize=serialize, parse_value=parse_value, )