python-3.8falconframeworkwaitress

"Missing 1 required positional argument: 'resp'" when invoking Falcon resource responder that has a 'self' argument


I am developing a WSGI application on Windows. I use peewee (which is supposedly unrelated) and:

falcon==2.0.0
waitress==1.4.3

I have the following code in my resources.py:

from models import Board

class BoardResource:
    def on_get_collection(self, req, resp):
        resp.media = Board.select()

    def on_get(self, req, resp):
        code = req.get_param('code')
        resp.media = Board.get_by_id(code)

I have the following code in my app.py:

import falcon
import models
from resources import BoardResource

def init():
    models.init()
    api = falcon.API()
    api.add_route('/boards', BoardResource, suffix='collection')
    api.add_route('/board', BoardResource)
    return api

api = init()

I start the app with this command: waitress-serve app:api. When I request /boards from the API, I get this error:

ERROR:waitress:Exception while serving /boards
Traceback (most recent call last):
  File "c:\users\pepsiman\.virtualenvs\hsech-api\lib\site-packages\waitress\channel.py", line 349, in service
    task.service()
  File "c:\users\pepsiman\.virtualenvs\hsech-api\lib\site-packages\waitress\task.py", line 169, in service
    self.execute()
  File "c:\users\pepsiman\.virtualenvs\hsech-api\lib\site-packages\waitress\task.py", line 439, in execute
    app_iter = self.channel.server.application(environ, start_response)
  File "c:\users\pepsiman\.virtualenvs\hsech-api\lib\site-packages\falcon\api.py", line 269, in __call__
    responder(req, resp, **params)
TypeError: on_get_collection() missing 1 required positional argument: 'resp'

I decided to remove the self argument from the definiton of on_get_collection and the error was gone. I know that self must be there and have no idea why it doesn't work like that. Any ideas how to fix?


Solution

  • I have found the problem myself: when calling api.add_route the responder class must indeed be instantiated, thus the following lines:

    api.add_route('/boards', BoardResource, suffix='collection')
    api.add_route('/board', BoardResource)
    

    need to be modified like this:

    api.add_route('/boards', BoardResource(), suffix='collection')
    api.add_route('/board', BoardResource())
    

    Of course it works without removing the self argument from the definitions.

    I hope this silly mistake of mine will help someone fix theirs.