Global variable scope in flask app module and another module in python

I have 3 files,
api file where flask app will be running.
utilities file which has my functions
trainer file where functions from utilities file will be called

api.py

import trainer
app = Flask(__name__)

@app.route('/start', methods=['POST'])
def apifunc(id):
   result = trainer.consume(id)
   return jsonify(result)

if __name__ == '__main__':
    app.run(debug=True, port=LISTEN_PORT, threaded=True, use_reloader=False)

utilities.py

line 1 --> aggregate = 30
def function1(agg1):
  global aggregate
  ... some codes...
  line 100 --> print(aggregate)  

trainer.py

from utilities import function1
def consume(id)
  value = function1(agg1)
  ... some codes...
  return value

I have a global variable in utilities file, “aggregate”.
When I run the app for first time by hitting the end point “/start”, line 100 gets the value 30 from line 1 declaration,
but
when I hit the end point again, I get error,

ERROR:api:500 Internal Server Error: name 'aggregate' is not defined

but when I shutdown the app, and re-start, line 100 works again. Not sure why?
the variable “aggregate” is only the utilities module global variable. When the app runs its not going through the line 1 declaration.
How should I avoid this error?

using Flask g if I declare in api file, I feel that will be unnecessary usage and import. pls correct me?

I have 3 files,
api file where flask app will be running.
utilities file which has my functions
trainer file where functions from utilities file will be called
[…]

Ok. bear in mind that a global only exists while Python is running your
programme.

When I run the app for first time by hitting the end point “/start”, line 100 gets the value 30 from line 1 declaration,

As expected I gather.

but
when I hit the end point again, I get error,

ERROR:api:500 Internal Server Error: name 'aggregate' is not defined

There should be a traceback in the windo where you app is running which
shows what line of code is raising that error. What does it show?

but when I shutdown the app, and re-start, line 100 works again. Not sure why?

Because you’ve started a new Python run. variables are in-memory values,
and vanish when Python shuts down. To persist things over multiple runs
you need to save things in a file (or database of some kind), and
re-access the prior values from that file (or database) when your
program is restarted.

the variable “aggregate” is only the utilities module global variable. When the app runs its not going through the line 1 declaration.
How should I avoid this error?

When you import a module, that module is run the first time that
happens - that is what defines the things in the module.

So your api.py imports trainer, and trainer imports utilities.
And that last runs your utilities.py file the first time it is
imported.

using Flask g if I declare in api file, I feel that will be unnecessary usage and import. pls correct me?

Importing the same thing in multiple places is normal - the first import
defines the module (and runs it) and the other imports just obtain a
reference to the module which was imported earlier.

Does this make anything cleaerer?

I didn’t mean python shutdown,
Run the flask app,

c:\test>python api.py
* Serving Flask app 'api'
 * Debug mode: on
INFO:werkzeug:WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:8080
INFO:werkzeug:Press CTRL+C to quit

—> hit end point from HTML
app starts

INFO:api:--->Log 1: Starting App on Port: 8080
.......

…run finish…
again I hit the end point from HTML, I get Error
but if I CTRL+C and quit
and come back to drive and run

c:\test>python api.py

then it works without error

My issue is I can’t CTRL+C everytime to restart app, when finish I keep hitting the HTML to start next run,
which is where I get Error

and
as I mentioned trackback shows the line of error in 100
and as
NameError: name ‘aggregate’ is not defined

My guess is that the problem has something to do with this part:

Please try the advice here in order to narrow down the problem:

Here is the Flask app.py

from flask import Flask, redirect, url_for, request
import trainer
app = Flask(__name__)
 

@app.route('/success/<name>')
def success(name):
    gValue = trainer.myFunction()
    name = name + gValue
    return 'welcome %s' % name
 
 
@app.route('/login', methods=['POST', 'GET'])
def login():
    if request.method == 'POST':
        user = request.form['nm']
        return redirect(url_for('success', name=user))
    else:
        user = request.args.get('nm')
        return redirect(url_for('success', name=user))
 
 
if __name__ == '__main__':
    app.run(debug=True, threaded=True, use_reloader=False)

HTML file

<html>
<body>	 
	<form action = "http://localhost:5000/login" method = "post">
<p>Enter Name:</p>
<p><input type = "text" name = "nm" /></p>
<p><input type = "submit" value = "submit" /></p>
	</form>	 
</body>
</html>

trainer.py

from utils import sumValue

def myFunction():
   pullValue = sumValue()
   return pullValue

utils.py

aggregateValue = " defaultValue"

def sumValue():
    global aggregateValue
    x = " mainValue"
    x1 = x + aggregateValue
    aggregateValue = " modifiedValue"
    x2 = x1 + aggregateValue
    print(x2)
    return x2

running the app

C:\test>python app.py
 * Serving Flask app 'app'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit
127.0.0.1 - - [09/Jan/2024 16:12:57] "POST /login HTTP/1.1" 302 -
 mainValue defaultValue modifiedValue
127.0.0.1 - - [09/Jan/2024 16:12:57] "GET /success/Value HTTP/1.1" 200 -
127.0.0.1 - - [09/Jan/2024 16:15:59] "POST /login HTTP/1.1" 302 -
 mainValue modifiedValue modifiedValue
127.0.0.1 - - [09/Jan/2024 16:15:59] "GET /success/Value HTTP/1.1" 200 -

in the first run we get
mainValue defaultValue modifiedValue
in 2nd run
mainValue modifiedValue modifiedValue
as the 2nd run is a fresh run, I expect the middle value should be defaultValue instead of modifiedValue,
The global declaration in utils.py is not getting initialized during 2nd run,
If we Ctrl+C and start again, memory is cleared to get defaultValue
May I know how to initialize the global variable here

Well, no, it is not. Imagine this code:

count = 0

def handle_request():
    global count
    input("What is the HTTP GET data?")
    count += 1
    print(f"Okay, we have now handled {count} requests.")

handle_request()
handle_request()

Of course we should expect the counter to go up for each “request”. It is still the same Python process running, and still the same global variable (represented as the same attribute on the same module object). Making a webapp doesn’t change any of that. The server doesn’t restart your code for every incoming request, and neither does utils or trainer get re-imported (but even if they did, Python would use the cached versions that were already imported, unless you jump through some hoops to reload them explicitly).

Of course not. The entire reason for using global variables is to avoid them being “initialized” every time the function runs. (But there is not really any such thing in Python; the first time you assign a value to a variable is not special.)

If you want the value to get (re)set every time the function is called, then it should use a local variable. That’s what they’re for.

If you need to remember values between calls in some way, but also “clear” them sometimes, then you need specific rules for when they should be cleared and when they should use the remembered value.