使用 Asyncio + Aiohttp 将一个请求的输出用作下一个请求的参数
Output of one request used as a parameter in next request using Asyncio + Aiohttp
我是异步编程、Asyncio、Aiohttp 世界的新手。
我有多个请求,其中 - 第一个请求的输出被用作第二个请求的参数。
到目前为止我已经尝试了这么多-
import aiohttp
import asyncio
async def get_response(session, url, params):
async with session.get(url=url, params=params) as response:
response = await response.json()
return response['output']
async def main():
tasks = []
url = "https://example.api.com/"
url_1 = url + 'path_1'
url_2 = url + 'path_2'
params = {'name': "Hello"}
async with aiohttp.ClientSession() as session:
a1 = get_response(session, url_1, params)
tasks.append(a1)
params = {'name': a1}
b1 = get_response(session, url_2, params)
tasks.append(b1)
responses = await asyncio.gather(*tasks, return_exceptions=True)
print(responses)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
我收到这个很明显的错误 -
TypeError("Invalid variable type: value should be str, int or float, got <coroutine object get_response at 0x00000000037FA6C0> of type <class 'coroutine'>")
那么如何将第一个请求的输出而不是协程对象传递给第二个请求 -
params = {'name': a1}
b1 = get_response(session, url_2, params)
如果第二个需要第一个协程的结果,那么你不能运行两个协程并行,你需要等待响应第一个。例如:
async def get_both(session, url_1, url_2, params_1):
a1 = await get_response(session, url_1, params_1)
params_2 = {'name': a1}
b1 = await get_response(session, url_2, params_2)
return a1, b1 # or just b1 if you don't need a1
您的 main()
将如下所示:
async def main():
url = "https://example.api.com/"
url_1 = url + 'path_1'
url_2 = url + 'path_2'
params = {'name': "Hello"}
async with aiohttp.ClientSession() as session:
responses = await get_both(session, url_1, url_2, params)
print(responses)
当然,您不会得到并行提取,但这是一个请求依赖于另一个请求的结果这一事实的直接结果。您可以轻松地做的是并行化 get_both
的多个实例 - 例如如果 url_1
和 url_2
是列表,你可以这样做:
async def main():
url_list_1 = [...]
url_list_2 = [...]
params = {'name': "Hello"}
async with aiohttp.ClientSession() as session:
coros = [get_both(session, url_1, url_2, params)
for url_1, url_2 in zip(url_list_1, url_list_2)]
all_responses = await asyncio.gather(*coros)
print(all_responses)
我是异步编程、Asyncio、Aiohttp 世界的新手。
我有多个请求,其中 - 第一个请求的输出被用作第二个请求的参数。
到目前为止我已经尝试了这么多-
import aiohttp
import asyncio
async def get_response(session, url, params):
async with session.get(url=url, params=params) as response:
response = await response.json()
return response['output']
async def main():
tasks = []
url = "https://example.api.com/"
url_1 = url + 'path_1'
url_2 = url + 'path_2'
params = {'name': "Hello"}
async with aiohttp.ClientSession() as session:
a1 = get_response(session, url_1, params)
tasks.append(a1)
params = {'name': a1}
b1 = get_response(session, url_2, params)
tasks.append(b1)
responses = await asyncio.gather(*tasks, return_exceptions=True)
print(responses)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
我收到这个很明显的错误 -
TypeError("Invalid variable type: value should be str, int or float, got <coroutine object get_response at 0x00000000037FA6C0> of type <class 'coroutine'>")
那么如何将第一个请求的输出而不是协程对象传递给第二个请求 -
params = {'name': a1}
b1 = get_response(session, url_2, params)
如果第二个需要第一个协程的结果,那么你不能运行两个协程并行,你需要等待响应第一个。例如:
async def get_both(session, url_1, url_2, params_1):
a1 = await get_response(session, url_1, params_1)
params_2 = {'name': a1}
b1 = await get_response(session, url_2, params_2)
return a1, b1 # or just b1 if you don't need a1
您的 main()
将如下所示:
async def main():
url = "https://example.api.com/"
url_1 = url + 'path_1'
url_2 = url + 'path_2'
params = {'name': "Hello"}
async with aiohttp.ClientSession() as session:
responses = await get_both(session, url_1, url_2, params)
print(responses)
当然,您不会得到并行提取,但这是一个请求依赖于另一个请求的结果这一事实的直接结果。您可以轻松地做的是并行化 get_both
的多个实例 - 例如如果 url_1
和 url_2
是列表,你可以这样做:
async def main():
url_list_1 = [...]
url_list_2 = [...]
params = {'name': "Hello"}
async with aiohttp.ClientSession() as session:
coros = [get_both(session, url_1, url_2, params)
for url_1, url_2 in zip(url_list_1, url_list_2)]
all_responses = await asyncio.gather(*coros)
print(all_responses)