Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested schemas with many=true do not generate a list of schemas in the swagger docs #86

Open
rogerfachini opened this issue Jul 16, 2020 · 6 comments

Comments

@rogerfachini
Copy link

Hi, thanks for taking the time to make this!

I found a corner case where the generated swagger docs / model do not match the Marshmallow schema provided. For nested fields, the parameter many=True seems to be ignored when creating the model. For example, this schema:

class WidgetSchema(Schema):
    bar = fields.String()

class GadgetSchema(Schema):
    foo = fields.String()
    widgets = fields.Nested(WidgetSchema, many=True)

appears in the generated swagger docs as:

{
  "foo": "string",
  "widgets": {
    "bar": "string"
  }
}

whereas the model should be:

{
  "widgets": [
    {
      "bar": "string"
    }
  ],
  "foo": "string"
}
Here's a minimal reproduction of the problem based on the example in the readme...

from dataclasses import dataclass
from marshmallow import Schema, fields, post_load
from flask import Flask
from flask_accepts import responds
from flask_restx import Api, Resource

@dataclass
class Widget:
    bar: str

@dataclass
class Gadget:
    foo: str
    widgets: list

class WidgetSchema(Schema):
    bar = fields.String()

class GadgetSchema(Schema):
    foo = fields.String()
    widgets = fields.Nested(WidgetSchema, many=True)

def create_app():
    app = Flask(__name__)
    api = Api(app)

    @api.route("/gadget")
    class GadgetResource(Resource):
        @responds(schema=GadgetSchema, api=api)
        def get(self):
            return Gadget(foo=None, widgets=[{'bar': None}, {'bar': None}])

    return app


if __name__ == "__main__":
    create_app().run()

@exit99
Copy link

exit99 commented Oct 7, 2020

Can confirm. We have this issue as well.

@Wormfriend
Copy link
Contributor

Hi, thank you for creating this neat library. I also have the same problem. Is there some kind of fix available by now? Enjoy your day!

@Wormfriend
Copy link
Contributor

Wormfriend commented Apr 28, 2021

I tried to overcome this by using fields.List but then the swagger documentation fails to build. I narrowed it down to

 'test': {
    'items': {
       'example': <marshmallow.missing>,
        'type': 'number'
    }

where marshmallow.utils._Missing seems to end up in the dict before the json.dumps. Any idea where this is coming from? Seems to be more of an flask-restx issue, doesn't it?

@Wormfriend
Copy link
Contributor

Wormfriend commented Apr 28, 2021

It seems kinda hacky but I could resolve the fields.List issue by adding a type-check for ma.utils._Missing within the _ma_field_to_fr_field function. Any ideas about this? Where is this coming from?

def _ma_field_to_fr_field(value: ma.Field) -> dict:
    fr_field_parameters = {}

    # add type-checking for ma.utils._Missing
    if hasattr(value, "default") and not isinstance(value.default, ma.utils._Missing): 
        fr_field_parameters["example"] = value.default

    if hasattr(value, "required"):
        fr_field_parameters["required"] = value.required

    if hasattr(value, "metadata") and "description" in value.metadata:
        fr_field_parameters["description"] = value.metadata["description"]

    if hasattr(value, "missing") and type(value.missing) != ma.utils._Missing:
        fr_field_parameters["default"] = value.missing

    return fr_field_parameters

I have the feeling this is somehow related to issue #103 .

@apryor6
Copy link
Owner

apryor6 commented May 4, 2021

Apologies for delays responding here. I would happily review/merge a PR (w/ tests). I unfortunately cannot commit to a reasonable timeframe for addressing this myself due to personal time conflicts.

@Wormfriend
Copy link
Contributor

Thank's for responding. I'll see what I can do. :)

Wormfriend added a commit to Wormfriend/flask_accepts that referenced this issue May 6, 2021
…x issue apryor6#86. Implemented test utils_test.test_unpack_nested_many as well.
apryor6 added a commit that referenced this issue Jun 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants