python-3.xflask-restfulflask-apispec

flask_apispec library makes Flask app to crash when use_kwargs decorator is used


I am building a Restful API in Python 3.8 using flask_restful, flask_apispec, and marshmallow. When I enable use_kwargs decorator my app is crushing on a POST with TypeError: post() takes 1 positional argument but 2 were given

I'd appreciate any help in solving this bug.

# requirements.txt
aniso8601==9.0.1
apispec==5.1.1
certifi==2021.10.8
charset-normalizer==2.0.7
click==8.0.3
Flask==2.0.2
flask-apispec==0.11.0
Flask-RESTful==0.3.9
gunicorn==20.1.0
idna==3.3
itsdangerous==2.0.1
Jinja2==3.0.2
MarkupSafe==2.0.1
marshmallow==3.14.0
pytz==2021.3
requests==2.26.0
six==1.16.0
tableauserverclient==0.17.0
urllib3==1.26.7
webargs==8.0.1
Werkzeug==2.0.2

from apispec import APISpec
from flask import Flask, request
from flask_restful import Resource, Api
from apispec.ext.marshmallow import MarshmallowPlugin
from flask_apispec.extension import FlaskApiSpec
from marshmallow import Schema, fields, post_load, ValidationError
from flask_apispec.views import MethodResource
from flask_apispec import use_kwargs, marshal_with

app = Flask(__name__)  # Flask app instance initiated
api = Api(app)  # Flask restful wraps Flask app around it.
app.config.update({
    'APISPEC_SPEC': APISpec(
        title='Kube Controller',
        version='v1',
        plugins=[MarshmallowPlugin()],
        openapi_version='2.0.0'
    ),
    'APISPEC_SWAGGER_URL': '/swagger/',  # URI to access API Doc JSON
    'APISPEC_SWAGGER_UI_URL': '/swagger-ui/'  # URI to access UI of API Doc
})
docs = FlaskApiSpec(app)


class AwesomeRequestSchema(Schema):
    api_type = fields.String(required=True)

    @post_load
    def create(self, data, **kwargs):
        return MyAPI(**data)


class MyAPI:
    def __init__(self, api_type):
        self.api_type = api_type
        self.message = "hi"


class AwesomeAPI(MethodResource, Resource):
    @use_kwargs(AwesomeRequestSchema)
    @marshal_with(AwesomeRequestSchema, code=200, description='Something created')
    def post(self):
        """
        POST
        """
        try:
            schema = AwesomeRequestSchema()
            data = schema.load(request.json)
            print(data.api_type)
            return request.json
        except ValidationError as err:
            return err.messages


api.add_resource(AwesomeAPI, '/')
docs.register(AwesomeAPI)

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

Thanks!


Solution

  • I had the same issue. The use_kwargs decorator will try to populate and inject the AwesomeRequestSchema object into the post() method: https://flask-apispec.readthedocs.io/en/latest/api_reference.html#flask_apispec.annotations.use_kwargs

    To fix, replace

    def post(self):
    

    with

    def post(self, populated_request_object):