Send file with HTTP.post

Hi everyone,

I’m looking to upload files via an API using Julia with the HTTP.jl package. Unfortunately, the API can’t retrieve my file, and I get an error:

{“code”:500,“message”:“Unable to retrieve file from request.”,“payload”:}

Here is my code (the API key is a public one for the public test API, anyone can try ;))

using HTTP

url = "https://apitest.nakala.fr/datas/uploads"

headers = 
    Dict(
        "X-API-KEY" => "01234567-89ab-cdef-0123-456789abcdef", 
        "accept" => "application/json"
    )

fileOpened = open(PATH_TO_THE_FILE, "r")    

fileCur = Dict("file" => fileOpened)

response = HTTP.post(url, files=fileCur, headers=headers)

I wrote a similar script with Python and everything seems to work:

import requests

url = "https://apitest.nakala.fr/datas/uploads"

headers = {"X-API-KEY":"01234567-89ab-cdef-0123-456789abcdef", "accept": "application/json"}

fileOpened = open(PATH_TO_THE_FILE, "rb")    

fileCur = {'file': fileOpened}

response = requests.post(url, files=fileCur, headers=headers)

print(str(response.text))

The (good) response from the server:

{“name”:“myFile.txt”,“sha1”:“35b7740a641464a2dfecd282ba0592a8a23f65a3”}

I must have made a mistake with objects sent with HTTP.post but I don’t know how to fix it… Does anyone have any ideas?

Thanks a lot!!
Josselin

HTTP.jl’s API is different from Python’s requests. In particular, HTTP.request (post is a convenience method for request), doesn’t know the keyword arguments files and headers.

Instead it is called as HTTP.post(url, headers, body).

I believe something like

body = HTTP.Form(Dict(:file => fileOpened))

would do the trick. See API Reference · HTTP.jl

Your headers seem fine, but maybe you need to declare

Content-Type => multipart/form-data

No guarantees though, I’m not an expert.

1 Like

@skleinbo thank you very much for your help, it works perfectly!!

That’s great! If you are happy with my answer, and feel like your problem is fully resolved, please mark it as the solution.

1 Like

Here is another scenario as an example for other Oxigraph users. I wanted to translate the following curl command from the Oxigraph documentation into a call to HTTP.post()
curl -X POST -T my-turtle-file.ttl -H 'Content-Type: text/turtle' "http://127.0.0.1:7878/store?default"
This worked for me:

url = "http://127.0.0.1:7878/store?default"
headers = ["Content-Type" => "text/turtle"]
body=read("my-turtle-file", String)
HTTP.post(url, headers=headers, body=body)