python-3.xflaskflask-sqlalchemyflask-restful

How do you return a file from an API response flask_restful?


I Have two API's one is basically for generating PDF's basing on the data sent.

This first API endpoint below

http://localhost:5000/api/sendReceiptData

Returns a PDF file as an attachment.

The second API will consume the first API and should return a PDF as an attachment in the response. I have tried it out but I get this error TypeError: Object of type bytes is not JSON serializable

How can I therefore return a file response from the first API within this second API


EDIT: I have this same specific scenario and adding this edit since the question was marked as duplicate/closed. The link to the duplicate question shows how to serve a file that you already have stored locally. But I wanted a way to serve the file from memory as soon as it was retrieved from the first API call because I do not want the file stored on the webserver. The file in my scenario can be any format including audio, doc, pdf, image, etc. Here is how I was able to do this:

# Make GET call to API to retrieve file in response
response = requests.get(url, auth=(user, pwd), headers=headers, stream=True)
response.raw.decode_content = True

# Forward json error received from failed GET call
if response.status_code != 200:
    return {**response.json()}, response.status_code

# Forward raw file received from successful GET call 
return send_file(response.raw, attachment_filename=file_name, as_attachment=True)

Solution

  • You need to use send_file method to return pdf file

    import os
    from flask import Flask, make_response, send_file
    from werkzeug.utils import secure_filename
    
    app = Flask(__name__)
    PDF_FOLDER = '/path/to/pdf/folder'  # Replace with the path to your PDF folder
    
    @app.route("/pdf/<string:filename>", methods=['GET'])
    def return_pdf(filename):
        try:
            filename = secure_filename(filename)  # Sanitize the filename
            file_path = os.path.join(PDF_FOLDER, filename)
            if os.path.isfile(file_path):
                return send_file(file_path, as_attachment=True)
            else:
                return make_response(f"File '{filename}' not found.", 404)
        except Exception as e:
            return make_response(f"Error: {str(e)}", 500