Coder Social home page Coder Social logo

Comments (11)

apryor6 avatar apryor6 commented on June 11, 2024

On the latest (0.14.2) version I observe that the Swagger documentation does not correctly capture many=True, but the validation does work. Can you confirm this is what you experience?

Here is the script I used:

from dataclasses import dataclass
from marshmallow import fields, Schema, post_load
from flask import Flask, jsonify, request
from flask_accepts import accepts, responds


@dataclass
class Widget:
    foo: str
    baz: int


class WidgetSchema(Schema):
    foo = fields.String(default="test value")
    baz = fields.Integer(default=422)

    @post_load
    def make(self, data, **kwargs):
        return Widget(**data)


def create_app(env=None):
    from flask_restplus import Api, Namespace, Resource

    app = Flask(__name__)
    api = Api(app)

    @api.route("/restplus/make_a_widget")
    class WidgetResource(Resource):
        @accepts(
            dict(name="some_arg", type=str), schema=WidgetSchema(many=True), api=api
        )
        @responds(schema=WidgetSchema(many=True), api=api)
        def post(self):
            from flask import jsonify

            return request.parsed_obj

    return app


app = create_app()
if __name__ == "__main__":
    app.run(debug=True)

and then the curl request:

curl -X POST "http://127.0.0.1:5000/restplus/make_a_widget" -H "accept: application/json" -H "Content-Type: application/json" -d "[{ \"baz\": 422, \"foo\": \"test value\"},{ \"baz\": 1, \"foo\": \"another value\"}]"

yields a successful response:

[
    {
        "baz": 422,
        "foo": "test value"
    },
    {
        "baz": 1,
        "foo": "another value"
    }
]

Assuming this is what you observe as well, the issue is limited to the Swagger documentation itself, and I suspect the fix is simply to make sure if many=True that a List is wrapped around the converted schema. Should be straightforward to fix.

from flask_accepts.

imgos avatar imgos commented on June 11, 2024

I agree, your example functions correctly and only the swagger documentation is incorrect.

In a more complex app, I still have a problem with the many=True input. It is likely an interaction with another library and not a problem with this one.

Thanks for publishing this library, it is quite helpful and easy to use!

from flask_accepts.

apryor6 avatar apryor6 commented on June 11, 2024

I just tried a couple of things and wasn't quite able to get it working the way I'd like. I'll need to spend some more time on it later.

Basically it appears there is no issue with nested objects/lists -- the issue is isolated to documentation of top-level many=True.

I would point out that perhaps a more specific solution would be to declare a separate schema that explicitly wraps a list of your objects. This has the benefit of allowing you the control the model name and add additional metadata if necessary; however, it is more verbose and may not do what you want. I only bring it up as an alternative for the time being:

from dataclasses import dataclass
from marshmallow import fields, Schema, post_load
from flask import Flask, jsonify, request
from flask_accepts import accepts, responds


@dataclass
class Widget:
    foo: str
    baz: int


class WidgetSchema(Schema):
    foo = fields.String(default="test value")
    baz = fields.Integer(default=422)

    @post_load
    def make(self, data, **kwargs):
        return Widget(**data)


class WidgetList(Schema):
    widgets = fields.List(fields.Nested(WidgetSchema))


def create_app(env=None):
    from flask_restplus import Api, Namespace, Resource

    app = Flask(__name__)
    api = Api(app)

    @api.route("/restplus/make_a_widget")
    class WidgetResource(Resource):
        @accepts(dict(name="some_arg", type=str), schema=WidgetList, api=api)
        @responds(schema=WidgetList, api=api)
        def post(self):
            from flask import jsonify

            return request.parsed_obj

    return app


app = create_app()
if __name__ == "__main__":
    app.run(debug=True)

from flask_accepts.

imgos avatar imgos commented on June 11, 2024

I am generally opposed to top-level lists, but in this case I have no choice but to keep to retain compatibility.

I was able to determine the cause of my list validation failure. It was due to having RESTPLUS_VALIDATE set to True in the app configuration. Once I set it to False, then the issue is reduced to just swagger being incorrect.

I do not recall why RESTPLUS_VALIDATE was set and in my case disabling it seems fine. Should it be allowed while using flask_accepts, though? Everything seems to work okay with it set to True except for top-level list validation.

With it True, the restplus Resource's validate_payload fails while trying to validate the list as a model.

from flask_accepts.

imgos avatar imgos commented on June 11, 2024

For posterity, this example exhibits the validation issue I saw:

from dataclasses import dataclass
from marshmallow import fields, Schema, post_load
from marshmallow.validate import Range
from flask import Flask, request
from flask_accepts import accepts, responds


@dataclass
class Widget:
    foo: str
    baz: int


class WidgetSchema(Schema):
    foo = fields.String(default="test value")
    baz = fields.Integer(default=422)

    @post_load
    def make(self, data, **kwargs):
        return Widget(**data)


def create_app(env=None):
    from flask_restplus import Api, Resource

    app = Flask(__name__)
    app.config["RESTPLUS_VALIDATE"] = True

    api = Api(app)

    @api.route("/restplus/make_a_widget")
    class WidgetResource(Resource):
        @accepts(schema=WidgetSchema(many=True), api=api)
        @responds(schema=WidgetSchema(many=True), api=api)
        def put(self):
            return request.parsed_obj

    return app


app = create_app()

if __name__ == "__main__":
    app.run(debug=True)

from flask_accepts.

apryor6 avatar apryor6 commented on June 11, 2024

from flask_accepts.

VolodyaEsk avatar VolodyaEsk commented on June 11, 2024

@apryor6 so you think it is a marshmallow issue or swagger, not flask_accepts, correct?

Looks similar to
https://stackoverflow.com/questions/58484417/flask-marshmallow-nested-schema-with-many-true-not-working

from flask_accepts.

VolodyaEsk avatar VolodyaEsk commented on June 11, 2024

This issue can be closed as resolved.
The fix - #51

from flask_accepts.

VolodyaEsk avatar VolodyaEsk commented on June 11, 2024

@apryor6
Can you bump up version of the package and release new version on PyPI?

from flask_accepts.

apryor6 avatar apryor6 commented on June 11, 2024

Yes, apologies for the delay!

https://pypi.org/project/flask-accepts/0.15.4/

from flask_accepts.

VolodyaEsk avatar VolodyaEsk commented on June 11, 2024

Thank you.

from flask_accepts.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.