4

For a while now I am trying to learn how to use Ajax with Flask. On the official website of flask there is an example:

from flask import Flask, jsonify, render_template, request
app = Flask(__name__)

@app.route('/_add_numbers')
def add_numbers():
    a = request.args.get('a', 0, type=int)
    b = request.args.get('b', 0, type=int)
    return jsonify(result=a + b)

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

It works for me well. But I am looking for the following program:

  1. a jQuery code sends an initial number to the python app
  2. the python app stores the number and responds 'received: [the number]'
  3. while true: the python app waits for requests 'increase' for which it adds 1 to the number and returns it

The jQuery part doesn't matter, I can do that but I am not sure how to implement the python part:

@app.route('/_inc_number')
def inc_number():
    n = request.args.get('n', 0, type=int)
    while true:
        req = request.args.get('req', 0, type=string)
        if req == 'increase':
            n = n + 1
            return n #It exits the function. how respond without quit?

Please explain me how I can data back? I am new to both Ajax and Flask too, and I suspect that it is not "real" ajax...Is that right? How would you implement a simple function with the same functionality in flask?

2 Answers 2

4

I think what you are missing is that each time the client requests a number increase there is an independent request. Your inc_number handler would be coded as follows:

@app.route('/_inc_number')
def inc_number():
    n = request.args.get('n', 0, type=int)
    n = n + 1
    return n

Then from the jQuery side you have to invoke an independent Ajax request each time you want to increase the number.

Note that with this type of solution the jQuery app is the one that keeps track of the current value of the counter, and it has to send it to Flask with each request. Another possibility would be to have the Flask side remember the number in a user session. For that type of solution your Flask app would have two view functions:

from flask import session
# you need to set a SECRET_KEY in configuration, used to sign the user session

@app.route('/set_number')
def set_number():
    # store n in the user session
    session['n'] = request.args.get('n', 0, type=int)

@app.route('/inc_number')
def inc_number():
    session['n'] = session['n'] + 1
    return session['n']

With this solution now jQuery can set the number and not have to send it every time when it invokes inc_number.

I hope this helps.

Sign up to request clarification or add additional context in comments.

3 Comments

yes, that helps a lot, thanks, however I still have some questions: how long does this program is going to run? Can it still serve other clients? What do I need to do with the SECRET_KEY?
This is a web server, it runs until you stop it. The web server listens to connections from any client, not a specific one. A request is short lived, once the server handles one request it forgets about it and is ready to receive another, from the same or a different client. You could have one or one hundred clients, all asking the server to increment the number, and the server will handle each independently of the rest. And each client will have its own counter, of course.
The SECRET_KEY is just configuration, Flask uses it to add a cryptographic signature to the user session, so that the contents cannot be tampered with. This is because typically user sessions contain authentication information, stuff that you don't want an attacker to be able to forge. All you need to do is define your SECRET_KEY in the configuration, Flask does the rest. Each application should have a different key, and the key that you choose should never be made public.
1

HTTP requests don't have a memory, they are independent of each other. It means when your Python app gets a request, it does something, sends a response immediately and quits. That's the nature of HTTP.

If you want something persistent (like your number) that lives through more requests, you need:

  • Persistent storage on the server. It can be a file, a database, or in case of Flask simply an object (variable) in memory.
  • Identify the user between separate requests. That's what session handling and cookies are for.

A very primitive method (shouldn't be used on production system):

  • persistent storage: create a global dict (called num) in main()
  • in index():
    • create a random session identifier (si)
    • set num[si] = 0
    • send si as a cookie
  • in inc_number() use si from cookie (sent back by the browser) to increase the appropriate num[si]

2 Comments

szepnapot, but there are various chat applications using Ajax; is this HTTP request thing different from that? How do I implement >real< Ajax connection in python?
Ajax uses HTTP. "Normally" your browser sends an HTTP request by typing a url and hitting Enter, or by clicking a link. Ajax does the same, but in the background. There's no difference between the two cases: both send HTTP requests. What I described as a "primitive method" can be used with or without Ajax, it's your choice. Some chat applications use long polling which is leaving the connection open for a longer time. But you cannot leave it open indefinitely, so eventually you need persistance and session handling.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.