Async без головной боли: встретить areq, замена погружения для запросов Python

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Может быть, просто ваша новая любимая микро-библиотека.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE