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!
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):