python-restx / flask-restx

Fork of Flask-RESTPlus: Fully featured framework for fast, easy and documented API development with Flask
https://flask-restx.readthedocs.io/en/latest/
Other
2.15k stars 332 forks source link

AttributeError: 'SchemaModel' object has no attribute 'items' #142

Open edwinhaver opened 4 years ago

edwinhaver commented 4 years ago

Hi,

I am trying to use @api.marshal_with a JSON schema but I get the following error: AttributeError: 'SchemaModel' object has no attribute 'items'

The schema is correct as it works with @api.response and the model is shown correctly in Swagger.

Code

downloadOrderResponse = api.schema_model('DownloadOrderResponse', {
    'properties': {
        'iccid': {
            "type" : "string",
            "pattern" : "^[0-9]{19}[0-9F]?$",
            "description" : "ICCID as described in section 5.2.1"
        }
    },
    'type': 'object'
})

@api.route('/downloadOrder')
class DownloadOrder(Resource):
    @api.marshal_with(downloadOrderResponse, skip_none=True)
    def post(self):
        return {
            "iccid": "01234567890123456789"
        }

Expected Behavior

Correct response marshalling using the JSON schema.

Actual Behavior

Throws: AttributeError: 'SchemaModel' object has no attribute 'items'

Error Messages/Stack Trace

Traceback (most recent call last): File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask/app.py", line 2464, in call return self.wsgi_app(environ, start_response) File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask/app.py", line 2450, in wsgi_app response = self.handle_exception(e) File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask_restx/api.py", line 638, in error_router return original_handler(f) File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask/app.py", line 1867, in handle_exception reraise(exc_type, exc_value, tb) File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise raise value File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask_restx/api.py", line 636, in error_router return self.handle_error(e) File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app response = self.full_dispatch_request() File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request rv = self.handle_user_exception(e) File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask_restx/api.py", line 638, in error_router return original_handler(f) File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception reraise(exc_type, exc_value, tb) File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise raise value File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask_restx/api.py", line 636, in error_router return self.handle_error(e) File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request rv = self.dispatch_request() File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request return self.view_functionsrule.endpoint File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask_restx/api.py", line 375, in wrapper resp = resource(*args, kwargs) File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask/views.py", line 89, in view return self.dispatch_request(*args, *kwargs) File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask_restx/resource.py", line 44, in dispatch_request resp = meth(args, kwargs) File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask_restx/marshalling.py", line 269, in wrapper resp, self.fields, self.envelope, self.skip_none, mask, self.ordered File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask_restx/marshalling.py", line 58, in marshal out, has_wildcards = _marshal(data, fields, envelope, skip_none, mask, ordered) File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/flask_restx/marshalling.py", line 181, in _marshal for k, v in iteritems(fields) File "/Users/edwin/.local/share/virtualenvs/flask-test-BGYUVEN8/lib/python3.7/site-packages/six.py", line 589, in iteritems return iter(d.items(**kw)) AttributeError: 'SchemaModel' object has no attribute 'items'

Environment

natm commented 4 years ago

I've seen this issue in the past, https://github.com/noirbizarre/flask-restplus/issues/293

Would be great to reliably use JSON schemas as models.

syzhakov commented 3 years ago

Same happens for me.. Seems like there is no way to use marshal_with with schema model, just with schema...

er1csu commented 3 years ago

Are there any known workarounds for this bug?

harshal-c commented 3 years ago

Has anyone looked into this recently? I'm keen to know the workaround also

PrashantChouksey commented 2 years ago

I got same error in my code, when I was import from flask_restful import marshal_with then solution was I replaced it with flask_apispec import marshal_with then It's fixed.

sylv01 commented 2 years ago

I got same error in my code, when I was import from flask_restful import marshal_with then solution was I replaced it with flask_apispec import marshal_with then It's fixed.

@PrashantChouksey I followed this recommendation and was unable to use the marshal_with() decorator. Could you elaborate perhaps with an example of how you were able to do this?

Here's my code and my change... Original code with AttributeError: 'SchemaModel' object has no attribute 'items' error.

@ns.route("/settings")
class Settings(Resource):
    model = ns.schema_model('User Settings', settings_schema)
    @ns.marshal_with(model)
    def get(self):
        """Read in user.json file and return contents of file."""
        with open(USER_FILE, 'r') as f:
            data = json.loads(f.read())
        return data

Updated code with new error AttributeError: 'SchemaModel' object has no attribute 'dump'

from flask_apispec import marshal_with
...
@ns.route("/settings")
class Settings(Resource):
    model = ns.schema_model('User Settings', settings_schema)
    @marshal_with(model)
    def get(self):
        """Read in user.json file and return contents of file."""
        with open(USER_FILE, 'r') as f:
            data = json.loads(f.read())
        return data

The swagger docs do not show the 'Example Value' with the updated method either.

CharlesPerrotMinotHCHB commented 5 months ago

Still an issue...

ProgTiger commented 3 months ago

Same problem here...

{
  "error": "'SchemaModel' object has no attribute 'items'"
}