akgold / do4ds

A book on DevOps for Data Scientists with CRC Press.
https://do4ds.com
Other
130 stars 27 forks source link

Lab 3 - httr2 request results in error HTTP 422 Unprocessable Entity #254

Open durraniu opened 3 months ago

durraniu commented 3 months ago

I ran app.run(port = 8080) which opened the docs page in browser. Clicking the Try button under Predict POST request produces a prediction (200 OK). However, the R shiny app displays the error HTTP 422 Unprocessable Entity. I then ran the code outside of shiny:

httr2::request("http://127.0.0.1:8080/predict") |>
    httr2::req_body_json(list(
        bill_length_mm = 30,
        species_Chinstrap = "Adelie" == "Chinstrap",
        species_Gentoo = "Adelie" == "Gentoo",
        sex_male = "Male" == "Male"
    )) |>
    httr2::req_perform()
Error in `httr2::req_perform()`:
! HTTP 422 Unprocessable Entity.
Run `rlang::last_trace()` to see where the error occurred.

Dry Run

I checked that the request is correct:

httr2::request("http://127.0.0.1:8080/predict") |>
    httr2::req_body_json(list(
        bill_length_mm = 30,
        species_Chinstrap = "Adelie" == "Chinstrap",
        species_Gentoo = "Adelie" == "Gentoo",
        sex_male = "Male" == "Male"
    )) |>
    httr2::req_dry_run()
POST /predict HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: httr2/1.0.1 r-curl/5.2.1 libcurl/8.3.0
Accept: */*
Accept-Encoding: deflate, gzip
Content-Type: application/json
Content-Length: 86

{"bill_length_mm":30,"species_Chinstrap":false,"species_Gentoo":false,"sex_male":true}

CURL

Running curl works:

curl -X POST "http://127.0.0.1:8080/predict" \
 -H "Accept: application/json" \
 -H "Content-Type: application/json" \
 -d '[{"bill_length_mm":39.1,"species_Chinstrap":false,"species_Gentoo":true,"sex_male":true}]' \

 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   121  100    32  100    89   6294  17505 --:--:-- --:--:-- --:--:-- 30250{"predict":[5083.6963092196365]}

So, I translated that to httr2 syntax:


httr2::curl_translate("curl -X POST 'http://127.0.0.1:8080/predict' \
 -H 'Accept: application/json' \
 -H 'Content-Type: application/json' \
 -d '[{'bill_length_mm':39.1,'species_Chinstrap':false,'species_Gentoo':true,'sex_male':true}]' ")

But even that throws the same error:

httr2::request("http://127.0.0.1:8080/predict") |> 
    httr2::req_method("POST") |> 
    httr2::req_headers(
        Accept = "application/json",
    ) |> 
    httr2::req_body_raw("[{bill_length_mm:39.1,species_Chinstrap:false,species_Gentoo:true,sex_male:true}]", "application/json") |> 
    httr2::req_perform()
Error in `httr2::req_perform()`:
! HTTP 422 Unprocessable Entity.
Run `rlang::last_trace()` to see where the error occurred.

I am not sure what is going wrong with httr2. Any ideas?

durraniu commented 3 months ago

Same issue in Python

By the way, the same happens with the python shiny app. Running the post request outside shiny shows that the same 422 error occurs:

d = {
    "bill_length_mm" : 30,
    "sex_Male" : True,
    "species_Gentoo" : True, 
    "species_Chinstrap" : True    
}
import requests
r = requests.post('http://127.0.0.1:8080/predict', json = d)
r
<Response [422]>