使用 aiohttp 分离异步请求和保存
Separating async requests and saving using aiohttp
我目前多次调用外部 API 并从每次调用下载响应内容。我正在使用 aiohttp 和 asyncio 来加速这个过程,但我无法弄清楚如何将获取功能与保存功能分开。
设置
import asyncio
import os
from aiohttp import ClientSession
目前,我正在使用以下功能:
async def fetch_and_save(link, path, client):
async with await client.get(link) as response:
contents = await response.read()
if not os.path.exists(os.path.dirname(path)):
os.makedirs(os.path.dirname(path))
with open(path, "wb") as f:
f.write(contents)
我的主要调用如下所示:
async def fetch_and_save_all(inputs):
async with ClientSession() as client:
tasks = [asyncio.ensure_future(fetch_and_save(link, path, client))
for link, path in inputs]
for f in asyncio.as_completed(tasks):
await f
def main(inputs):
loop = asyncio.get_event_loop()
loop.run_until_complete(fetch_and_save_all(inputs))
if __name__ == "__main__":
inputs = [
(f"https://httpbin.org/range/{i}", f"./tmp/{i}.txt") for i in range(1, 10)]
main(inputs)
鉴于这个基本示例,是否可以在 fetch_and_save
中分离提取和保存功能?
只需为 fetch
部分和 save
部分创建独立函数。
async def fetch(link, client):
async with await client.get(link) as response:
contents = await response.read()
return contents
def save(contents, path):
if not os.path.exists(os.path.dirname(path)):
os.makedirs(os.path.dirname(path))
with open(path, 'wb') as f:
bytes_written = f.write(contents)
return bytes_written
async def fetch_and_save(link, path, client):
contents = await fetch(link, client)
save(contents, path)
我目前多次调用外部 API 并从每次调用下载响应内容。我正在使用 aiohttp 和 asyncio 来加速这个过程,但我无法弄清楚如何将获取功能与保存功能分开。
设置
import asyncio
import os
from aiohttp import ClientSession
目前,我正在使用以下功能:
async def fetch_and_save(link, path, client):
async with await client.get(link) as response:
contents = await response.read()
if not os.path.exists(os.path.dirname(path)):
os.makedirs(os.path.dirname(path))
with open(path, "wb") as f:
f.write(contents)
我的主要调用如下所示:
async def fetch_and_save_all(inputs):
async with ClientSession() as client:
tasks = [asyncio.ensure_future(fetch_and_save(link, path, client))
for link, path in inputs]
for f in asyncio.as_completed(tasks):
await f
def main(inputs):
loop = asyncio.get_event_loop()
loop.run_until_complete(fetch_and_save_all(inputs))
if __name__ == "__main__":
inputs = [
(f"https://httpbin.org/range/{i}", f"./tmp/{i}.txt") for i in range(1, 10)]
main(inputs)
鉴于这个基本示例,是否可以在 fetch_and_save
中分离提取和保存功能?
只需为 fetch
部分和 save
部分创建独立函数。
async def fetch(link, client):
async with await client.get(link) as response:
contents = await response.read()
return contents
def save(contents, path):
if not os.path.exists(os.path.dirname(path)):
os.makedirs(os.path.dirname(path))
with open(path, 'wb') as f:
bytes_written = f.write(contents)
return bytes_written
async def fetch_and_save(link, path, client):
contents = await fetch(link, client)
save(contents, path)