I am trying to write a file sharing application that exposes a REST interface.
The library I am using, Flask-RESTful only supports returning JSON by default. Obviously attempting to serve binary data over JSON is not a good idea at all.
What is the most "RESTful" way of serving up binary data through a GET method? It appears possible to extend Flask-RESTful to support returning different data representations besides JSON but the documentation is scarce and I'm not sure if it's even the best approach.
The approach suggested in the Flask-RESTful documentation is to declare our supported representations on the Api object so that it can support other mediatypes. The mediatype we are looking for is application/octet-stream
.
First, we need to write a representation function:
from flask import Flask, send_file, safe_join
from flask_restful import Api
app = Flask(__name__)
api = Api(app)
@api.representation('application/octet-stream')
def output_file(data, code, headers):
filepath = safe_join(data["directory"], data["filename"])
response = send_file(
filename_or_fp=filepath,
mimetype="application/octet-stream",
as_attachment=True,
attachment_filename=data["filename"]
)
return response
What this representation function does is to convert the data, code, headers
our method returns into a Response
object with mimetype application/octet-stream
. Here we use send_file
function to construct this Response
object.
Our GET
method can be something like:
from flask_restful import Resource
class GetFile(Resource):
def get(self, filename):
return {
"directory": <Our file directory>,
"filename": filename
}
And that's all the coding we need. When sending this GET
request, we need to change the Accept
mimetype to Application/octet-stream
so that our API will call the representation function. Otherwise it will return the JSON data as by default.
There's an xml
example on github
I know this question was asked 7 years ago so it probably doesn't matter any more to @Ayrx. Hope it helps to whoever drops by.
As long as you're setting the Content-Type
header accordingly and respecting the Accept
header sent by the client, you're free to return any format you want. You can just have a view that returns your binary data with the application/octet-stream
content type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With