代码之家  ›  专栏  ›  技术社区  ›  Bhargav

python asyncio REST api调用出错

  •  2
  • Bhargav  · 技术社区  · 6 年前

    我正试图使用asyncio调用REST API async,但我一直收到错误“ coroutine was never awaited “我明白。但我希望这种行为,我希望我的功能结束只是张贴,而不是等待结果。这是我的密码

    async def callCoroutine:
        #call a REST API 
    
    def lambda_handler(event, context):   
        loop = asyncio.get_event_loop()
        task = loop.create_task(callCoroutine(data))
        return
    

    有人能帮忙吗?

    3 回复  |  直到 6 年前
        1
  •  1
  •   0az    6 年前

    如果只需要调用API,而不考虑结果,则可以在另一个线程中使用执行器,这不会阻塞主线程。

    在执行器中运行,使用 AbstractEventLoop.run_in_executor() 遗嘱执行人 concurrent.futures .

        2
  •  1
  •   wowkin2    6 年前

    对于当前示例,您需要在某个地方运行循环(例如,如果您有某个web服务器或工作者- loop.run_forever() )

    带运行循环的固定代码示例

    import asyncio
    
    
    async def callCoroutine(data):
        print('This is data: %s' % data)
    
    
    def lambda_handler(event, context):   
        loop = asyncio.get_event_loop()
        task = loop.create_task(callCoroutine(context))
        return
    
    lambda_handler(None, {'a': 1})
    
    loop = asyncio.get_event_loop()
    loop.run_forever()
    

    举例说明 run_in_executor()

    import asyncio
    import requests
    
    
    def call_rest_api(data):
        print('Triggered REST API in background')
        response = requests.get(data['url'])
        print('Response: %s' % response)
    
    
    async def main(loop):
        print('Some operations here...')
    
        data = {'url': 'http://example.com#some_rest_api'}
        loop.run_in_executor(None, call_rest_api, data)
    
        print('Continue work of main thread...')
    
    
    if __name__ == '__main__':
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main(loop))
    

    简单的例子 await (如果需要同步调用API)

    但是,如果要编写同步代码,则不必使用asyncio。

    import asyncio
    import requests
    
    
    def call_rest_api(data):
        print('Triggered REST API in background')
        response = requests.get(data['url'])
        print('Response: %s' % response)
    
    
    async def main(loop):
        print('Some operations here...')
    
        data = {'url': 'http://example.com#some_rest_api'}
        await call_rest_api(data)
    
        print('Continue work of main thread...')
    
    
    if __name__ == '__main__':
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main(loop))
    

    你能提供一个更详细的例子来说明你所拥有的和你想要达到的目标吗?

        3
  •  0
  •   Char    6 年前

    在您的例子中,主线程是同步运行的。 所以您需要在另一个线程中使用 asyncio.run_coroutine_threadsafe .

    import asyncio
    import threading
    
    # Run asyncio loop in other thread
    loop = asyncio.new_event_loop()
    threading.Thread(target=loop.run_forever).start()
    
    
    async def call_coroutine(data):
        # call a REST API 
        return
    
    
    def lambda_handler(event, context):   
        # Run the coroutine on the loop of other thread
        future = asyncio.run_coroutine_threadsafe(call_coroutine(data), loop)
        # If need to get result: 
        result = future.result()  # This will block the main thread
    
        do_something_else()
        return
    
    # If need to stop the asyncio loop
    loop.call_soon_threadsafe(loop.stop)