Search code examples
pythonflaskcounterflask-session

Flask Counter for a Game


I'm creating a game on Flask and want to have a counter across the entire session. I put together some psuedo code for the general outline of the project. Basically it's a script that pulls a random question from a database, collects user input, returns the correct answer, and then starts over again at the user input route. I want to add a counter that will appears regardless of the function of route. I looked into Flask sessions, but it was confusing where or how to implement... any thoughts/ suggestions? Sessions or otherwise?

get_db_info():
    connects to a database

@app.route('/questions')
def user_input():
    collects user input and puts into variable

@app.route('/answers')
def results():
    if user input = results:
        print(correct!)
    elif:
        print(incorrect)
    renders back to user_input()

Solution

  • You already mention sessions, I think they are the solution to your problem:

    Flask-Session is an extension for Flask that adds support for Server-side Session to your application.

    Here is an example of doing this with a session. It stores three counters, one for total accesses to the app and two for accesses to individual routes. If you call /A three times and then /B, it will give you

    accessed B 1 times, accessed app 4 times

    from flask import Flask, session
    from flask_session import Session
    
    app = Flask(__name__)
    # Check Configuration section for more details
    SESSION_TYPE = 'filesystem'
    app.config.from_object(__name__)
    Session(app)
    
    @app.route('/')
    def reset():
        session["counterA"]=0
        session["counterB"]=0
        session["counterTotal"]=0
    
        return "all counters were reset"
    
    @app.route('/A')
    def routeA():
        if not "counterA" in session:
            session["counterA"]=0
    
        if not "counterTotal" in session:
            session["counterTotal"]=0
    
        session["counterA"]+=1
        session["counterTotal"]+=1
    
        return "accessed A {} times, accessed app {} times".format(session["counterA"], session["counterTotal"])
    @app.route('/B')
    def routeB():
        if not "counterB" in session:
            session["counterB"] = 0
    
        if not "counterTotal" in session:
            session["counterTotal"] = 0
    
        session["counterB"] += 1
        session["counterTotal"] += 1
    
        return "accessed B {} times, accessed app {} times".format(session["counterB"], session["counterTotal"])
    
    
    if __name__ == '__main__':
        app.run()
    

    The session behaves like a dictionary and is available across all routes. You can simply put your counter there.

    For the sake of completeness, a solution without sessions is also possible: In principle, the flask routes behave just like python functions. So the following will work:

    counter = 0
    @app.route('/questions')
    def user_input():
        global counter
        print(counter)
        counter+=1
    
    @app.route('/answers')
    def results():
        global counter
        print(counter)
        counter+=1
    

    I would discourage the use of globals, they can make your code very hard to read and are not thread safe.