
Async без головной боли: встретить areq, замена погружения для запросов Python
18 июля 2025 г.Если вы написали сценарии Python, которые используютrequests
Вы знаете, насколько это интуитивно понятно и надежно. Это просто работает. Это просто. И на данный момент это стало почти мышечной памятью. История начинается с простого фрагмента кода, который выглядит примерно так.
import requests
def foo():
try:
response = requests.get("https://jsonplaceholder.typicode.com/todos/1")
assert isinstance(response, requests.Response)
response.raise_for_status()
if response.ok:
response_json = response.json()
return response_json
except requests.exceptions.RequestException as e:
response_text = response.text
print("Text:", response_text)
return None
if __name__ == '__main__':
foo()
Он чистый, лаконичный и легко проверяемый.
Но тогда ваше приложение растет. Может быть, вы попадаете в сотни API или создаете веб -скребок. В любом случае, ваш верный синхронный код больше не подходит. Это начинает замедляться. И кто -то предлагает, почему бы не пойти асинхронно? Идея прилипает к вашей голове. Это кажется элегантным, красивым и больше всего, неизбежным. Итак, вы начинаете рефактор. Вы читаете оhttpx
, библиотека де-факто для всех, кто хочет сделать асинхронные запросы. И это кажется простым - сначала. Но после рефакторинга и отладки у вас осталось.
import httpx
import asyncio
async def foo():
try:
async with httpx.AsyncClient() as client:
response = await client.get("https://jsonplaceholder.typicode.com/todos/1")
assert isinstance(response, httpx.Response)
response.raise_for_status()
if response.is_success:
response_json = response.json()
print(response_json)
except httpx.HTTPError as e:
print("Text:", getattr(response, 'text', None))
return None
if __name__ == "__main__":
asyncio.run(foo())
Большой. Вы присоединились к асинхронной революции. Но что -то кажется странным. Так много изменений, просто чтобы заставить асинхровый поток работать!
httpx.AsyncClient()
Контекст -менеджерclient.get()
возвращает кораку, которая должна ожидаться- Исключения больше не являются
requests.exceptions.RequestException
- Незначительная проблема, но
response.ok
теперь заменен наresponse.is_success
С точки зрения рефакторинга, я определенно более нервничаю и менее уверен вhttpx
код, чемrequests
код. Не потому чтоhttpx
плохая библиотека, но потому, что пораженная область много. Если что -то пойдет не так, это будет очень трудно отладить. Кроме того, я больше не распознаюсь код или идиомы.
Это была именно та проблема, которую я пытался решить. Способ перейти от синхронных рабочих процессов, используя запросы на асинхронные рабочие процессы с использованиемhttpx
элегантно.
Это привело меня к построениюareq
: Минимальная асинхронная замена для запросов-нет странных новых интерфейсов, никакой дополнительной церемонии. Просто асинхронно, где вы этого хотите, и знакомое поведение, где вы этого ожидаете. Вот тот же код с использованием areq вместо запросов, и почти ничего не изменилось.
import areq
import asyncio
import requests
async def foo():
try:
response = await areq.get("https://jsonplaceholder.typicode.com/todos/1")
assert isinstance(response, requests.Response)
response.raise_for_status()
if response.ok:
response_json = response.json()
print(response_json)
except requests.exceptions.RequestException as e:
print("Text:", getattr(response, 'text', None))
return None
if __name__ == "__main__":
asyncio.run(foo())
Вот и все. Нет дополнительных конфигураций, нет новых типов для изучения. Нет специальных идиомов. Да, мне пришлось добавить асинхронологическую долю, где бы это ни было. Но почти ничего не изменилось. Более того,isinstance(response, requests.Response)
Возвращает правда!
- Нет контекстных менеджеров по шаблону
- Нет нового объекта ответа для изучения
- Тип проверок и, кроме того, что пункты остаются такими же
Для кого я строил?
Цель позадиareq
Прост: принесите асинхронные преимущества в ваше программное обеспечение, не разрушая ваш код (или ваш мозг). Вы получаете свои запросы Ergonomics Plus Async Speed - без переписываний, никаких психических накладных расходов API.areq
нет ничего особенного: это просто простая оберткаhttpx
Полем Но я чувствую, что это будет действительно полезно для некоторых людей.
🔄 Команды, мигрирующие в асинхрон, постепенно
У вас не всегда есть роскошь, чтобы остановить все и рефактировать всю свою кодовую базу для Async. Сareq
, вы можете начать принимать асинхронные части по частям, сохраняя оставшуюся часть своей логики нетронутой.
Хотите преобразовать только одну функцию? Одна конечная точка? Один модуль?areq
Позволяет вам сделать именно это, не сломавшись .OK, утверждения типа или ваш тестовый макет.
🧠 Люди, которые в конечном итоге хотят переехать вhttpx
(но не сегодня)
areq
здесь нет, чтобы конкурировать сhttpx
Полем На самом деле, это может быть вашhttpx
Полем
Вы можете использоватьareq
Чтобы разблокировать Async Performance сейчас - не переписывая все. Позже, как только вы стабилизировали свою логику и собрали данные профилирования, вы можете перейти на родныеhttpx
для более глубокого контроля или потокового потребностей. -
🧵 Строители инструментов CLI, фоновых заданий и легких API
Если вы работаете над скребками, ботами, микро службами или любым программным обеспечением, которое требует параллелизма, но не хочет полной психической нагрузки на новую парадигму запроса,areq
для вас. Это дает вам асинхронность без церемонии.
💼 Коды команды, поддерживающие код устаревших запросов
Ваш старый код запросов работает нормально. Это проверено в битве. Теперь вы просто хотите, чтобы это было быстрее.areq
позволяет вам это сделать. Нет переписать. Нет поломки. Нет гневных регрессионных тестов.
Что под капюшоном?
areq
:
- Использование
httpx.AsyncClient
под капюшоном. - Преобразует ответ на
requests.Response
Оказывай. - Конвертирует общие
httpx
Исключения (например,httpx.ConnectTimeout
) вrequests.exceptions.RequestException
подклассы. - Поддерживает все основные глаголы HTTP
Это не полная замена для всегоhttpx
илиrequests
может сделать, но он охватывает 90% практических вариантов использования, особенно когда вы пытаетесь модернизировать старую кодовую базу.
Известные ограничения
- Потоковая и продвинутая обработка сеансов не поддерживается (пока!)
- Объект ответа представляет собой подкласс
requests.Response
, но не может рассматриваться как то же самое во всех сценариях. Но эй - это рано. И это работает для большинства в реальных случаях использования, с которыми я столкнулся.
Установка и использованиеareq
Это очень легко установитьareq
Полем Вы можете установить его из PYPI, как и любой другой пакет Python.
pip install areq
Как вы можете помочь
Звездарепо
В главной роли репо помогает большему количеству людей обнаружитьareq
и позволяет вам быть в курсе функций, когда они развертываются.
Используйте его в своем коде!
Братьareq
для спина. Используйте его в своем коде, скажите мне, что разрывается. ФайлпроблемаПолем
Предложить функции
Хотите потоковую поддержку? Обработка печенья? Какая эта функция сделает вашу жизнь намного лучше?
Способствовать!
areq
открыт по получению лицензии MIT. Это также мой проект со мной как единственным разработчиком. Таким образом, если у вас есть классная идея, разбирайтесь в репозитории, реализуйте и выкладываете PR. Я обязательно рассмотрю это.
Распространить слово
Расскажи своим друзьям и коллегам. Блог об этом - хорошем, плохой и уродливой. Чем больше людей используютareq
, тем лучше это станет.
Последние мысли
Иногда все, что вам нужно, это небольшая обертка, которая уважает ваши старые привычки. Этоareq
Полем Это не спасет мир, но это спасет вас несколько дней.
Если вы когда -нибудь:
хотел «просто сделать это асинхронным», не переписывая все
был сожжен тонкими различиями между
requests
иhttpx
Или вы просто хотите заставить свой верный устаревший код запустить, но быстрее
Затем
areq
Может быть, просто ваша новая любимая микро-библиотека.
Оригинал