So I have a simple Flask app (no database connected) that needs to execute a function with arguments parsed via a form. This function processes large amounts of data (and takes a few minutes to do so), and it's divided in parts, after which, yields some strings. The idea is that while the function is running, these strings appear dinamically on a template. And I was able to make that, and when the app is hosted on a local server it functions correctly. But, when deployed to Google Cloud App Engine, it does not allow me to dinnamically output theses strings, instead, it waits till all the function was executed to output them. main.py
from flask import Flask, render_template, redirect, url_for, request, session, flash, Response
import requests
from jinja2 import Environment
from jinja2.loaders import FileSystemLoader
app = Flask(__name__)
app.secret_key = "123"
def my_function(arg1, arg2, arg3):
#Does something and defines string1
yield string1
#Does something else and defines string2
yield string2
#Does something else and defines string3
yield string3
@app.route('/', methods=['GET', 'POST'])
def home():
if request.method == 'POST':
arg1 = request.form.get('arg1')
arg2 = request.form.get('arg2')
arg3 = request.form.get('arg3')
env = Environment(loader=FileSystemLoader('templates'))
tmpl = env.get_template('result.html')
return Response(tmpl.generate(result = my_function(arg1, arg2, arg3)))
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
index.html
<form method="POST">
<input type="text" name="arg1">
<input type="text" name="arg2">
<input type="text" name="arg3">
<input type="submit">
</form>
result.html
<div>
{% for line in result %}
<p>{{ line }}</p>
{% endfor %}
</div>
app.yaml
runtime: python37
Terminal output after running $ python main.py and submitting form
"GET / HTTP/1.1" 200
"POST / HTTP/1.1" 200
and opens result.html while my_function() is running
Terminal output after deploying and running $ gcloud app logs read
https://i.sstatic.net/6lBIt.png
and stays on index.html till my_function() ends running and then opens result.html
As @DazWilkin said - App Engine does not support streaming. In addition, App Engine has a deadline of 1 minute for each request i.e. each call to App Engine as part of your standard app has to return within a minute
With respect to your issue, you can
It solves your problem but the results are not instantaneous - they are dependent on how often you poll your server.
If you really need real-time response and your application is significant or large then you'll have to look into PubSub but this won't run on app engine (as earlier mentioned). You'll have to go the route of Google Compute Engine (GCE)