Как использовать Asyncio с циклом while - PullRequest
0 голосов
/ 14 февраля 2019

Мой код создает заказ с API при каждом вводе product_id.Затем он проверяет, через интервалы времени, успешно ли был создан заказ.Я определенно не правильно использую asyncio и надеялся, что кто-то может дать совет или даже asyncio - правильный инструмент для работы?

Я проверил документацию и примеры в Интернете, но мне трудно понять, большинствовероятно, потому что я все еще учусь кодировать (начинающий программист с Python 3.7.1)

import asyncio
import requests
import time


#creates order when a product id is entered
async def create_order(product_id):
        url = "https://api.url.com/"
    payload = """{\r\n    \"any_other_field\": [\"any value\"]\r\n  }\r\n}"""       
    headers = {
        'cache-control': "no-cache",
        }

    response = requests.request("POST", url, data=payload, headers=headers)
    result = response.json()
    request_id = result['request_id']
    result = asyncio.ensure_future(check_orderloop('request_id'))
    return result


#loops and check the status of the order.
async def check_orderloop(request_id):
    print("checking loop: " + request_id)   
    result = check_order(request_id)
    while result["code"] == "processing request":
        while time.time() % 120 == 0:
            await asyncio.sleep(120)
            result = check_order(request_id)
            print('check_orderloop: ' + result["code"])
            if result["code"] != "processing request":
                if result["code"] == "order_status":
                    return result
                else:
                    return result


#checks the status of the order with request_id         
async def check_order(request_id):
    print("checking order id: " + request_id)
    url = "https://api.url.com/" + request_id

    headers = {
        'cache-control': "no-cache"
        }

    response = requests.request("GET", url, headers=headers)
    result = response.json()
    return result


asyncio.run(create_order('product_id'))

без asyncio, он может создавать + проверку только для одного заказа за раз.Я хотел бы, чтобы код мог создавать + проверку для множества разных заказов одновременно и асинхронно.

Когда я тестирую, пробуя два разных идентификатора продукта, он дает следующее и не завершает функции.

<coroutine object create_order at 0x7f657b4d6448>
>create_order('ID1234ABCD')
__main__:1: RuntimeWarning: coroutine 'create_order' was never awaited
<coroutine object create_order at 0x7f657b4d6748>

1 Ответ

0 голосов
/ 14 февраля 2019

Неправильно использовать блокирующую библиотеку requests в асинхронном коде.Ваша программа будет ждать завершения каждого запроса и ничего не будет делать.Вместо этого вы можете использовать async aiohttp library .

Вы не можете просто вызвать функцию async и ожидать, что она будет выполнена, она просто вернет вам объект coroutine.Вы должны добавить эту сопрограмму в цикл обработки событий asyncio.run(), как в коде:

>>> asyncio.run(create_order('ID1234ABCD'))

Или, если вы хотите запустить несколько сопрограмм одновременно:

>>> asyncio.run(
    asyncio.wait([
        create_order('ID1234ABCD'),
        create_order('ID1234ABCD')
    ])
)

Также, если вы хотите комфортно тестировать свои async функции из REPL, вы можете использовать IPython , он может запускать асинхронные функции прямо из REPL (только для версий более новых, чем 7.0).

Установить:

pip3 install ipython

Запустить:

ipython

И теперь вы можете ожидать свою асинхронную функцию:

In [1]: await create_order('ID1234ABCD')
...