How can I send multipart request using HTTP.jl where first part is json ans seocnd is csv file?
HTTP.request("POST"...
How can I send multipart request using HTTP.jl where first part is json ans seocnd is csv file?
HTTP.request("POST"...
import HTTP
url = "http://localhost:8080";
open("file.json") do json; open("file.csv") do csv
headers = []
body = HTTP.Form([
"json" => json,
"csv" => csv
])
HTTP.post(url, headers, body)
end end
(You can check the request with e.g. netcat -lp 8080
)
See documentation for HTTP.Form
(and HTTP.Multipart
), and Julia HTTP POST request with image attachment - Stack Overflow
Thank you. I think it is working, but I need to add filename of csv. Please, do you know how to add filename for it?
Did you read the documentation I linked? It is explained there, and also in the SO answer.
I tried mentioned advice:
url="http://$hostname:$port/myEndPoint"
headers = ["X-User-Id" => "d5as4d654asd65a64s5dad6a"]
body = HTTP.Form(Dict(
"json" => HTTP.Multipart("data.json", open("data.json"), "text/json"),
"csv" => HTTP.Multipart("data.csv", open("data.csv"), "text/csv"),
))
res = HTTP.post(url, headers, body)
inputJson = JSON.parse(String(req.body))
but I still getting an error with filename:
Got exception outside of a @test
HTTP.ExceptionRequest.StatusError(400, "POST", "/myEndPoint", HTTP.Messages.Response:
"""
HTTP/1.1 400 Bad Request
Content-Type: application/json
Transfer-Encoding: chunked
{"status":"InvalidInputData","description":"Item fileName is not recognized."}""")
Stacktrace:
[1] request(::Type{ExceptionLayer{ConnectionPoolLayer{StreamLayer{Union{}}}}}, ::URIs.URI, ::Vararg{Any, N} where N; kw::Base.Iterators.Pairs{Symbol, Union{Nothing, Bool}, Tuple{Symbol, Symbol}, NamedTuple{(:iofunction, :reached_redirect_limit), Tuple{Nothing, Bool}}})
@ HTTP.ExceptionRequest ~/.julia/packages/HTTP/dCYNB/src/ExceptionRequest.jl:22
Then you need to consult the documentation of the API you are using, maybe the names have to be something specific.
I have another issue related to multipart. It looks like PUT is not working correctly. I tried same example for POST and PUT. Same example worked for POST and didn’t work for PUT.
When I ran it in swagger or with CURL command, PUT option was working. When I used following code using HTTP.jl it was failing on side of server in function “HTTP.parse_multipart_form(req)”. I don’t understand why it is working with swagger, curl, but not working with HTTP.jl.
Working POST:
url = "http://$hostname:$port/datasets/csv"
headers = ["X-User-Id" => "9997773e-7e42-40d1-896b-5659a6229066",
"Content-Type"=> "multipart/form-data"]
mpdt = Vector{Pair}(undef, 2)
mpdt[1] = "configuration" => open("Upload.json")
mpdt[2] = "csv" => HTTP.Multipart("Upload.csv", open("Update.csv"), "text/csv")
body = HTTP.Form(mpdt)
res = HTTP.request("POST", url, headers, body)
Not working PUT:
url = "http://$hostname:$port/datasets/$(datasetId)/csv"
headers = ["X-User-Id" => "9997773e-7e42-40d1-896b-5659a6229066",
"Content-Type"=> "multipart/form-data"]
mpdt = Vector{Pair}(undef, 2)
mpdt[1] = "configuration" => open("Update.json")
mpdt[2] = "csv" => HTTP.Multipart("Update.csv", open("Update.csv"), "text/csv")
body = HTTP.Form(mpdt)
res = HTTP.request("PUT", url, headers, body)
Missing is boundary for HTTP.jl request. Is something wrong in my code or in HTTP.jl?
From swagger:
"""
PUT /datasets/d891d099-9e90-4b63-95cb-f889670989fc/csv HTTP/1.1
X-User-Id: 1127773e-7e42-40d1-896b-5659a6ce9066
Content-Type: multipart/form-data; boundary=---------------------------84871092641888763363568039506
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/swagger-ui
Origin: http://localhost:8080
Content-Length: 584
Connection: keep-alive
-----------------------------84871092641888763363568039506
Content-Disposition: form-data; name="configuration"
{
"att1": "va1",
"att2": "va2l",
"att3": "val3"
}
-----------------------------84871092641888763363568039506
Content-Disposition: form-data; name="file"; filename="Update.csv"
Content-Type: text/csv
Date;pA;pB;pC
2004-01-01 01:00:00;2;22;222
2004-01-01 03:00:00;4;44;444
2004-01-01 05:00:00;6;66;666
-----------------------------84871092641888763363568039506--
"""
From HTTP.jl
"""
PUT /datasets/d891d099-9e90-4b63-95cb-f889670989fc/csv HTTP/1.1
X-User-Id: 1127773e-7e42-40d1-896b-5659a6ce9066
Content-Type: multipart/form-data;
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:88.0) Gecko/20100101 Firefox/88.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/swagger-ui
Origin: http://localhost:8080
Content-Length: 584
Connection: keep-alive
-----------------------------84871092641888763363568039506
Content-Disposition: form-data;
{
"att1": "va1",
"att2": "va2l",
"att3": "val3"
}
-----------------------------84871092641888763363568039506
Content-Disposition: form-data; name="file"; filename="Update.csv"
Content-Type: text/csv
Date;pA;pB;pC
2004-01-01 01:00:00;2;22;222
2004-01-01 02:00:00;4;44;444
2004-01-01 03:00:00;6;66;666
-----------------------------84871092641888763363568039506--
"""
HTTP.jl only adds the Content-Type
automatically for POST
: https://github.com/JuliaWeb/HTTP.jl/blob/255a75907a06b1340e7deac659383f15f3aa55f0/src/MessageRequest.jl#L58-L61.
I added that code but didn’t know if it made sense for any other request types. You can probably make a PR and relax that to POST
or PUT
at least.
I added this, will be available in HTTP.jl 0.9.15.