openapi-generator icon indicating copy to clipboard operation
openapi-generator copied to clipboard

[BUG][PYTHON] boolean ref6570 expansion

Open DarioHett opened this issue 3 years ago • 1 comments

Description

In the _ref6570_expansion booleans are consciously not covered, while they should be included as "true" or "false".

Unfortunately, I cannot share the spec of the api. The parameters of a GET request included { "name": "with_data", "type": "boolean", "description": "...", "in": "query", "required": false, "default": false },

Suggest a fix

Just had to patch two sections:

class ParameterSerializerBase:
    @classmethod
    def _get_default_explode(cls, style: ParameterStyle) -> bool:
        return False

    @staticmethod
    def __ref6570_item_value(in_data: typing.Any, percent_encode: bool):
        """
        Get representation if str/float/int/None/items in list/ values in dict
        None is returned if an item is undefined, use cases are value=
        - None
        - []
        - {}
        - [None, None None]
        - {'a': None, 'b': None}
        """
        if type(in_data) in {str, float, int}:
            if percent_encode:
                return quote(str(in_data))
            return str(in_data)
        elif isinstance(in_data, bool): # HERE
            return "true" if in_data else "false" # HERE
        elif isinstance(in_data, none_type):
            # ignored by the expansion process https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.1
            return None
        elif isinstance(in_data, list) and not in_data:
            # ignored by the expansion process https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.1
            return None
        elif isinstance(in_data, dict) and not in_data:
            # ignored by the expansion process https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.1
            return None
        raise ApiValueError(
            "Unable to generate a ref6570 item representation of {}".format(in_data)
        )

[...]

    @classmethod
    def _ref6570_expansion(
        cls,
        variable_name: str,
        in_data: typing.Any,
        explode: bool,
        percent_encode: bool,
        prefix_separator_iterator: PrefixSeparatorIterator,
    ) -> str:
        """
        Separator is for separate variables like dict with explode true, not for array item separation
        """
        named_parameter_expansion = prefix_separator_iterator.separator in {"&", ";"}
        var_name_piece = variable_name if named_parameter_expansion else ""
        if type(in_data) in {str, float, int, bool}: # add ", bool" here.
            return cls.__ref6570_str_float_int_expansion(
                variable_name,
                in_data,
                explode,
                percent_encode,
                prefix_separator_iterator,
                var_name_piece,
                named_parameter_expansion,
            )

DarioHett avatar Oct 13 '22 14:10 DarioHett

This is a duplicate ticket of https://github.com/OpenAPITools/openapi-generator/issues/1260 Please see my comment here https://github.com/OpenAPITools/openapi-generator/issues/1260#issuecomment-1249702545

There is no public internet standard which describes an agreed upon way to send boolean query parameters. RFC 6570 does not define how to send boolean query parameters. If you need this behavior, please submit a PR adding this feature by adding an additional property option for the generator like booleanInQueryParamBy="presence|value" where presence would add ?someVal and value would send ?someVal=true

spacether avatar Oct 18 '22 02:10 spacether

Shouldn't the boolean at least be specified in _ref6570_expansion? As right now I get the error in _ref6570_expansion:

Unable to generate a ref6570 representation of True

I don't care if it is send as true or True but I would not expect an exception in this case, and be allowed to pass a boolean value as a parameter.

ErnoW avatar Nov 18 '22 14:11 ErnoW

Thanks @DarioHett this patch works perfectly 🙌

ErnoW avatar Nov 18 '22 14:11 ErnoW