How to handle multi users' requests separately in Flask?

Viewed 10082

I've written the following flask server:

from flask import Flask, render_template, request
import os

app = Flask(__name__)
# home
@app.route('/')
def home():
    return 'HOME PAGE'

@app.route('/add')
def add():
    global a
    a += 1
    return str(a)

if __name__ == '__main__':
    a = 0
    HOST = '10.10.10.10'
    PORT = 5555
    app.run(HOST, PORT)

Considering there are two users (from different IP addresses) of my server: A and B. When user A requests by url 10.10.10.10:5555/add, he gets the result 1. After that, if user B requests by url 10.10.10.10:5555/add he will get 2. Because two users share the same variable a

However, I want my server to handle A and B separately which means a user A and B have a variable a in their own way. The requests of A shouldn't affect the result that B will get. For example, When user A requests, he gets 1. After that user B requests and he should get 1 as well.

How should I modify my code to achieve this?

3 Answers

Based on your question, I think you're confused about the definition of "global".

In Flask, you have a Flask server with multiple threads and potentially multiple processes handling requests. you had a global variable a, and you wanted to keep adding to it in every request and want a variable to be independent.This is totally possible in theory and practice. It's also a really bad idea. This case actually create Deadlocks

The problem is that you can't easily control which threads and processes "win"

You should keep the webserver itself as stateless as possible. Each request should be totally independent and not share any state in the server. Instead, use a database or caching layer which will handle the state for you. This seems more complicated but is actually simpler in practice. Check out SQLite for example ; it's pretty simple.

Thanks to @n00dl3 's suggestion, I've managed to achieve the goal of my example. Here is the code:

from flask import Flask, render_template, request, session
import os
from datetime import timedelta

app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days = 7)

# login
@app.route('/<username>', methods=['GET', 'POST'])
def home(username):
    if username in session:
        print(session.keys())
        return 'hello {}'.format(username)
    else:
        session[username] = username
        # generate this user's variable
        a[username] = 0
        print(session.keys())
        return 'login as {}'.format(username)

# logout
@app.route('/logout/<username>', methods=['GET', 'POST'])
def logout(username):
    session.pop(username)
    print(session.keys())
    return '{} logout!'.format(username)

# call add function with specific username
@app.route('/add/<username>')
def add(username):
    global a
    a[username] += 1
    return str(a[username])


if __name__ == '__main__':
    a = {}
    #HOST = environ.get('SERVER_HOST', 'localhost')
    HOST = '10.10.50.23'
    try:
        PORT = int(os.environ.get('SERVER_PORT', '5555'))
    except ValueError:
        PORT = 5555
    app.run(HOST, PORT, debug=True)

However, I'm not sure if my way is a decent solution. So still listen to any better answers.

Related