Faça milhares de requisições assíncronas de forma super rápida!
- #Python
Crie um código assíncrono para realizar milhares requisições de forma mais rápida, usando asyncio e aiohttp
Neste simples exemplo, vamos assumir que precisamos coletar item a item de uma API, para podermos verificar a performance entre a forma de coleta síncrona e assíncrona
import asyncio
import aiohttp
import requests
BASE_URL = 'https://fakestoreapi.com/products' ## API possui 20 produtos como teste
TCP_REQUESTS_LIMIT = 30
TIMOUT_SECONDS_LIMIT = 300
## para criar uma função assincrona em python, basta usar async no inicio
async def async_example():
async def get_url(session, item_id):
response = await session.get(f'{BASE_URL}/{item_id}')
return item_id, await response.json()
# Definindo timeout para nossa sessão, sem timeout total e com 5 minutos para aguardar response
session_timeout = aiohttp.ClientTimeout(total=None, sock_connect=TIMOUT_SECONDS_LIMIT, sock_read=TIMOUT_SECONDS_LIMIT)
# Limite de conexões simultâneas para a sessão, por padrão o protocolo TCP suporta até 100
connector = aiohttp.TCPConnector(limit=TCP_REQUESTS_LIMIT) # Limita as requisições simultâneas (semáforo de requests async)
# Iniciamos a session com as configurações
async with aiohttp.ClientSession(timeout=session_timeout, connector=connector) as session:
lista_de_tarefas = []
# Cria e popula a lista de tarefas, obs: não executa as tarefas
for item_id in range(1, 21):
# Usamos ensure_future para garantir o agendamento da tarefa pelo asyncio
tarefa = asyncio.ensure_future(get_url(session, item_id))
lista_de_tarefas.append(tarefa)
# Diz para o asyncio executar as tarefas e aguardar o fim de todas
resultados = await asyncio.gather(*lista_de_tarefas)
print(resultados)
def sync_example():
session = requests.Session()
for item_id in range(1, 21):
response = session.get(f'{BASE_URL}/{item_id}')
print((item_id, response.json()))
if __name__ == '__main__':
### Assumindo um caso hipotético onde tenhamos que buscar item a item de uma API, qual seria mais eficiente?
# Dependendo da internet, pode demorar entre 10 a 15 segundos ou até mais usando requests
sync_example()
# O asyncio com aiohttp executa muito mais rapido comparado a requests normais, entre 1 a 4 segundos
asyncio.run(async_example())
# Obs: a API possibilita trazer todos os produtos de uma única vez, são 20 produtos ao todo
# print(requests.get(BASE_URL).json())
Usar a biblioteca requests é algo muito mais simples de formular comparado a uma estrutura assíncrona para requisições, porem caso o assunto seja velocidade e muita velocidade, como por exemplo na casa do milhar, o uso do conjunto de asyncio e aiohttp vale muito a pena e pode auxiliar neste processo
Obs:
Vale ressaltar que a biblioteca requests do python se comporta de forma sincrona, mesmo que utilizada dentro de uma função async