Flashing message using Flask up task completion - python

I'm still new to Flask and I am trying to build a flask app that flashes status as and when tasks are complete
`
app.route("/", methods=['GET', 'POST'])
def root():
form = ReusableForm(request.form)
if request.method == 'POST':
name = request.form['name']
if form.validate():
Reports1 = RunReport1()
flash('Report 1 run successfully')
Report2 = RunReport2()
flash('Report 2 run successfully')
return render_template('run.html', form=form)'
However, there doesn't seem to be a way to flash messages without rendering the html page each time. Any assistance would be greatly appreciated. Thanks.

You can do it with Flask without roundtrip to the system. You have to use content streaming. For this you have to use stream_with_context for the response.
#app.route("/")
def root():
reports = ["Reports1", "Reports2"]
def generate_output():
for i in range(0, len(reports)):
report = reports[i]
template = '<p>{{ report }}.</p>'
context = {'report': report}
yield render_template_string(template, **context)
time.sleep(5)
return Response(stream_with_context(generate_output()))
So this will update the response till server side complete its tasks. Normally this is used for long running processes. Refer the documentation.
Hope this helps!

Related

How to separate flask app.route order of events

I have a small program that opens up an outlook email when a button is clicked on an html page. The problem is, I don't know the order of my app.route objects and the posted data from my html page.
My html (openemailJS.html):
my flask app:
import win32com.client
from flask import Flask, render_template, jsonify, json, url_for, request, redirect
import pythoncom, time, os, sys
app = Flask(__name__)
#app.route('/',methods = ['POST', 'GET'])
def index():
if request.method == 'POST':
emailid = request.args.get('nm')
time.sleep(1)
pythoncom.CoInitialize()
outlook = win32com.client.dynamic.Dispatch("Outlook.Application").GetNameSpace('MAPI')
inbox = outlook.GetDefaultFolder(6)
sentbox = outlook.GetDefaultFolder(5)
all_sentbox = sentbox.Items
all_inbox = inbox.Items
tryopen = outlook.GetItemFromID(emailid)
tryopen.display()
return render_template('openemailJS.html')
print(emailid)
else:
time.sleep(1)
emailid = request.args.get('nm')
#emailid = request.form.get('nm')
time.sleep(1)
pythoncom.CoInitialize()
outlook = win32com.client.dynamic.Dispatch("Outlook.Application").GetNameSpace('MAPI')
inbox = outlook.GetDefaultFolder(6)
sentbox = outlook.GetDefaultFolder(5)
all_sentbox = sentbox.Items
all_inbox = inbox.Items
tryopen = outlook.GetItemFromID(emailid)
tryopen.display()
print(user)
return render_template('openemailJS.html')
I think I need to separate the ' return render_template('openemailJS.html') 'into its own app.route('/something here/') but I don't know how to do that.
Currently, when I run it how it is, the emailid does not get posted before the def index(): runs, causing a 'parameter not found' where it should be. If I comment out everything but the 'return render_template', run the program, and then uncommment it out and click the button, then it gets posted as it should.
I added an if statement to retrieve the data only if the form is posted. I still think it makes sense to render the template first before doing anything, but I don't know.

How to Consume POST Rest API on Django Web? want to consume API of User registration in django and here is the code which i have done

In Views.py
this the code in view.py
def Save(request):
if request.method == "POST":
user=request.POST
email=user.get("email")
password=user.get("password")
print "password",password
display_name= request.POST.get('displayname')
hometown = request.POST.get('hometown')
gender = request.POST.get('radios')
occupation= request.POST.get('occupation')
services.post_register(email,password,display_name,gender)
in Service.py code is-
service.py
def post_register(email,password,display_name,gender):
postdata={'email':email,'password':password,'display_name':display_name,'gender':gender,'}
response = requests.post('http://www.example.com/rest-auth/users/1/',
data=json.dumps(postdata))
afer running this i am getting response 415. thank you
415 error code means that the media type is not supported. I think you can simply replace the json.dumps(postdata) by postdata. Looking at the requests library you don't need it:
r = requests.post('http://httpbin.org/post', data = {'key':'value'})

flask to execute other tasks after return render_template

In flask app, I need to execute other task's checkJob function (checking the job status and email to the the user) after executing return render_template(page). The user will see the confirm page but there is still background job running to check the job status.
I tried to use celery https://blog.miguelgrinberg.com/post/using-celery-with-flask for the background job and it does not work. Anything after return render_template(page) is not being executed.
Here's the code fragment:
#app.route("/myprocess", methods=['POST'])
def myprocess():
//.... do work
#r = checkJob()
return render_template('confirm.html')
r = checkJob()
#celery.task()
def checkJob():
bb=1
while bb == 1:
print "checkJob"
time.sleep(10)
As suggested in the comments, you should use apply_async().
#app.route("/myprocess", methods=['POST'])
def myprocess():
#.... do work
r = checkJob.apply_async()
return render_template('confirm.html')
Note that, as with the example, you do not want to invoke checkJob() but rather keep it like checkJob.

Flask / Heroku / Redis / RQ Internal Server Error

I have a recommendation site. Everything was working dandy, until at points when the site was under a decent amount of traffic, the recommendations would take longer than 30 seconds (Heroku's limit) and time-out, throwing a 500 error. I realize this is a very long time for a http request.
So, I read up online and implemented RQ with Redis. I got that to work, but after some testing, it will still throw the Internal Server Error, even though the requests are going through a queue.
I'm really just lacking knowledge here and I have no idea what to do. I think I'm missing the whole idea of rq and redis I guess? Here's some of my code if it helps, but I'm hoping for more of just guidance of where to go from here to fix this error.
worker.py
import os
import redis
from rq import Worker, Queue, Connection
listen = ['high', 'default', 'low']
redis_url = os.getenv('REDISTOGO_URL',
'redis://redistogo:sampleurl:portNo/')
if not redis_url:
raise RuntimeError('Set up Redis to go first.')
conn = redis.from_url(redis_url)
if __name__=='__main__':
with Connection(conn):
worker = Worker(map(Queue, listen))
worker.work()
part of my views.py
q = Queue(connection=conn)
#app.route('/')
def home():
form = ArtistsForm()
return render_template('home.html', form=form)
#app.route('/results', methods=['POST'])
def results():
form = ArtistsForm()
error = None
try:
if request.method == 'POST' and form.validate():
table = 'Artists'
artists = []
for value in form.data.items():
if (value[1] is not ''):
artists.append(value[1])
results = q.enqueue_call(func=getArtists, args=(table, *artists))
while results.result is None:
time.sleep(1)
results = results.result.values.tolist()
return render_template('results.html', results=results)
else:
error = "Please be sure to enter 5 artists with correct spelling" \
" and punctuation"
except pylast.WSError:
return render_template('error.html')
return render_template('home.html', form=form, error=error)
Any guidance is appreciated
You can always try dividing the work between a web dyno to simply acknowledge the request, then have worker dynos doing the heavy lifting.
Kafka or something similar could be used to accomplish this.

webbrowser.open('mailto:....') launches mail client in local execution environment but not on production server

I am using the following code to launch the e-mail client with pre-defined fields. The e-mail client launches as expected when I test on my local machine, but not on the production server. On the production server I simply get the redirect to '/'. Any suggestions on what could cause the e-mail client to launch? I tested on all browsers I, and did not see any difference in behaviour.
#app.route('/errorform', methods=['GET', 'POST'])
def errorform():
form = ErrorForm()
logs = str(open(file, "r").readlines()[int(file_len(file))]).rstrip()
if form.validate_on_submit():
if form.includeLogs.data == False:
webbrowser.open('mailto:test#mail.com?subject=Feedback&body=<insert your message here>')
return redirect('/')
else:
webbrowser.open('mailto:test#mail.com?subject=Feedback&body=<insert your message here> \n\n Logs: %s' % (logs))
return redirect('/')
return render_template('main.html', form=form, show_results=0, page = 'errorform')
Ok, since you've got an answer to the first question, here comes a suggestion to the second problem: just redirect to the mailto: URL:
#app.route('/errorform', methods=['GET', 'POST'])
def errorform():
form = ErrorForm()
logs = str(open(file, "r").readlines()[int(file_len(file))]).rstrip()
if form.validate_on_submit():
if form.includeLogs.data == False:
return redirect('mailto:test#mail.com?subject=Feedback&body=<insert your message here>')
else:
return redirect('mailto:test#mail.com?subject=Feedback&body=<insert your message here> \n\n Logs: %s' % (logs))
return render_template('main.html', form=form, show_results=0, page = 'errorform')
Worked For Me™ here.

Categories

Resources