skip to Main Content

I am trying to create an image recogniton program and so far I have made the model and all of the actual AI aspect of things. However, when it came to implementing this into a website, I have been having lots of unexpected troubles when I’m trying to display a prediction on another web-page using Python Flask.

For instance, whenever I click on upload after choosing my image, it just opens a new web-page with the directory of the image and project files where I can navigate the files/folders. It should just be a container with the prediction and some text.

I am quite new to this style of programming so I’m not sure how to solve the bugs as of now, so any help would be greatly appreciated. I have linked a photo of the current project directory structure.

enter image description here

Here is my Python Flask code

@app.route('/')
def index():
    return render_template('html/enter_p.html')

@app.route('/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return redirect(request.url)
    file = request.files['file']
    if file.filename == '':
        return redirect(request.url)
    if file:
        # Save the file
        file_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
        file.save(file_path)
        # Redirect to the prediction page
        return redirect(url_for('predict', filename=file.filename))

@app.route('/predict/<filename>')
def predict(filename):
    # Load your model and make a prediction
    result = model.predict(os.path.join(app.config['UPLOAD_FOLDER'], filename))  # Replace with your prediction logic
    return render_template('results.html', prediction=result, filename=filename)

if __name__ == '__main__':
    app.run(debug=True)

Here is my results html code:

    <div class="container">
        <h1>Prediction Result: {{ prediction }}</h1>
        <img src="{{ url_for('static', filename='uploads/' + filename) }}" alt="Uploaded Mole Image" width="300px">
        <br>

And if necessary, here is my upload form:

            <form action = "../static/uploads/" method = "post" enctype = "multipart/form-data">
                <input type = "file" name = "file" accept = "image/*" required>
                <button type = "submit">Upload</button>
            </form>

3

Answers


  1. Chosen as BEST ANSWER

    I think the exact same issue is going on here and I suspect that this is a much simpler case so it would help to understand what goes wrong here, so that I can try and apply a similar fix to the original issue.

    Essentially, the link in <a href="{{ url_for('index') }}">>Upload another image</a> via the flask code below isn't working. I have a image of my directory in the above question.

    @app.route('/')
    def index():
        return render_template('../html/first_page.html')
    

    Any ideas on what is going wrong?


  2. Here’s what you can do:-

    Remove action from the form and add onsubmit where you can handle your upload logic. This will keep your page in the same tab and post your image to the backend.

    function submitHandler(e) {
     e.preventDefault();
     // Code to manage file upload
    }
    
    <form action="" onsubmit="submitHandler()/>
    
    Login or Signup to reply.
  3. I have changed your code slightly and combined the two routes index and upload_file into one. Since the form is now sent to the same address from which the form is retrieved, it is no longer necessary to set the action attribute of the form.

    Another advantage is that the lines redirect(request.url) send a GET request to the address used, which is not possible with your POST variant because it does not accept GET.

    ./app.py
    from flask import (
        Flask, 
        redirect, 
        render_template, 
        request, 
        url_for
    )
    import os
    
    # ...
    
    app = Flask(__name__)
    app.config.from_mapping(
        UPLOAD_FOLDER=os.path.join(app.static_folder, 'uploads')
    )
    os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
    
    @app.route('/', methods=['GET', 'POST'])
    def index():
        if request.method == 'POST':
            if 'file' not in request.files:
                return redirect(request.url)
            file = request.files['file']
            if file.filename == '':
                return redirect(request.url)
            if file:
                # Save the file
                file_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
                file.save(file_path)
                # Redirect to the prediction page
                return redirect(url_for('predict', filename=file.filename))
        return render_template('index.html')
    
    @app.route('/predict/<path:filename>')
    def predict(filename):
        result = model.predict(os.path.join(app.config['UPLOAD_FOLDER'], filename)) 
        return render_template('results.html', prediction=result, filename=filename)
    
    # ...
    
    ./templates/index.html
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Index</title>
    </head>
    <body>
        <form method="POST", enctype="multipart/form-data">
            <input type="file" name="file" accept="image/*" required>
            <button type="submit">Upload</button>
        </form>
    </body>
    </html>
    
    ./templates/results.html
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Predict</title>
    </head>
    <body>
        <div class="container">
            <h1>Prediction Result: {{ prediction }}</h1>
            <img src="{{ url_for('static', filename='uploads/' + filename) }}" alt="Uploaded Mole Image" width="300px">
            <br>
            <a href="{{ url_for('index') }}">Upload another image</a>
        </div>
    </body>
    </html>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search