python 异步调用函数,如何从同步代码Python调用异步函数

So I'm locked to a python 3.6.2 interpreter that follows my desktop application.

What I want is to call an async function from a synchronized method or function.

When calling the python function from the desktop application it has to be a normal function which can not be awaited.

From the desktop application I am able to send a list of urls, and what I want is to send back response from every url in an async matter.

here is my try I've marked the SyntaxError which I don't know how to bypass.

import fmeobjects

import asyncio

import aiohttp

import async_timeout

logger = fmeobjects.FMELogFile()

timeout = 10

class FeatureProcessor(object):

def __init__(self):

pass

def input(self, feature):

urls_and_coords = zip(feature.getAttribute('_list{}._wms'),\

feature.getAttribute('_list{}._xmin'),\

feature.getAttribute('_list{}._ymin'),\

feature.getAttribute('_list{}._xmax'),\

feature.getAttribute('_list{}._ymax'))

-> SyntaxError: newfeature = await main(urls_and_coords)

self.pyoutput(newfeature)

def close(self):

pass

async def main(urls):

loop = asyncio.get_event_loop()

async with aiohttp.ClientSession(loop=loop) as session:

feature = loop.run_until_complete(fetch_all(session, urls, loop))

return feature

async def fetch_all(session, urls, loop):

results = await asyncio.gather(*[loop.create_task(fetch(session, url)) for url in urls])

return results

async def fetch(session, url):

with async_timeout.timeout(10):

async with session.get(url[0]) as response:

newFeature = fmeobjects.FMEFeature()

response_data = await response

newFeature.setAttribute('response', response_data)

newFeature.setAttribute('_xmin',url[1])

newFeature.setAttribute('_xmax',url[2])

newFeature.setAttribute('_ymin',url[3])

newFeature.setAttribute('_ymax',url[4])

return newFeature

I have tried making these changes:

import fme

import fmeobjects

import asyncio

import aiohttp

import async_timeout

logger = fmeobjects.FMELogFile()

class FeatureProcessor(object):

def __init__(self):

pass

def input(self, feature):

urls_and_coords = zip(feature.getAttribute('_list{}._wms'),\

feature.getAttribute('_list{}._xmin'),\

feature.getAttribute('_list{}._ymin'),\

feature.getAttribute('_list{}._xmax'),\

feature.getAttribute('_list{}._ymax'))

loop = asyncio.get_event_loop()

result = loop.run_until_complete(main(loop, urls_and_coords))

#feature.setAttribute('result',result)

self.pyoutput(feature)

def close(self):

pass

async def main(loop, urls):

async with aiohttp.ClientSession(loop=loop) as session:

return await fetch_all(session, urls, loop)

async def fetch_all(session, urls, loop):

results = await asyncio.gather(*[loop.create_task(fetch(session, url)) for url in urls])

return results

async def fetch(session, url):

with async_timeout.timeout(10):

async with session.get(url[0]) as response:

#newFeature = fmeobjects.FMEFeature()

response = await response

#newFeature.setAttribute('response', response_data)

#newFeature.setAttribute('_xmin',url[1])

#newFeature.setAttribute('_xmax',url[2])

#newFeature.setAttribute('_ymin',url[3])

#newFeature.setAttribute('_ymax',url[4])

return response, url[1], url[2], url[3], url[4]

but now I end up with this error:

Python Exception : object ClientResponse can't be used in 'await'

expression

Traceback (most recent call last):

File "", line 20, in input

File "asyncio\base_events.py", line 467, in run_until_complete

File "", line 29, in main

File "", line 33, in fetch_all

File "", line 41, in fetch

TypeError: object ClientResponse can't be used in 'await' expression

解决方案

@deceze answer is probably the best you can do in Python 3.6.

But in Python 3.7, you could directly use asyncio.run in the following way:

newfeature = asyncio.run(main(urls))

It will properly create, handle, and close an event_loop.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值