Vadim Filin
Vadim Filin

Reputation: 383

aiohttp implicitly turns out my method to function

My aiohttp middleware gets function as parameter instead of bound method which have been passed to route. How to explain this behavior? How to avoid that?

class AsyncHttpServer:

    def __init__(self, host=None, port=None, loop=None, conf_path=None):
        self.loop = loop
        self.conf_path = conf_path
        self.host = host
        self.port = port
        self.loop = loop
        self.app = web.Application(
            middlewares=[
                preprocess_request,
            ]
        )

    def serve_forever(self):

        with RequestHandler(self.conf_path) as handler:
            print(handler.search)  # bound method 'search'. Instance is irrelevant
            self.app.router.add_routes([                   
                web.post('/search', handler.search, name='search'),                   
            ])
            try:
                web.run_app(self.app, port=self.port, host=self.host, loop=self.loop)
            except KeyboardInterrupt:
                pass

@asyncio.coroutine
@middleware
def preprocess_request(request, handler):
    print(handler) # function 'search'

Upvotes: 1

Views: 650

Answers (1)

Vadim Filin
Vadim Filin

Reputation: 383

If handlers are organized with class and have been passed to route, aiohttp wraps those handlers with decorators using partial.wraps and makes it like usual functions. So it is impossible to use this functions as object methods directly.

They can be used as methods only after unwrapping:

handler.__wrapped__.__self__

or handlers class may be passed as web.Application() value because it have MutableMapping protocol:

with RequestHandler(self.conf_path) as handler:
        self.app["handler"] = handler

and may be called like:

class_handler = request.app["handler"]

Upvotes: 2

Related Questions