Flask send_file not sending file

As Rob Bricheno said,

You need to return the result of send_file

So you can save the result of "flask.send_file", then clean up, then return the result.

print("sending file...")
result = send_file("dl/"+video_title+".f137.mp4", as_attachment=True)
print("file sent, deleting...")
os.remove("dl/"+video_title+".f137.mp4")
return result

Extending @Rob Bricheno's answer, if you need to clean up after the request, you can create a deferred method that will execute after the request is complete:

@app.route('/', methods=["GET", "POST"])
def index():
    if request.method == "POST":
        link = request.form.get('Link')
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            info_dict = ydl.extract_info(link, download=False)
            video_url = info_dict.get("url", None)
            video_id = info_dict.get("id", None)
            video_title = info_dict.get('title', None)
            ydl.download([link])
        print("sending file...")
        response = send_file("dl/"+video_title+".f137.mp4", as_attachment=True)
        # Create handle for processing display results (non-blocking, excecutes after response is returned)
        @flask.after_this_request
        def add_close_action(response):
            @response.call_on_close
            def process_after_request():
                try:
                    print("file sent, deleting...")
                    os.remove("dl/"+video_title+".f137.mp4")
                    print("done.")
                except Exception as e:
                    logger.exception(str(e))
        return response
    else:
        return render_template("index.html", message=message)

You need to return the result of send_file:

@app.route('/', methods=["GET", "POST"])
def index():
    if request.method == "POST":
        link = request.form.get('Link')
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            info_dict = ydl.extract_info(link, download=False)
            video_url = info_dict.get("url", None)
            video_id = info_dict.get("id", None)
            video_title = info_dict.get('title', None)
            ydl.download([link])
        print("sending file...")
        return send_file("dl/"+video_title+".f137.mp4", as_attachment=True)
    else:
        return render_template("index.html", message=message)

Unfortunately, this will make it harder for you to "clean up" after sending the file, so you probably want to do that as part of scheduled maintenance (e.g. run a cron job to delete old downloaded files). See here for more information about the problem.