Мы рады сообщить о выпуске версии httr2 1.1.0. httr2
— это универсальный HTTP-клиент, который предоставляет современный интерфейс с поддержкой конвейеров для работы с веб-API. Он построен на базе пакета {curl} и предлагает такие функции, как явные объекты запросов, встроенные инструменты ограничения скорости и повторов, полная поддержка OAuth, а также безопасная работа с секретами и учетными данными.
В этом посте мы подробно рассмотрим новый потоковый интерфейс, построенный вокруг функции req_perform_connection(), изучим новый набор инструментов для работы с URL и выделим некоторые из самых значимых изменений, включая улучшенную поддержку AWS и усовершенствования системы кэширования. Также мы расскажем о статусе изменений в жизненном цикле пакета.
Этот пост включает самые важные улучшения версий с 1.0.1 по 1.0.7, в ходе которых были доработаны различные функции и исправлены многочисленные ошибки. Полный список изменений вы можете найти в заметках о выпуске на GitHub или в файле NEWS.
Установка
Установите httr2
из CRAN
с помощью следующей команды:
install.packages("httr2")
Потоковая передача данных
Главное новшество этого релиза — улучшенный API для работы с потоковыми ответами, когда содержимое запроса поступает не сразу, а передается частями. Это особенно актуально для взаимодействия с большими языковыми моделями (LLM), где важна быстрая и плавная подача ответов в чате.
Вы можете протестировать новый функционал в пакете ellmer, который позволяет общаться с LLM от различных провайдеров.
Ключевой новой функцией стала req_perform_connection() — она пришла на смену устаревшей req_perform_stream() с механизмом обратных вызовов. В отличие от предыдущей версии, req_perform_connection() возвращает стандартный объект ответа с подключением, через которое поступают данные:
library(httr2)
req <- request(example_url()) |> req_template("/stream-bytes/:n", n = 10240)
resp <- req_perform_connection(req)
resp
#> <httr2_response>
#> GET http://127.0.0.1:49283/stream-bytes/10240
#> Status: 200 OK
#> Content-Type: application/octet-stream
#> Body: Streaming connection
Получив потоковое подключение, вы можете многократно вызывать функции resp_stream_*()
для загрузки данных порциями. Чтобы определить, когда следует завершить процесс, используйте функцию resp_stream_is_complete().
while (!resp_stream_is_complete(resp)) {
bytes <- resp_stream_raw(resp, kb = 2)
cat("Downloaded ", length(bytes), " bytes\n", sep = "")
}
#> Downloaded 2048 bytes
#> Downloaded 2048 bytes
#> Downloaded 2048 bytes
#> Downloaded 2048 bytes
#> Downloaded 2048 bytes
#> Downloaded 0 bytes
Помимо resp_stream_raw(), которая возвращает необработанный вектор, вы можете использовать resp_stream_lines() для потоковой передачи данных построчно и resp_stream_sse() для потоковой передачи событий от сервера.
Инструменты для обработки URL
Работа с URL стала проще благодаря трем новым функциям: url_modify(), url_modify_query() и url_modify_relative(). Вы можете увидеть, как они работают, в примерах ниже:
# url_modify() изменяет компоненты URL
url_modify("https://example.com", hostname = "github.com")
#> [1] "https://github.com/"
url_modify("https://example.com", scheme = "http")
#> [1] "http://example.com/"
url_modify("https://example.com", path = "abc", query = list(foo = "bar"))
#> [1] "https://example.com/abc?foo=bar"
# url_modify_query() позволяет изменять отдельные параметры запроса
# изменение существующего параметра:
url_modify_query("http://example.com?a=1&b=2", a = 10)
#> [1] "http://example.com/?b=2&a=10"
# удаление параметра:
url_modify_query("http://example.com?a=1&b=2", b = NULL)
#> [1] "http://example.com/?a=1"
# добавление нового параметра:
url_modify_query("http://example.com?a=1&b=2", c = 3)
#> [1] "http://example.com/?a=1&b=2&c=3"
# url_modify_relative() переходит по относительному URL
url_modify_relative("https://example.com/a/b/c.html", "/d/e/f.html")
#> [1] "https://example.com/d/e/f.html"
url_modify_relative("https://example.com/a/b/c.html", "C.html")
#> [1] "https://example.com/a/b/C.html"
url_modify_relative("https://example.com/a/b/c.html", "../B.html")
#> [1] "https://example.com/a/B.html"
Мы также добавили функцию req_url_relative(), чтобы упростить переход к относительному URL для существующего запроса.
Другие улучшения
Есть несколько других значительных улучшений, которые стоит выделить:
Мы упростили взаимодействие с веб-сервисами AWS с помощью req_auth_aws_v4() для подписи запросов и resp_stream_aws() для потоковой передачи ответов. Особая благодарность проекту lifion-aws-event-stream за предоставление понятной примерной реализации.
Мы устранили множество ошибок, которые делали req_cache() ненадежным. Это включает улучшение обработки изменений, касающихся только заголовков, более эффективное очищение кэша и добавление новых опций для отладки. Если вы работаете с веб-API, поддерживающим кэширование, мы настоятельно рекомендуем попробовать эту функцию. В следующем релизе пакета {gh} кэш будет использоваться по умолчанию, и мой опыт работы с девелоперской версией показывает, что это значительно улучшает производительность.
Функция is_online() предоставляет удобный способ проверки подключения к интернету.
Функция req_perform_promise() позволяет выполнять запросы в фоновом режиме (благодаря @gergness) с использованием эффективного метода, который ожидает активности сокетов cURL (спасибо @shikokuchuo).
Важные изменения
В связи с развитием httr2 были внесены некоторые изменения:
Функция req_perform_iterative() теперь стабильна и больше не является экспериментальной.
Функция req_perform_stream() заменена на req_perform_connection(), как упомянуто выше.
Функции with_mock() и local_mock() устарели и будут удалены в следующем релизе. Вместо них следует использовать with_mocked_responses() и local_mocked_responses().