1

My code creates an order with an API whenever a product_id is entered. It then checks, in timed interval loops, if the order was created successfully. I'm definitely not using asyncio right and was hoping if someone could provide a tip or if even asyncio is the right tool for the job?

I checked the documentation and examples online but find it difficult to understand, most likely because I'm still learning how to code (beginner programmer w/ 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'))

W/o asyncio, it can only create+check for one order at a time. I would like the code to be able to create+check for many different orders simultaneously and asynchronously.

When I test by trying two different product ids, it gave the following and doesn't complete the functions.

<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
  • 1
    You definitely don't want to use sync requests library in async code, use aiohttp instead. It even has almost the same API! Commented Feb 14, 2019 at 9:29

1 Answer 1

1

It's bad to use blocking requests library in asynchronous code. Your program will wait for each request to finish and will not do anything meantime. You can use async aiohttp library instead.

You can't just call async function and expect it to be executed, it will just return you a coroutine object. You have to add this coroutine to event loop by asyncio.run(), how you did in the code:

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

Or if you want to run multiple coroutines in the same time:

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

Also if you want to test your async functions from REPL comfortably, you can use IPython, it can run async functions right from REPL (only for versions newer than 7.0).

Install:

pip3 install ipython

Run:

ipython

And now you can await your async function:

In [1]: await create_order('ID1234ABCD')
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.