It seems to be pretty common practice to have global scope class instances that are used in flask routes, something like this:
from flask import Flask
app = Flask(__name__)
class Utility:
def get_properties():
pass
util_obj = Utility()
@app.route('/aaa/bbb/ccc',methods=['POST'])
def func1():
util_obj.get_properties()
pass
if __name__ == "__main__":
app.run(host='127.0.0.1', port=5000, debug=True)
But what if the Utility class has attributes that need to be instantiated at runtime?
import argparse
from flask import Flask
app = Flask(__name__)
class Utility:
def __init__(self, x): # x is only known at runtime
self.x = x
def get_properties(self):
pass
util_obj = Utility() # This will fail, as we need "x"
@app.route('/aaa/bbb/ccc',methods=['POST'])
def func1():
util_obj.get_properties()
pass
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("x") # This needs to be used to instantiate the Utility class
app.run(host='127.0.0.1', port=5000, debug=True)
How can this be done cleanly?
I have tried to create a function that creates the app and instantiates the class, but that feels like bad practice.
It sounds like what you are likely after is the application context
https://flask.palletsprojects.com/en/2.3.x/appcontext/
Or sessions
https://flask.palletsprojects.com/en/2.3.x/quickstart/#sessions
Both of these are useful for storing data and/or returning objects at runtime. The application context in particular is used in the Flask documentation to initialise databases and return their cursor/handle at runtime. I would follow the Flask documentation quickstart and tutorials for a thorough explanation of how to setup a project this way.
Using what you have there though, you could just set self.x to a default value and change it before initialising your application.
import argparse
from flask import Flask
app = Flask(__name__)
class Utility:
def __init__(self): # x is only known at runtime
self.x = None
def get_properties(self):
pass
util_obj = Utility() # This will fail, as we need "x"
@app.route('/aaa/bbb/ccc',methods=['POST'])
def func1():
util_obj.get_properties()
pass
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("x") # This needs to be used to instantiate the Utility class
args = parser.parse_args()
util_obj.x = args.x
app.run(host='127.0.0.1', port=5000, debug=True)