首页 > 解决方案 > 使用 Asyncio 执行 HTTP 请求

问题描述

以下函数需要异步发送请求:

devices.csv 中的行数 = 100 万

必需:每天为所有 100 万行发送 POST 请求,持续 3 天

def check_in():
    logging.info('Starting')
    day = 0
    while day < 3:
        logging.info('Check-in Day = ' + str(day))
        with open('devices.csv', newline='') as csvfile: 
            reader = csv.DictReader(csvfile)
            for row in reader:
                device_sn = row['serial_number']
                payload = {
                    "product": "##",
                    "board": "###",
                    "hardware_id": "0000",
                    "usage_id": "000",
                    "mac_address": row['mac_address'],
                    "serial_number": row['serial_number']
                }
                logging.info(
                    'Check-in device: ' + device_sn)
                checkin_post(payload, device_sn)
            day += 1
def checkin_post(payload, device_sn):
    payload = payload
    serial_number = device_sn

    print('\n' + 72 * '=' + '\nPOST /device/' +
          serial_number + '/check-in')

    resp = requests.post(base_url + '/device/' +
                         serial_number + '/check-in', auth=auth, json=payload)

    print(resp.status_code)

代码可能会更改为可能类似于:

async def checkin_post(payload, device_sn):

    payload = payload
    serial_number = device_sn

    print('\n' + 72 * '=' + '\nPOST /device/' +
          serial_number + '/check-in')

    resp = requests.post(base_url + '/device/' +
                         serial_number + '/check-in', auth=auth, json=payload)
    return resp.status_code


async def main(payload, device_sn):
    checkin_post(payload, device_sn)

此外,由于没有await,它并不是真正的异步。

标签: pythonpython-3.xpython-requestspython-asyncio

解决方案


如果您现在已经解决了,很抱歉回复晚了。但是您需要返回 ensure_future 对象。你可以试试下面的代码:

async def check_in():
    logging.info('Starting')
    count = 0
    futures = []
    while count < 3:
        logging.info('Check-in Day = ' + str(count))
        with open('devices.csv', newline='') as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                device_sn = row['serial_number']
                payload = {
                    "product": "##",
                    "board": "###",
                    "hardware_id": "0000",
                    "usage_id": "000",
                    "mac_address": row['mac_address'],
                    "serial_number": row['serial_number']
                }
                logging.info(
                    'Check-in device: ' + device_sn)
                async with aiohttp.ClientSession() as session:
                    async with session.post(base_url + '/device/' + device_sn + '/check-in', auth=auth, json=payload) as resp:
                        futures.append(asyncio.ensure_future(await resp.status))
            count += 1
    return await asyncio.gather(*futures)

def main():
    loop = asyncio.get_event_loop()
    futures = asyncio.ensure_future(check_in())
    responses = loop.run_until_complete(futures)

推荐阅读