Knopfi
Knopfi

Reputation: 19

Update image on python flask app using javascript

I'm trying to display an image on a simple website, which I am using Flask for. I already tried to do this using a js script on the website itself, but it didn't work. However, I do not know how to periodically update/refresh the image. I'm using html and javascript for the first time right now and I'm too confused to get it to work.

This is the main .py file:

from flask import Flask, render_template
import os

#sorry for the bad code :/

app = Flask(__name__)

@app.route("/")
def running():
    return "<p>Website running!</p>"


app.config['UPLOAD_FOLDER'] = os.path.join('static','images')

@app.route("/chart")
def show_img():
    full_filename = os.path.join(app.config['UPLOAD_FOLDER'], 'chart.png')
    return render_template("chart.html", user_image = full_filename)


if __name__ == "__main__":
    app.run(port=3000)

This is chart.html:

<!DOCTYPE html>
<html>
<body>
    <img src={{ url_for("static", filename="images/"+"chart.png" ) }}/>
</body>
</html>

What is the easiest way to update/reload the image every 5 seconds? The filename stays the same, but the image itself changes

Upvotes: 1

Views: 846

Answers (1)

Some notes:

  • When working inside a request, it is better to use current_app
from Flask import current_app

@app.route("/chart")
def show_img():
    # current_app.config
    full_filename = os.path.join('images', 'chart.png')
    return render_template("chart.html", user_image=full_filename)

We removed static as we'll be using static in the template itself.

  • Since you already have the user_image variable, you can add it to the file directly
<!DOCTYPE html>
<html>
<body>
    <img src={{ url_for("static", filename=user_image ) }}/>
</body>
</html>

This will display the image.

Dealing with uploads

If you want to implement uploads etc, use flask-reuploaded, a maintained fork of Flask-uploads.

On the front-end, you need a file upload form. Then you need a route to accept the uploaded file. Then you need to make sure that the uploaded filename is always the same, maybe by deleting existing files beforehand.

A complete demo

Following the official docs, here is a demo.

Folder structure

.
├── app.py
├── static
│   └── images
├── templates
    └── chart.html

chart.html

<!DOCTYPE html>
<html>
<body>
     <form method="post" enctype=multipart/form-data action="/upload">
      <input type="file" name="file">
      <input type="submit" value="Upload">
    </form>
    <br>

    <img src={{ url_for("static", filename=user_image ) }}/>
</body>
</html>

app.py

import os
from flask import Flask, flash, request, redirect, url_for, render_template
from werkzeug.utils import secure_filename

UPLOAD_FOLDER = '/path/to/the/uploads'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}

app = Flask(__name__)
current_file = ''

@app.route("/")
def running():
    return "<p>Website running!</p>"


app.config['UPLOAD_FOLDER'] = os.path.join('static','images')

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    global current_file
    if request.method == 'POST':
        # check if the post request has the file part
        if 'file' not in request.files:
            flash('No file part')
            return redirect(request.url)
        file = request.files['file']
        # If the user does not select a file, the browser submits an
        # empty file without a filename.
        if file.filename == '':
            flash('No selected file')
            return redirect(request.url)
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            current_file = filename
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return redirect(url_for('show_img', name=filename))

@app.route("/chart")
def show_img():
    filename = os.path.join('images', current_file)
    return render_template("chart.html", user_image=filename)


if __name__ == "__main__":
    app.run(port=3000)

Upvotes: 1

Related Questions