Reputation: 776
I have this Flask View which takes a POST and GET requests
Goal is to do something with the Data from the POST request
and use it for the GET request
for example this AJAX GET Request
$.getJSON({url: '/uploadajax'}).done(result =>console.log(result));
which waits to return the processed data from the POST request
I was able to pass the data to the AJAX call by
declaring the global variable result
and changed it in the function
and use it as a return value for the GET Request
Question here: is there a cleaner way to perform this task ?
result = 0
# ------------upload-file-----------------------------------------#
@flask_class.route('/uploadajax', methods=['POST', 'GET'])
def receave_file():
if request.method == 'POST':
uploaded_file = request.files['file']
# filename = secure_filename(uploaded_file.filename)
if uploaded_file.filename != "":
filename = secure_filename(uploaded_file.filename)
file_ext = os.path.splitext(filename)[1] # was macht das ?
if file_ext not in Config.ALLOWED_EXTENSIONS:
abort(400)
# file kann auch net gespeichert werden
uploaded_file.save(os.path.join(flask_class.instance_path, 'uploads', filename))
# ------------------------------------- #
df = pd.read_excel(uploaded_file)
columns = df.columns.to_list()
global result
result = json.dumps(columns)
# return result
print("shoud return somehting")
# ---------------------------------------- #
return '', 204
# ---------------------------------------- #
else:
return "false"
else:
# GET REQUEST
if len(result) > 1:
return result
else:
return '', 404
# return render_template('index.html')
Upvotes: 3
Views: 1761
Reputation: 905
Yes, there is :)
Have a look at the following code:
class LocalStore:
def __call__(self, f: callable):
f.__globals__[self.__class__.__name__] = self
return f
# ------------upload-file-----------------------------------------#
@flask_class.route('/uploadajax', methods=['POST', 'GET'])
@LocalStore() # creates store for this unique method only
def receave_file():
if request.method == 'POST':
LocalStore.post_headers= request.headers
LocalStore.post_body = request.body
LocalStore.post_json = request.get_json()
LocalStore.post_params = request.params
LocalStore.answer_to_everything = 42
print("POST request stored.")
return jsonify({"response": "Thanks for your POST!"})
else:
try:
print("This is a GET request.")
print("POST headers were:", LocalStore.post_headers)
print("POST params were :", LocalStore.post_params)
print("POST body was :", LocalStore.post_body)
print("The answer is :", LocalStore.answer_to_everything)
return jsonify({"postHeadersWere": LocalStore.post_headers})
except AttributeError:
return jsonify({"response":"You have to make a POST first!"})
I created a special class which "injects" its reference into the __globals__
dictionary of the method. If you type the class name in the method, it will be the object reference, not the class reference. Be aware of that!
You then just need to add @LocalStore
underneath the @app.route(...)
of your application because the store needs to be routed with the method...
I think it's a quite elegant way that saves you the definition of 5 global variables for 5 different methods
Upvotes: 3