Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using class-based views with Flask 2.2 causes TypeError: view() takes 0 positional arguments but 1 was given #341

Closed
NimaQu opened this issue Aug 18, 2022 · 4 comments · Fixed by #392
Assignees
Labels
bug Something isn't working help wanted Extra attention is needed
Milestone

Comments

@NimaQu
Copy link

NimaQu commented Aug 18, 2022

Error when using class-based views for compliance documentation

from flask.views import MethodView
from apiflask import APIFlask

app = APIFlask(__name__)


@app.route('/pets/<int:pet_id>', endpoint='pet')
class Pet(MethodView):

    def get(self, pet_id):
        return {'message': 'OK'}

    def delete(self, pet_id):
        return '', 204

app.run(debug=True)

Environment:

  • Python version: 3.10
  • Flask version: 2.2.2
  • APIFlask version: 1.1.2
@NimaQu NimaQu added the bug Something isn't working label Aug 18, 2022
@hjlarry
Copy link
Contributor

hjlarry commented Aug 19, 2022

I compare the source code of dispatch_request() in flask and apiflask.
It seems this example class based routes only accepts keyword arguments.
The flask always return view_function(**req.view_args).
But for apiflask, I don't know why it return view_function(*req.view_args.values()) for most situation

@greyli
Copy link
Member

greyli commented Aug 19, 2022

The change in pallets/flask#4624 (Flask 2.2) caused this issue. Before 2.2, the view function created by view classes accepts both positional arguments and keyword arguments. 2.2 changed to accept keyword-only arguments, while APIFlask always passes request.view_args as positional arguments to make sure the arguments passed to the view function are in natural order (docs).

Pin Flask to 2.1 will fix this temporarily:

pip install flask==2.1

@greyli greyli changed the title Error when use class-based views Using class-based views with Flask 2.2 causes TypeError: view() takes 0 positional arguments but 1 was given Aug 19, 2022
@hjlarry hjlarry mentioned this issue Aug 23, 2022
5 tasks
@greyli greyli added this to the 1.1.3 milestone Aug 23, 2022
@greyli
Copy link
Member

greyli commented Sep 4, 2022

I just released 1.1.3 to pin Flask < 2.2 as a temporal workaround for this issue. For the real fix to this issue, these are the possible solutions:

  1. Revert this change upstream (Re-add *args to the view function in View classes pallets/flask#4776).
  2. Patch the view function in our add_url_rule method. Not sure how to do this. Maybe the Python signature can do the trick.
  3. Copy the whole flask.view module and modify it. This will be a breaking change (for class-based view users) since the user has to change the import statement from from flask.views import MethodView to from apiflask.views import MethodView. And we have to mirror future changes for this module from Flask.
  4. Turn all the arguments passed to the view function into keyword arguments (proposed by davidism). This seems a clean solution since we can remove the patched APIFlask.dispatch_request. This is also a breaking change that will affect all users. We have to set a default keyword for input data from different locations (data for JSON or json for JSON?). Users have to pass an argument to the app.input decorator to use a different argument name.

I prefer solution 1 now, while solution 3 seems a better option for the long term.

@greyli greyli added the help wanted Extra attention is needed label Sep 4, 2022
@greyli greyli modified the milestones: 1.1.3, 1.2.0 Sep 4, 2022
@greyli greyli pinned this issue Sep 4, 2022
@hjlarry
Copy link
Contributor

hjlarry commented Sep 5, 2022

It seems solution 1 can compat with current user project, 2 and 3 are both broken change.
I think we can try whether solution 1 worked first, 2 and 3 we can concern for the next big version.
But I don't know how to patch a function.

@greyli greyli self-assigned this Nov 12, 2022
@greyli greyli unpinned this issue Jan 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants