flaskstoragepytubestoring-data

Download a file without storing it


I'm building a Youtube Video Downloader using PyTube and Flask. What I want to do is the end user receives the video file, but I never store it into the server.

Currently the code looks like this:

def download_video():
if request.method == "POST":
    url = YouTube(session['link']) # Getting user input
    itag = request.form.get("itag") # Getting user input
    video = url.streams.get_by_itag(itag) 
    file = video.download(path) # Downloading the video into a folder
    return send_file(file, as_attachment=True) 
return redirect(url_for("home"))

The code works fine, the only drawback is that it is being store into the server, which later on can become an issue.

I already tried to download it to /dev/null/, which locally seems to work, but when deployed to Heroku, it gives me an Internal Server Error.


Solution

  • The download method is used to:

    Write the media stream to disk.

    A dirty workaround could of course be to remove the file saved at the output_path after calling download, but you could also write the media stream to a buffer using stream_to_buffer and send that.

    Minimal and reproducible example

    from pytube import YouTube
    from flask import Flask, send_file
    from io import BytesIO
    
    app = Flask(__name__)
    
    
    @app.route("/")
    def index():
        buffer = BytesIO()
        url = YouTube("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
        video = url.streams.get_by_itag(18)
        video.stream_to_buffer(buffer)
        buffer.seek(0)
    
        return send_file(
            buffer,
            as_attachment=True,
            attachment_filename="cool-video.mp4",
            mimetype="video/mp4",
        )
    
    
    if __name__ == "__main__":
        app.run()