pythonpython-requestspython-asyncio

Requests in Asyncio - Keyword Arguments


I'm using asyncio with the requests module to make an asynchronous HTTP request.

I can make a GET request like this:

@asyncio.coroutine
def do_checks():
    loop = asyncio.get_event_loop()
    req = loop.run_in_executor(None, requests.get, 'https://api.github.com/user')
    resp = yield from req
    print(resp.status_code)
loop = asyncio.get_event_loop()
loop.run_until_complete(do_checks())

However, I need to do support Basic HTTP Auth (described here) in the request.

According to the documentation, url and auth are both named parameters for requests.get().

But, if I run this (note the addition of url='' and auth = ''):

@asyncio.coroutine
def do_checks():
    loop = asyncio.get_event_loop()
    req = loop.run_in_executor(None, requests.get, url='https://api.github.com/user', auth=HTTPBasicAuth('user', 'pass'))
    resp = yield from req
    print(resp.status_code)
loop = asyncio.get_event_loop()
loop.run_until_complete(do_checks())

I get this error:

TypeError: run_in_executor() got an unexpected keyword argument 'url'

In the prototype for asyncio.run_in_executor(), additional arguments are supported:

BaseEventLoop.run_in_executor(executor, callback, *args)

requests.get() clearly supports named parameters (get, auth, etc.). What's wrong?


Solution

  • Two ways to do that. Create a wrapper function, or just use a session to provide the auth.

    Using a session:

    @asyncio.coroutine
    def do_checks():
        loop = asyncio.get_event_loop()
        session = requests.Session()
        session.auth = HTTPBasicAuth('user', 'pass')
        req = loop.run_in_executor(None, session.get, 'https://api.github.com/user')
        resp = yield from req
        print(resp.status_code)
    

    Writing a wrapper function (note that I'm using def for clarity here, but that a lambda would obviously work too):

    @asyncio.coroutine
    def do_checks():
        def do_req():
            return requests.get('https://api.github.com/user', auth=HTTPBasicAuth('user', 'pass'))
        loop = asyncio.get_event_loop()
        req = loop.run_in_executor(None, do_req)
        resp = yield from req
        print(resp.status_code)