apispec icon indicating copy to clipboard operation
apispec copied to clipboard

Add support for Marshmallow Tuple field

Open mcs07 opened this issue 6 years ago • 6 comments

marshmallow 3.0.0rc4 adds a Tuple field. It would be nice if the apispec marshmallow plugin could support this.

mcs07 avatar Feb 28 '19 10:02 mcs07

Yes! Absolutely. Would you like to submit the change?

lafrech avatar Feb 28 '19 10:02 lafrech

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
}

mcs07 avatar Feb 28 '19 11:02 mcs07

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.

lafrech avatar Feb 28 '19 11:02 lafrech

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 of anyOf
  • swagger editor complains about an additional property for either oneOf or anyOf 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

Bangertm avatar Feb 28 '19 15:02 Bangertm

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.

lafrech avatar Sep 01 '22 09:09 lafrech

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?

lukaskoeller avatar Feb 21 '24 13:02 lukaskoeller