-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add req_perform_open, which makes resp$body the underlying stream #521
Conversation
blocking = TRUE greatly simplifies cases where you don't have better things to do while you're waiting (i.e. most R use cases that are not Shiny or plumber?)
Co-authored-by: Hadley Wickham <[email protected]>
SSE equivalent usage: library(httr2)
# Define the API endpoint and your API key
api_endpoint <- "https://api.openai.com/v1/chat/completions"
api_key <- Sys.getenv("OPENAI_API_KEY")
# Build the request
response <- request(api_endpoint) %>%
req_headers(
"Content-Type" = "application/json",
"Authorization" = paste("Bearer", api_key)
) %>%
req_body_json(list(
model = "gpt-4o",
temperature = 0.7,
stream = TRUE,
messages = list(
list(
role = "system",
content = "You're an incredibly verbose assistant."
),
list(
role = "user",
content = "When did the modern Olympics start?"
)
)
)) %>%
req_perform_open(blocking = FALSE)
while (isIncomplete(response$body)) {
msg <- read_sse(response$body)
if (!is.null(msg)) {
cat(msg$data)
cat("\n")
} else {
message("SLEEPING...\n")
Sys.sleep(0.25)
}
}
close(response$body) |
BTW, Ideally we'd eventually have a true callback based async version that is both efficient and nonblocking. |
R/req-perform-stream.R
Outdated
#' @export | ||
#' @rdname req_perform_connection | ||
close.httr2_response <- function(con, ...) { | ||
check_streaming_response(con) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean if you call close(resp)
on a non-streaming response, you'll get an error? If so, I think a no-op would be better; as a general rule I try not to throw in cleanup code since it's so often invoked in places where errors are not expected or hard to deal with (like in a finally
or a gc finalizer).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah makes sense.
One issue we must address before merging is that |
And at a more meta level, we need to add some tests for |
I'm not saying we need to implement this or, even if we want to, that it needs to be part of this PR, but I just wanted to point out two things about the SSE spec:
es <- EventSource$new("http://localhost:5000")
es$addEventListener("message", \(e) { message("Message received: ", e$data) })
...
es$close() I wonder if a high-level SSE wrapper like this (or a more idiomatic version) is something httr2 users would expect to see and/or find useful.
|
* Requires r-lib/httr2#521 * Explain plot feature is currently broken
No one else has asked for SSE support, so I don't think we need to do prospective work, but I'm certainly happy to continue to build on this API as we discover more about what we need. I'm planning on merging this PR today. |
Looks great, thanks! |
Alternative, lower-level approach to #520. SSE support could be built on top--I'll take a stab at that too.
Example usage: