Sator
Sator

Reputation: 776

perform GET Request with output from POST Request in Flask

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

Answers (1)

TheClockTwister
TheClockTwister

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

Related Questions