How do I call render_template() once per minute flask - python-2.7

I am new to Flask. How do I call render_template('prices.html', stock_price) once every minute for a given page that is fed by constantly changing data?
I tried this:
throttle.Throttle(period=60) # 60 second throttle
while True:
stock_price = get_stock_price()
render_template('prices.html', stock_price=stock_price)
throttle.check() # Check if 60 seconds have passed otherwise sleep
The only thing that does work is return render_template(...). Apparently render_template() must be part of a return-statement. Unfortunately, once return is called the game is over.
How do I accomplish this? I'm assuming it is just ignorance on my part.

When you render the template you run the Flask process and return an HTML after the template file rendered, and as your said, you use return and the game is over.
Even if you will find a really hard-code way to do it, it's not a good way to do it. You will waste too much server calls and a user waiting time.
The easy way to do it
Writing a really simple Python function that return only the stock number(i guess you already have one - get_stock_price() )
But i would decorate it with a route(Lets say "/getprice"). Every one who will get to this page will get a black page but the stock price text.
Now for the real magic - use JQuery-AJAX on the HTML page to call this function:
$.ajax({
type: "POST",
url: "/getprice",
})
.done(function( price ) {
$("#price-box").val(price)
});
Hey but wait, what about my "once per minute"??
of curse we can insert this ajax call into setInerval() function like this:
setInterval(function() {
$.ajax({
type: "POST",
url: "/getprice",
})
.done(function( price ) {
$("#price-box").val(price)
});
}, 1000 * 60);
Tell me if you need any help with that.
The Pro way to do it
Ok, so you managed to send a request for your get_stock_price() function once per minute.
Great.
But what about performance?
I guess your get_stock_price() doing some other request or even some web scraping which, again, could be really hard for the server (think what going on when 10,000 users using this page).
What i would do is:
Store the data from get_stock_price() in your DB every minute(Cron Job would do the job), then when a user asks(AJAX request) for this data, pull it out of the DB.
This way the server will work on the background and the user won't see any different with his data loading speed.

Related

How to make a form save to the database every time it is edited in Django?

So I am trying to replicate the Google Docs functionality wherein every time you edit, the document will be saved. Will I be putting an onchange function on every input in the form then sending the data through ajax? How should I approach this or is this even feasible?
Note: I am just asking for some sort of pseudocode or simply the flow-chart of how I should do things.
I think that something like this should works:
jQuery(function($){
function changeFn(){
// make ajax save.
}
var timer;
$("#doc").bind("keyup", function(){
clearTimeout(timer);
timer = setTimeout(changeFn, 2000)
});
});
This will wait 2 seconds(you can try with 3 - 5 seconds) after the user press the last key, then will call the ajax function to save the content. I think that is better than save all the time when the user press a key. Note that if the user press a key before that time, the timeout will be interrupted and will initiate a new count.

peekRecord() is not working but peekAll() is working

My backend always responds with all available data and it took a considerably amount of time. So I'm reloading store periodically and I plan to use peekAll() and peekRecord().
My code is:
model: function() {
return Ember.RSVP.hash({
'clusters': this.store.peekAll('cluster'),
'single': this.store.peekRecord('cluster', 'cluster::My')
});
When code is executed, at first I can see that both of these items do not contain content. After few seconds data are loaded to store and I can see content 'clusters' on template as expected. But 'single' is still completely without content ({{model.single}} does not return nothing in template). But when I have a button with action:
alert(this.store.peekRecord('cluster', 'cluster::My'));
I can see that the record was found. Records are also available via Ember Inspector. What am I doing wrong that only peekAll() works in model for me.
The semantics of both methods are:
store.peekAll returns a live array that is updated as the store is updated.
store.peekRecord returns the corresponding object in the current cache, or null, and it does not update.
So the behaviour you're observing is the expected one. If you want to use the peek methods, my advise is to make sure that the initial request has finished loading before fetching any data from the store.

PyMongo find query returns empty/partial cursor when running in a Django+uWsgi project

We developed a REST API using Django & mongoDB (PyMongo driver). The problem is that, on some requests to the API endpoints, PyMongo cursor returns a partial response which contains less documents than it should (but it’s a completely valid JSON document).
Let me explain it with an example of one of our views:
def get_data(key):
return collection.find({'key': key}, limit=24)
def my_view(request):
key = request.POST.get('key')
query = get_data(key)
res = [app for app in query]
return JsonResponse({'list': res})
We're sure that there is more than 8000 documents matching the query, but in
some calls we get less than 24 results (even zero). The first problem we've
investigated was that we had more than one MongoClient definition in our code. By resolving this, the number of occurrences of the problem decreased, but we still had it in a lot of calls.
After all of these investigations, we've designed a test in which we made 16 asynchronous requests at the same time to the server. With this approach, we could reproduce the problem. On each of these 16 requests, 6-8 of them had partial results. After running this test we reduced uWsgi’s number of processes to 6 and restarted the server. All results were good but after applying another heavy load on the server, the problem began again. At this point, we restarted uwsgi service and again everything was OK. With this last experiment we have a clue now that when the uwsgi service starts running, everything is working correctly but after a period of time and heavy load, the server begins to return partial or empty results again.
The latest investigation we had was to run the API using python manage.py with DEBUG=False, and we had the problem again after a period of time in this situation.
We can't figure out what the problem is and how to solve it. One reason that we can think of is that Django closes pymongo’s connections before completion. Because the returned result is a valid JSON.
Our stack is:
nginx (with no cache enabled)
uWsgi
MemCached (disabled during debugging procedure)
Django (v1.8 on python 3)
PyMongo (v3.0.3)
Your help is really appreciated.
Update:
Mongo version:
db version v3.0.7
git version: 6ce7cbe8c6b899552dadd907604559806aa2e9bd
We are running single mongod instance. No sharding/replicating.
We are creating connection using this snippet:
con = MongoClient('localhost', 27017)
Update 2
Subject thread in Pymongo issue tracker.
Pymongo cursors are not thread safe elements. So using them like what I did in a multi-threaded environment will cause what I've described in question. On the other hand Python's list operations are mostly thread safe, and changing snippet like this will solve the problem:
def get_data(key):
return list(collection.find({'key': key}, limit=24))
def my_view(request):
key = request.POST.get('key')
query = get_data(key)
res = [app for app in query]
return JsonResponse({'list': res})
My very speculative guess is that you are reusing a cursor somewhere in your code. Make sure you are initializing your collection within the view stack itself, and not outside of it.
For example, as written, if you are doing something like:
import ...
import con
collection = con.documents
# blah blah code
def my_view(request):
key = request.POST.get('key')
query = collection.find({'key': key}, limit=24)
res = [app for app in query]
return JsonResponse({'list': res})
You could end us reusing a cursor. Better to do something like
import ...
import con
# blah blah code
def my_view(request):
collection = con.documents
key = request.POST.get('key')
query = collection.find({'key': key}, limit=24)
res = [app for app in query]
return JsonResponse({'list': res})
EDIT at asker's request for clarification:
The reason you need to define the collection within the view stack and not when the file loads is that the collection variable has a cursor, which is basically how the database and your application talk to each other. Cursors do things like keep track of where you are in a long list of data, in addition to a bunch of other stuff, but thats the important part.
When you create the collection cursor outside the view method, it will re-use the cursor on each request if it exists. So, if you make one request, and then another really, really fast right after that (like what happened when you applied high load), the cursor might only be half way through talking to the database, and so some of your data goes to the first request, and some to the second. The reason you would get NO data in a request would be if a cursor finished fetching data but hadn't been closed yet, so the next request tried to fetch data from the cursor, and there was none left to fetch in the query.
By moving the collection definition (and by association, the cursor definition) into the view stack, you will ALWAYS get a new cursor when you process a new request. You wont get any cross talking between your cursors and different requests, as each request cycle will have its own.

Django view called twice Firefox

EDIT: This question fixed my issue: What happens when no response is received for a request? I'm seeing retries
I have a weird issue. I have a Django application. The frontend has two forms. I submit the forms together via the same Ajax post method
// code to get and format form data to get into the format I need in the backend
var webURL = "showFormOutput";
$.post(webURL,
dataToSend,
callback
).fail(function(jqXHR, textStatus, errorThrown)
{
console.log("Status: " + textStatus);
console.log("Error: " + errorThrown);
});
In the Django view corresponding to that url, I do the following:
Print a message "View function" to log that I am in the view.
Parse the post data and put it into appropriate variables. Pass these variables to a Python function in a separate file. Let us call this function getQueryResults.
Create two Postgres queries (for two forms) using these variables. Print a log message "Query created".
Use Python's threading module to execute these two queries. I run the following line twice to create two separate threads for the two queries threading.Thread(target=threadFunction, args=(query,).start()
Log in the threadFunction "Query result ready" when the postgres query returns.
This is a long running query - takes up to ten minutes.
In Chrome, this works perfectly. However, in Firefox (and Safari too I think), I get the following issues:
When using Firefox, I can see in pg_stat_activity that two queries are running as expected. However, after about 5 minutes, there are FOUR queries running i.e. two more of the SAME query are started.
This is reflected in my logs also. I get the messages "View Function" and "Query Created" printed AGAIN. This means that somehow, the execution restarted from the view. This happens even on increasing the http.response.timeout to 30000.
Sometimes, Firefox just goes to the fail() case of the $.post and textStatus just says "Error" and errorThrown is blank. Sometimes, it prints my query results as expected but it waits for the second set of queries to finish. I thought it might be an issue with my Python threads but it makes no sense to have the whole view executed again since the threads never call the view anywhere! On the client side, the POST request doesn't seem to be sent again.
Notes: I am using django's filesystem-based cache to cache the query results. Could this be an issue? The second duplicate set of queries turn up even before the first actual set return results so I doubt this is the issue though.
Has anyone got any idea why using Firefox would result in my view being called twice?

Django iterate through a list of webpages

Hi I'm relatively new to python and DJANGO and was wondering if there was a way to load a webpage from a currently loaded webpage after a time delay
For example i have 5 or 6 graphs/charts on separate pages within my django project and want them to be displayed for 5-10 seconds then switch to the next one
I may be just missing something simple here but any help would be appreciated
If you expect them to submit the form within 30 seconds then a meta-refresh is quite a simple way to achieve that.
Otherwise you can use a javascript redirect that fires after a delay. The redirect would check that no action (such as filling out the fields) has been performed during the delay. Something like:
setTimeout(function() {
if (noChange) {
window.location = "http://www.yoururl.com";
}
}, 30 * 1000);
You should use javascript to do that:
$(function(){
setTimeout(checkUserStatus, 30000);
})
function checkUserStatus(){
//Code to check if user hit/click anything
//if yes clear TimeInterval and do the operation
//If no clear Time Interval and redirect to home page
}