Jinja not rendering in the HTML file which contains a button for redirecting

I tried to build a webhook using the Python Flask framework. The app_producer.py file (client) sends HTTP POST requests, and the app_consumer.py file (server) processes requests sent by the app_producer.py file.

app_consumer.py

from flask import render_template, Response, request
from flask_socketio import join_room
from init_consumer import app, socketio
import tasks_consumer
import uuid

# Render a template with a given context as a stream and return a TemplateStream
def render_template_stream(template_name, **context):
    app.update_template_context(context)
    t = app.jinja_env.get_template(template_name)
    rv = t.stream(context)
    rv.enable_buffering(5)
    return rv

# Registers a function to be run before the first request to this instance of the application
# Create a unique session ID and store it within the application configuration file
@app.before_request
def initialize_params():
    if not hasattr(app.config,'uid'):
        sid = str(uuid.uuid4())
        app.config['uid'] = sid
        print("initialize_params - Session ID stored =", sid)

# Render the assigned template file
@app.route("/", methods=['GET'])
def index():
    return render_template('consumer.html', stockSheet = {})
       
@app.route('/consumetasks', methods=['GET','POST'])
def get_stock_status():
    # Handle the POST request
    if request.method == 'POST':
        print("Retrieving stock status")
        return Response(render_template_stream('consumer.html', stockInfo = tasks_consumer.sendStockStatus()))     
    # Handle the GET request
    elif request.method == 'GET':
        return '''
         <!doctype html>
        <html>
            <head>
                <title>Stock Sheet</title>
                <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
            </head>

            <body class="container">
                <h1>Stock Sheet</h1>
                <div>
                    <button id="consumeTasks">Check stock status</button>
                </div>
            </body>
        </html>
        '''

# Run using port 5001
if __name__ == "__main__":
    socketio.run(app,host='localhost', port=5001,debug=True)

The tasks_consumer.py file that the app_consumer.py file imports:

import csv
from flask import request
from init_consumer import app, socketio
import json

# Receive the webhook requests and emit a SocketIO event back to the client
def send_message(data):
    status_code = 0
    if request.method == 'POST':
        roomid = app.config['uid']
        msg = json.dumps(data)
        event = "Send_stock_status"
        socketio.emit(event, msg, namespace = '/collectHooks', room = roomid)
        status_code = 200
    else:
        status_code = 405 # Method not allowed
    return status_code
    
# Retrieve the stock status of the products sent through the webhook requests and return them back to the client. 
@app.route('/consumetasks', methods=['POST'])
def sendStockStatus():
    request_data = request.get_json()
    stockList = [] # List of products in stock
    stockInfo = [] # List of products sent in the request
    stockSheet = {} # Dictionary of products sent in the request and their stock status
    with open("NZ_NVJ_Apparel_SKUs_sheet.csv", newline='') as csvFile:
        stockReader = csv.reader(csvFile, delimiter=',', quotechar='"')
        for row in stockReader:
            stockList.append(row[0])
    
    if request_data:
        if 'SKU' in request_data:
            stockInfo = request_data['SKU']
            for stock in stockInfo:
                if stock in stockList:
                    stockStatus = "In Stock"
                    stockSheet.update({str(stock):stockStatus})
                    yield stock, stockStatus
                else:
                    stockStatus = "Out of Stock"
                    stockSheet.update({str(stock):stockStatus})
                    yield stock, stockStatus
    send_message(stockSheet)
    print(stockSheet)

The consumer.html Jinja template file that I wanted to render:

<!doctype html>
<html>
  <head>
    <title>Stock Sheet</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  </head>

  <body class="container">
    <h1>Stock Sheet</h1>
    <div>
      <button id="consumeTasks">Check stock status</button>
      <script>
        document.getElementById("consumeTasks").onclick = function(){
          location.href = "http://localhost:5001/consumetasks";
        };
      </script>
    </div>

    <div id="stockSheet"> </div>
    <script>
        {% for stock in stockInfo %}
            {% if loop.index0 is even %}
                var SKU = "{{stock}}";
                document.getElementById("stockSheet").innerHTML += ("Product " + SKU);
            {% elif loop.index0 is odd %}
                var stockStatus = "{{stock}}";
                document.getElementById("stockSheet").innerHTML += (" is " + stockStatus + "<br>");
            {% endif %}
        {% endfor %}
   </script>
    
  </body>
</html>

In the consumer.html file, I used a <button> element to redirect the page from localhost:5001 to localhost:5001/consumetasks, so that the code in the Jinja template can be rendered. However, when I ran both the app_producer.py and app_consumer.py files to render the consumer.html template file and clicked the button on the localhost:5001 page, the contents inside the Jinja for loop failed to render.

When I checked the source code for the page localhost:5001/consumetasks, I found its source code was exactly the same as the code returned by the elif branch in the get_stock_status() function in app_consumer.py. I thought the problem was that the if branch in the get_stock_status() function in app_consumer.py was never executed. How can I fix my code so that the Jinja for loop in the consumer.html template can be rendered correctly?

Hi @yuanlintech ,

TLDR (The code)

Do you receive any error message ?

Could extract/post the part of code that doesn’t work ? (to not have to read all the code :slight_smile: )

Can you render the Jinja template with something like

#in Flask

@app.route('/test')
  def test():
    render_template('PathTo/consumer.html', stock=WhatEver)

Cheers