예제 #1
0
    def validate(self):
        """Validate that the FoldedContextField is correctly representable."""
        if not isinstance(self.fold_scope_location, FoldScopeLocation):
            raise TypeError(u'Expected FoldScopeLocation fold_scope_location, got: {} {}'.format(
                type(self.fold_scope_location), self.fold_scope_location))

        if self.fold_scope_location.field is None:
            raise ValueError(u'Expected FoldScopeLocation at a field, but got: {}'
                             .format(self.fold_scope_location))

        if self.fold_scope_location.field == COUNT_META_FIELD_NAME:
            if not GraphQLInt.is_same_type(self.field_type):
                raise TypeError(u'Expected the _x_count meta-field to be of GraphQLInt type, but '
                                u'encountered type {} instead: {}'
                                .format(self.field_type, self.fold_scope_location))
        else:
            if not isinstance(self.field_type, GraphQLList):
                raise ValueError(u'Invalid value of "field_type" for a field that is not '
                                 u'a meta-field, expected a list type but got: {} {}'
                                 .format(self.field_type, self.fold_scope_location))

            inner_type = strip_non_null_from_type(self.field_type.of_type)
            if isinstance(inner_type, GraphQLList):
                raise GraphQLCompilationError(
                    u'Outputting list-valued fields in a @fold context is currently not supported: '
                    u'{} {}'.format(self.fold_scope_location, self.field_type.of_type))
예제 #2
0
def _deserialize_anonymous_json_argument(expected_type, value):
    """Deserialize argument. See docstring of deserialize_json_argument.

    Args:
        expected_type: GraphQLType we expect. All GraphQLNonNull type wrappers are stripped.
        value: object that can be interpreted as being of that type

    Returns:
        a value of the type produced by the parser of the expected type:
            GraphQLDate: datetime.date
            GraphQLDateTime: datetime.datetime with tzinfo=pytz.utc
            GraphQLFloat: float
            GraphQLDecimal: decimal.Decimal
            GraphQLInt: six.integer_types, supporting long integers
            GraphQLString: six.string_types
            GraphQLBoolean: bool
            GraphQLID: six.string_types

    Raises:
        ValueError if the value is not appropriate for the type. ValueError is chosen because
        it is already the base case of exceptions raised by the GraphQL parsers.
    """
    allowed_types_for_graphql_type = {
        GraphQLDate.name: (six.string_types, ),
        GraphQLDateTime.name: (six.string_types, ),
        GraphQLFloat.name: (six.string_types, float, six.integer_types),
        GraphQLDecimal.name: (six.string_types, float, six.integer_types),
        GraphQLInt.name: (six.integer_types, six.string_types),
        GraphQLString.name: (six.string_types, ),
        GraphQLBoolean.name: (bool, ),
        GraphQLID.name: (
            six.integer_types,
            six.string_types,
        ),
    }

    # Check for long integers, bypassing the GraphQLInt parser
    if GraphQLInt.is_same_type(expected_type):
        if isinstance(value, six.integer_types):
            return value
        elif isinstance(value, six.string_types):
            return int(value)
        else:
            raise ValueError(u"Unexpected type {}. Expected one of {}.".format(
                type(value), (six.integer_types, six.string_types)))

    # Check if the type of the value is correct
    correct_type = True
    expected_python_types = allowed_types_for_graphql_type[expected_type.name]
    if isinstance(value,
                  bool) and not GraphQLBoolean.is_same_type(expected_type):
        correct_type = False  # We explicitly disallow passing boolean values for non-boolean types
    if not isinstance(value, expected_python_types):
        correct_type = False
    if not correct_type:
        raise ValueError(u"Unexpected type {}. Expected one of {}.".format(
            type(value), expected_python_types))

    # Use the default GraphQL parser to parse the value
    return expected_type.parse_value(value)
def _safe_match_argument(expected_type, argument_value):
    """Return a MATCH (SQL) string representing the given argument value."""
    if GraphQLString.is_same_type(expected_type):
        return _safe_match_string(argument_value)
    elif GraphQLID.is_same_type(expected_type):
        # IDs can be strings or numbers, but the GraphQL library coerces them to strings.
        # We will follow suit and treat them as strings.
        if not isinstance(argument_value, basestring):
            argument_value = unicode(argument_value)
        return _safe_match_string(argument_value)
    elif GraphQLFloat.is_same_type(expected_type):
        return represent_float_as_str(argument_value)
    elif GraphQLInt.is_same_type(expected_type):
        # Special case: in Python, isinstance(True, int) returns True.
        # Safeguard against this with an explicit check against bool type.
        if isinstance(argument_value, bool):
            raise GraphQLInvalidArgumentError(
                u'Attempting to represent a non-int as an int: '
                u'{}'.format(argument_value))
        return type_check_and_str(int, argument_value)
    elif GraphQLBoolean.is_same_type(expected_type):
        return type_check_and_str(bool, argument_value)
    elif GraphQLDate.is_same_type(expected_type):
        return _safe_match_date_and_datetime(expected_type, (datetime.date, ),
                                             argument_value)
    elif GraphQLDateTime.is_same_type(expected_type):
        return _safe_match_date_and_datetime(expected_type,
                                             (datetime.datetime, arrow.Arrow),
                                             argument_value)
    elif isinstance(expected_type, GraphQLList):
        return _safe_match_list(expected_type.of_type, argument_value)
    else:
        raise AssertionError(
            u'Could not safely represent the requested GraphQL type: '
            u'{} {}'.format(expected_type, argument_value))
예제 #4
0
    def validate(self):
        """Validate that the GremlinFoldedContextField is correctly representable."""
        if not isinstance(self.fold_scope_location, FoldScopeLocation):
            raise TypeError(
                u'Expected FoldScopeLocation fold_scope_location, got: {} {}'.
                format(type(self.fold_scope_location),
                       self.fold_scope_location))

        allowed_block_types = (GremlinFoldedFilter, GremlinFoldedTraverse,
                               Backtrack)
        for block in self.folded_ir_blocks:
            if not isinstance(block, allowed_block_types):
                raise AssertionError(
                    u'Found invalid block of type {} in folded_ir_blocks: {} '
                    u'Allowed types are {}.'.format(type(block),
                                                    self.folded_ir_blocks,
                                                    allowed_block_types))

        bare_field_type = strip_non_null_from_type(self.field_type)
        if isinstance(bare_field_type, GraphQLList):
            inner_type = strip_non_null_from_type(bare_field_type.of_type)
            if isinstance(inner_type, GraphQLList):
                raise GraphQLCompilationError(
                    u'Outputting list-valued fields in a @fold context is currently not supported: '
                    u'{} {}'.format(self.fold_scope_location,
                                    bare_field_type.of_type))
        elif GraphQLInt.is_same_type(bare_field_type):
            # This needs to be implemented for @fold _x_count support.
            raise NotImplementedError()
        else:
            raise ValueError(
                u'Invalid value of "field_type", expected a (possibly non-null) '
                u'list or int type but got: {}'.format(self.field_type))
def _safe_gremlin_argument(expected_type, argument_value):
    """Return a Gremlin string representing the given argument value."""
    if GraphQLString.is_same_type(expected_type):
        return _safe_gremlin_string(argument_value)
    elif GraphQLID.is_same_type(expected_type):
        # IDs can be strings or numbers, but the GraphQL library coerces them to strings.
        # We will follow suit and treat them as strings.
        if not isinstance(argument_value, six.string_types):
            if isinstance(argument_value,
                          bytes):  # likely to only happen in py2
                argument_value = argument_value.decode("utf-8")
            else:
                argument_value = six.text_type(argument_value)
        return _safe_gremlin_string(argument_value)
    elif GraphQLFloat.is_same_type(expected_type):
        return represent_float_as_str(argument_value)
    elif GraphQLInt.is_same_type(expected_type):
        # Special case: in Python, isinstance(True, int) returns True.
        # Safeguard against this with an explicit check against bool type.
        if isinstance(argument_value, bool):
            raise GraphQLInvalidArgumentError(
                u"Attempting to represent a non-int as an int: "
                u"{}".format(argument_value))

        return type_check_and_str(int, argument_value)
    elif GraphQLBoolean.is_same_type(expected_type):
        return type_check_and_str(bool, argument_value)
    elif GraphQLDecimal.is_same_type(expected_type):
        return _safe_gremlin_decimal(argument_value)
    elif GraphQLDate.is_same_type(expected_type):
        return _safe_gremlin_date_and_datetime(expected_type,
                                               (datetime.date, ),
                                               argument_value)
    elif GraphQLDateTime.is_same_type(expected_type):
        return _safe_gremlin_date_and_datetime(
            expected_type, (datetime.datetime, arrow.Arrow), argument_value)
    elif isinstance(expected_type, GraphQLList):
        return _safe_gremlin_list(expected_type.of_type, argument_value)
    else:
        raise AssertionError(
            u"Could not safely represent the requested GraphQL type: "
            u"{} {}".format(expected_type, argument_value))
예제 #6
0
def _safe_gremlin_argument(expected_type, argument_value):
    """Return a Gremlin string representing the given argument value."""
    if GraphQLString.is_same_type(expected_type):
        return _safe_gremlin_string(argument_value)
    elif GraphQLID.is_same_type(expected_type):
        # IDs can be strings or numbers, but the GraphQL library coerces them to strings.
        # We will follow suit and treat them as strings.
        if not isinstance(argument_value, six.string_types):
            if isinstance(argument_value, bytes):  # should only happen in py3
                argument_value = argument_value.decode('utf-8')
            else:
                argument_value = six.text_type(argument_value)
        return _safe_gremlin_string(argument_value)
    elif GraphQLFloat.is_same_type(expected_type):
        return represent_float_as_str(argument_value)
    elif GraphQLInt.is_same_type(expected_type):
        # Special case: in Python, isinstance(True, int) returns True.
        # Safeguard against this with an explicit check against bool type.
        if isinstance(argument_value, bool):
            raise GraphQLInvalidArgumentError(u'Attempting to represent a non-int as an int: '
                                              u'{}'.format(argument_value))

        return type_check_and_str(int, argument_value)
    elif GraphQLBoolean.is_same_type(expected_type):
        return type_check_and_str(bool, argument_value)
    elif GraphQLDecimal.is_same_type(expected_type):
        return _safe_gremlin_decimal(argument_value)
    elif GraphQLDate.is_same_type(expected_type):
        return _safe_gremlin_date_and_datetime(expected_type, (datetime.date,), argument_value)
    elif GraphQLDateTime.is_same_type(expected_type):
        return _safe_gremlin_date_and_datetime(expected_type,
                                               (datetime.datetime, arrow.Arrow), argument_value)
    elif isinstance(expected_type, GraphQLList):
        return _safe_gremlin_list(expected_type.of_type, argument_value)
    else:
        raise AssertionError(u'Could not safely represent the requested GraphQL type: '
                             u'{} {}'.format(expected_type, argument_value))
예제 #7
0
def validate_argument_type(name, expected_type, value):
    """Ensure the value has the expected type and is usable in any of our backends, or raise errors.

    Backends are the database languages we have the ability to compile to, like OrientDB MATCH,
    Gremlin, or SQLAlchemy. This function should be stricter than the validation done by any
    specific backend. That way code that passes validation can be compiled to any backend.

    Args:
        name: string, the name of the argument. It will be used to provide a more descriptive error
              message if an error is raised.
        expected_type: GraphQLType we expect. All GraphQLNonNull type wrappers are stripped.
        value: object that can be interpreted as being of that type
    """
    stripped_type = strip_non_null_from_type(expected_type)
    if GraphQLString.is_same_type(stripped_type):
        if not isinstance(value, six.string_types):
            _raise_invalid_type_error(name, "string", value)
    elif GraphQLID.is_same_type(stripped_type):
        # IDs can be strings or numbers, but the GraphQL library coerces them to strings.
        # We will follow suit and treat them as strings.
        if not isinstance(value, six.string_types):
            _raise_invalid_type_error(name, "string", value)
    elif GraphQLFloat.is_same_type(stripped_type):
        if not isinstance(value, float):
            _raise_invalid_type_error(name, "float", value)
    elif GraphQLInt.is_same_type(stripped_type):
        # Special case: in Python, isinstance(True, int) returns True.
        # Safeguard against this with an explicit check against bool type.
        if isinstance(value, bool) or not isinstance(value, six.integer_types):
            _raise_invalid_type_error(name, "int", value)
    elif GraphQLBoolean.is_same_type(stripped_type):
        if not isinstance(value, bool):
            _raise_invalid_type_error(name, "bool", value)
    elif GraphQLDecimal.is_same_type(stripped_type):
        # Types we support are int, float, and Decimal, but not bool.
        # isinstance(True, int) returns True, so we explicitly forbid bool.
        if isinstance(value, bool):
            _raise_invalid_type_error(name, "decimal", value)
        if not isinstance(value, decimal.Decimal):
            try:
                decimal.Decimal(value)
            except decimal.InvalidOperation as e:
                raise GraphQLInvalidArgumentError(e)
    elif GraphQLDate.is_same_type(stripped_type):
        # Datetimes pass as instances of date. We want to explicitly only allow dates.
        if isinstance(
                value,
                datetime.datetime) or not isinstance(value, datetime.date):
            _raise_invalid_type_error(name, "date", value)
        try:
            stripped_type.serialize(value)
        except ValueError as e:
            raise GraphQLInvalidArgumentError(e)
    elif GraphQLDateTime.is_same_type(stripped_type):
        if not isinstance(value, (datetime.date, arrow.Arrow)):
            _raise_invalid_type_error(name, "datetime", value)
        try:
            stripped_type.serialize(value)
        except ValueError as e:
            raise GraphQLInvalidArgumentError(e)
    elif isinstance(stripped_type, GraphQLList):
        if not isinstance(value, list):
            _raise_invalid_type_error(name, "list", value)
        inner_type = strip_non_null_from_type(stripped_type.of_type)
        for element in value:
            validate_argument_type(name, inner_type, element)
    else:
        raise AssertionError(
            u"Could not safely represent the requested GraphQLType: "
            u"{} {}".format(stripped_type, value))
예제 #8
0
def is_int_field_type(schema_info, vertex_name, field_name):
    """Return whether the field is of type GraphQLInt."""
    field_type = schema_info.schema.get_type(
        vertex_name).fields[field_name].type
    return GraphQLInt.is_same_type(field_type)