我有一个很长的密钥列表,我正在使用每个密钥调用 REST API 以获取有关它的一些元数据。
API 一次只能接受一个键,但我想知道是否有一种方法可以从我这边批量或多线程调用?
是的,有多种方法可以在 Python 中进行多线程或批量 REST API 调用,以提高程序的性能。实现此目的的一种方法是使用
concurrent.futures
模块,该模块为使用线程或进程异步执行函数提供高级接口。
以下示例代码展示了如何使用
concurrent.futures
批量执行多线程 REST API 调用:
import requests
from concurrent.futures import ThreadPoolExecutor
from itertools import islice
API_ENDPOINT = 'https://api.example.com/metadata'
def get_metadata(keys):
results = []
with ThreadPoolExecutor(max_workers=5) as executor:
for batch in iter(lambda: list(islice(keys, 5)), []):
futures = [executor.submit(get_metadata_for_key, key) for key in batch]
results += [future.result() for future in futures]
return results
def get_metadata_for_key(key):
url = f"{API_ENDPOINT}/{key}"
response = requests.get(url)
if response.status_code == 200:
return response.json()
else:
return None
在此示例中,
get_metadata
函数获取键列表,并以 5 个为一组对每个键使用 ThreadPoolExecutor
到 execute get_metadata_for_key
函数。 islice
函数用于创建一个返回 5 个键批次的迭代器从输入列表中。 executor.submit
函数用于为批次中的每个键向线程池提交一个新任务,该任务返回一个concurrent.futures.Future
对象。 future.result()
函数用于检索每个任务的结果并将其附加到结果列表中。
您可以修改
max_workers
参数来控制执行任务的线程数量。在此示例中,我使用 5 个线程。
对此的其他回复看起来像 ChatGPT,所以应该忽略它。
但是,我确实使用它的代码作为基础来编写一个可以完成我想要的功能的函数。
def get_save_metadata(keys, workers):
results = {}
with ThreadPoolExecutor(max_workers=workers) as executor:
for batch in tqdm(batched(keys, workers)):
futures = {key: executor.submit(get_metadata_for_key, key) for key in batch}
futures = {key: value.result() for key, value in futures.items()}
results.update({key: xmltodict.parse(value) for key, value in futures.items()})
return results