TIL: File Uploads Using the Req Elixir Library

The Req Elixir library doesn’t support file uploads(as of version 0.4.5). Instead, you need to use multipart to construct the HTTP request before you send it.

Here is an example sending an mp3 file to the OpenAI audio transcription API(aka Whisper):

def transcribe_audio(file_path, token) do
    model = "whisper-1"
    filename = Path.basename(file_path)
    {:ok, file_contents} = File.read(file_path)

    multipart =
      Multipart.new()
      |> Multipart.add_part(Multipart.Part.text_field(model, "model"))
      |> Multipart.add_part(
        Multipart.Part.file_content_field(filename, file_contents, :file, filename: filename)
      )

    content_length = Multipart.content_length(multipart)
    content_type = Multipart.content_type(multipart, "multipart/form-data")

    headers = [
      {"authorization", "Bearer #{token}"},
      {"Content-Type", content_type},
      {"Content-Length", to_string(content_length)}
    ]

    Req.post(
      "https://api.openai.com/v1/audio/transcriptions",
      headers: headers,
      body: Multipart.body_stream(multipart)
    )
  end