I’m using Oxygen.jl to implement an endpoint that retrieves data, processes it, and creates a DataFrame. I’d like the /dataframe
POST method to return a downloadable file named test.csv
containing the DataFrame. I tried adding Content-Disposition: attachment; filename="test.csv"
to the headers of the HTTP response in the handler, but it didn’t work.
Here’s some sample code that mimics the situation:
using CSV
using DataFrames
using HTTP
using Oxygen
# Create a sample DataFrame
df = DataFrame(
Name = ["Alice", "Bob", "Charlie"],
Age = [25, 30, 35],
City = ["New York", "Los Angeles", "Chicago"]
)
# Define the endpoint to return the DataFrame as a downloadable CSV file
@post "/dataframe" function (req::HTTP.Request)
io = IOBuffer()
CSV.write(io, df)
seekstart(io)
return HTTP.Response(
200,
[
"Content-Type" => "text/csv",
"Content-Disposition" => "attachment; filename=\"test.csv\"",
],
io,
)
end
# Start the Oxygen server
serve()
Does anyone have suggestions for how to force the download as a file or know why this approach isn’t working?
I copied/pasted your code and changed @post
to @get
and it works just fine when visiting localhost:8080/dataframe in my browser. If I define it to accept POST requests (i.e., leaving your code as is), I can hit the same URL in Postman and it returns the .csv data. Are you getting an error, or what’s the problem exactly? If you are trying to just put localhost:8080/dataframe in the address bar of your browser, you will need to redefine it with @get
.
Thanks for your reply! I forgot to change the method to GET in the example. Originally, I was passing some parameters in the request body to create a DataFrame dynamically, so I used the POST method.
However, when I test the endpoint on the Swagger page created by Oxygen, or if I use Postman or a curl
command in the terminal, I only get the contents of the DataFrame displayed in the response section (Swagger/Postman) or printed in the terminal. What I’m looking for is for the test.csv
file to be directly downloaded, without having to save it manually.
Right now, if I press the Save Response
button in Postman, it opens a window to select the path to save it as test.csv
. Is there a way to make the file download automatically instead of just showing the content in the response?
I think you would have to write some additional code to write the contents of the file to your local disk. So after you make the request, I think you could just do something like:
response = HTTP.get(url)
if response.status == 200
open(filename, "w") do file
write(file, response.body)
end
else
# handle other cases
end
In the browser, user interaction will always be necessary (a browser is never going to allow a site to save files to the user’s machine without their knowledge/consent).
Correct. I was hoping that if I used the Swagger page, the browser would prompt me to download the file and then proceed with the download automatically.