Используйте асинхронный HTTP-клиент, ограничьте одновременные запросы и записывайте хэши по исходным индексам. MD5 считайте потоково по байтам ответа, явно определив политику ошибок.
Есть входной массив URL. Нужно параллельно перейти по ссылкам, получить содержимое ответов, посчитать MD5 и вернуть массив хэшей в том же порядке. Как бы вы это реализовали?
Используйте асинхронный HTTP-клиент, ограничьте одновременные запросы и записывайте хэши по исходным индексам. MD5 считайте потоково по байтам ответа, явно определив политику ошибок.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Используйте асинхронный HTTP-клиент, ограничьте одновременные запросы и записывайте хэши по исходным индексам. MD5 считайте потоково по байтам ответа, явно определив политику ошибок.
Пример для доверенных URL, Python 3.11+ и aiohttp; ошибка любого запроса отменяет пакет:
import asyncio
import hashlib
import aiohttp
async def hashes(urls):
result = [None] * len(urls)
limit = asyncio.Semaphore(10)
timeout = aiohttp.ClientTimeout(total=30)
async with aiohttp.ClientSession(timeout=timeout) as session:
async def fetch(index, url):
async with limit:
async with session.get(url) as response:
response.raise_for_status()
digest = hashlib.md5(usedforsecurity=False)
size = 0
async for chunk in response.content.iter_chunked(65536):
size += len(chunk)
if size > 10_000_000:
raise ValueError('response too large')
digest.update(chunk)
result[index] = digest.hexdigest()
async with asyncio.TaskGroup() as group:
for index, url in enumerate(urls):
group.create_task(fetch(index, url))
return result
Хэшируется декодированное клиентом тело. Для огромного массива нужен фиксированный пул workers, для пользовательских URL — SSRF-защита с проверкой redirect. MD5 не подходит для доказательства подлинности.
Источник: docs.aiohttp.org.