I am building a small Flask app in Windows 11. In my app, I take a string from a user, convert it to a text file, and send the user that text file in a subfolder of 'static'. However, the key thing I want to do is send that file as an anchor tag that downloads on clicking.
I want the download link to appear as a clickable link on the original webpage (that is have a one page site that doesn't reroute), and I do not want to send a direct download (Flask's send_file function).
My Flask App (app.py):
#Package Imports
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
import random
#Create Flask Form
#Create the Flask form here.
class MyForm(FlaskForm):
    text_field = StringField('Write here.', validators=[DataRequired()])
    submit_field = SubmitField('Submit')
#This function makes a text file with the user's text.
def make_text_file(my_string):
    filename = 'static/text_files/{}.txt'.format(random.randint(1, 1000000))
    with open(filename, 'w') as file:
        file.write(my_string)
    return '/'.join(filename.split('/')[1:])
#Create the Flask app here.
app = Flask(__name__)
app.config['SECRET_KEY'] = 'ABCDEFG'
@app.route('/', methods=['GET', 'POST'])
def index():
    result = False
    form = MyForm()
    
    if request.method == 'POST':
        text = request.form['text_field']
        result = make_text_file(text)
        return render_template('index.html', form=form, result=result)
    
    return render_template('index.html', form=form, result=result)
My HTML Jinja2/Template (index.html):
<html>
    <body>
        <form method="POST" action="{{ url_for('index') }}">
            <div class='form-div'>
                {{ form.csrf_token }}
                <div>{{ form.text_field }}</div>
                <div>{{ form.submit_field }}</div>
            </div>
        </form>
        
        <div id='result-link'>
            {% if result == False %}
                <div></div>
            {% else %}
                <a href="{{ url_for('static', filename=result) }}" download>Here is your file.</a>
            {% endif %}
        </div>
    </body>
</html>
I have tried the following solutions but they did not work:
- I used the @after_this_request decorator from Flask, but since my route function handles both 'GET' and 'POST' requests, how do I specify that a specific function (namely deleting the file) should happen after a 'POST' request? To my knowledge, this solution only works in Linux. While I do plan on serving the end website in a Linux server, is there a way to test the filed deletion mechanism in Windows?
- I tried WebSockets, namely Flask-SocketIO, and incorporated this into my code as well. However, I receive a "The WebSocket transport is not available, you must install a WebSocket server that is compatible with your async mode to enable it. See the documentation for details. (further occurrences of this error will be logged with level INFO)". I am running a Flask development server in the virtual environment and am unsure how to set up a production server to test whether the WebSocket strategy works.
- While the example I provide is text files, I eventually want to be able to serve video files to clients. Would reading the file into memory, per the solution here be a feasible solution?
 
    