apispec icon indicating copy to clipboard operation
apispec copied to clipboard

Generating labels of validate.OneOf(labels=[..]) in the json schema

Open ddorian opened this issue 3 years ago • 3 comments

Hi,

I have the following field in marshmallow:

    the_field = fields.Integer(validate=[validate.OneOf([1, 2, 3], labels=['one', 'two', 'three'])])

And the resulting json:

"the_field": {
    "type": "integer",
    "enum": [
        1,
        2,
        3
    ]
}

Is there a way to also print the labels ['one', 'two', 'three'] in the json ?

ddorian avatar Jun 15 '21 12:06 ddorian

This is actually a bug I came here to report. We have enum values in the OneOf validator, with the correct label values for what is actually serialized. apispec tries to put these into the enum list and that breaks JSON serialisation.

The field2choices converter function should use the labels if available, instead of choices.

mjpieters avatar Jun 24 '21 15:06 mjpieters

Thanks for reporting. Anyone willing to propose a PR for this? Thanks.

lafrech avatar Jun 28 '21 07:06 lafrech

I haven’t yet made a PR because I am not 100% certain that using the labels is the canonical solution here.

the other option is to use the field to serialise the choices; after all, the OpenAPI spec needs serialised values, while the OneOf validator holds deserialised values.

Labels on the other hand are intended to serve as UI depictions of each value, which doesn’t necessarily mean that they are the exact same thing as the serialised version for each choice.

To illustrate: a TimeDelta field could be constrained with OneOf values for 1 hour, 1 day, 1 week, etc. with the values being timedelta() objects and the labels human-friendly text (1 hour from now, tomorrow, etc.) while the serialised format uses an integer representing the number of hours in the delta. Using the OneOf labels would result in the wrong OpenAPI representation.

So, if I’m creating a PR, I’d be leaning towards explicit conversion of the OneOf choices values.

mjpieters avatar Jun 28 '21 20:06 mjpieters