flask-restx icon indicating copy to clipboard operation
flask-restx copied to clipboard

Trying to migrate from flask_restful... I get "TypeError: TodoList.__init__() takes 1 positional argument but 2 were given"

Open nickshanks347 opened this issue 3 years ago • 1 comments
trafficstars

Ask a question Why doesn't my code work?

Additional context

As mentioned in the title, I'm trying to migrate from flask_restful. Admittedly, I've only changed the import line from flask_restful to flask_restx. I've read through the flask_restx docs and I can't find anything that jumps out to me as to why this isn't working. This is the error I get:

TypeError: TodoList.__init__() takes 1 positional argument but 2 were given
Here is the code:
from flask import Flask, abort
from flask_restx import Resource, Api, reqparse, fields, marshal
import uuid

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

todo_fields = {
    "id": fields.String,
    "label": fields.String,
    "done": fields.Boolean,
    "colour": fields.String,
    "uri": fields.Url("todo"),
}

todo = []
todo.append({"id": "1", "label": "First task", "done": False, "colour": "red"})
todo.append({"id": "2", "label": "Second task", "done": False, "colour": "green"})
todo.append({"id": "3", "label": "Third task", "done": False, "colour": "blue"})

class TodoList(Resource):
    def __init__(self):
        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument("label", type=str, required=True, help="no label provided", location="json")
        self.reqparse.add_argument("colour", type=str, required=False, help="no colour provided", location="json",)
        self.reqparse.add_argument("done", type=bool, required=False, location="json", default=False)
        super(TodoList, self).__init__()

    def get(self):
        return todo

    def post(self):
        args = self.reqparse.parse_args()
        task = {
            "id": str(uuid.uuid4()),
            "label": args["label"],
            "done": args["done"],
            "colour": args["colour"],
        }
        todo.append(task)
        return marshal(task, todo_fields), 201

class Todo(Resource):
    def __init__(self):
        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument("label", type=str, required=False, location="json")
        self.reqparse.add_argument("colour", type=str, required=False, location="json")
        self.reqparse.add_argument("done", type=bool, required=False, location="json")
        super(Todo, self).__init__()

    def get(self, id):
        task = [task for task in todo if task["id"] == id]
        if len(task) == 0:
            abort(404)
        return marshal(task[0], todo_fields)

    def put(self, id):
        task = [task for task in todo if task["id"] == id]
        if len(task) == 0:
            abort(404)
        task = task[0]
        args = self.reqparse.parse_args()
        for k, v in args.items():
            if v is not None:
                task[k] = v
        return marshal(task, todo_fields)
    
    def delete(self, id):
        task = [task for task in todo if task["id"] == id]
        if len(task) == 0:
            abort(404)
        todo.remove(task[0])
        return {"status": True}

api.add_resource(TodoList, "/api/tasks")
api.add_resource(Todo, "/api/tasks/<string:id>")

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

nickshanks347 avatar Jun 15 '22 01:06 nickshanks347

Your__init__is missing parameters

class MyView(Resource):

    def __init__(self, api=None, *args, **kwargs):
        super().__init__(api=api, *args, **kwargs)

systemime avatar Aug 03 '22 16:08 systemime