Skip to content

Swagger submitting incorrect format for Model-based form inputs #566

@brendan-morin

Description

@brendan-morin

Hi, this is a bit of an edge case I'm running into, but I hope it's solvable with some configuration. It is also possible this is a bug with swagger itself, or I'm just using things in an unintended way.

The Problem

The swagger configuration generated for my form endpoint does not submit list data in a valid way. All other usage works fine, everything passes tests, etc. It is only when trying to use swagger UI's "Try it out" does this fail.

The failure mode is that swagger submits lists of items like my_values=a,b, but should be submitting via the my_values=a&my_values=b, i.e. the way of explode=True, style='form' in OpenAPI 3.0+. As form data, my backend does not properly parse the comma-separated method.

Reproducing

Assume the following schema and endpoint:

from marshmallow import Schema, fields

# Schema
class MyFormData(Schema):
    my_values = fields.List(fields.String())

# API
blueprint = Blueprint(
    "forms", 
    "forms", 
    url_prefix="/forms"
)

@blueprint.route("/my-form")
class MyForm(MethodView):
    @blueprint.arguments(MyFormData, location="form")
    def post(self, data):
        """
        Submit form
        """
        print(data)
        pass

POST-ing to this endpoint via swagger with values and the form encoding like this:

Screenshot 2023-10-12 at 3 39 42 PM

yields a curl statement like this:

curl -X 'POST' \
  'http://localhost:8060/forms/my-form' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'my_values=a,b'

Which we can confirm by seeing the print output that this is not parsed into two values:

# in post handler
print(data)
> OrderedDict([('my_values', ['a,b'])])

The relevant bits of openapi.json looks something like:

  "paths": {
    "/forms/my-form": {
      "post": {
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/MyFormData"
              }
            }
          }
        },
        "tags": [
          "forms"
        ]
      }
    },
...
      "MyFormData": {
        "type": "object",
        "properties": {
          "my_values": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },

Related Work

This appears at least tangentially related to marshmallow-code/apispec#500 and the fix marshmallow-code/apispec#778. I wasn't able to parse out if there is anything in there that I can action on though.

Thanks for taking the time to read - any thoughts on a potential workaround for fix would be appreciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions