apispec
apispec copied to clipboard
Add support for Marshmallow Tuple field
marshmallow 3.0.0rc4 adds a Tuple field. It would be nice if the apispec marshmallow plugin could support this.
Yes! Absolutely. Would you like to submit the change?
This might be a bit trickier than I first thought....
I presume the first thing to do is to add to DEFAULT_FIELD_MAPPING
:
marshmallow.fields.Tuple: ("array", None),
But from reading the OpenAPI spec it doesn't seem to be possible to specify the types of the contained items individually. So I think the best we could do is to use anyOf
then list the types? And also constrain the length?
{
"type": "array",
"items": {
"anyOf": [
{"type": "float"},
{"type": "string"}
]
},
"minItems": 2,
"maxItems": 2
}
Since it may contain nested fields, it probably deserves a special treatment in there like List
and Dict
: https://github.com/marshmallow-code/apispec/blob/dev/apispec/ext/marshmallow/openapi.py#L420.
There's been discussions in https://github.com/marshmallow-code/apispec/issues/172 about making this easier to extend, but for now, we can just add a case.
How about adding an extension to indicate the order to the user. Maybe something like:
{
"type": "array",
"items": {
"oneOf": [
{"type": "number"},
{"type": "string"}
]
},
"minItems": 2,
"maxItems": 2,
"x-order": [
{"type": "number"},
{"type": "string"}
],
}
If there is enough of a use case we could look look to add something to the standard, but using an extension short term can help validate the use case.
A couple other things I noted in playing around:
- the spec on arrays calls out using
oneOf
instead ofanyOf
- swagger editor complains about an additional property for either
oneOf
oranyOf
in a 2.0 spec so we may need to only add that that for 3.x specs - interestingly if I put a definition with number, string, number in the oneOf field swagger editor displays an appropriate example
Info about representing tuple in OpenAPI:
- https://json-schema.org/understanding-json-schema/reference/array.html#tuple-validation
- https://stackoverflow.com/questions/57464633/how-to-define-a-json-array-with-concrete-item-definition-for-every-index-i-e-a
I'd like a solution here that doesn't try to handle older OpenAPI versions.
I couldn't really follow: Is there now a way to get fields.Tuple()
correctly translated to a tuple in the openapi spec?
I set openapi_version="3.1.0"
in the APISpec
from apispec
accordingly but couldn't see any improvement in the generated json.
Can anyone enlighten me?