pythonflask

Flask writing to file on built-in server but not on remote server


The following works on the builtin server, but not when I deploy to my VPS.

@app.route("/json", methods=["POST"]) 
def json(): 
    if request.is_json:   
        req = request.get_json() 
        with open("data1.txt", "w") as f:
          f.write("text here")
        res = make_response(jsonify({"result": "okeydokey"}))
        return res 

I get the "200 Okay" response and the "okeydokey" result on Postman.

But I don't get file "data1.txt"

No wsgi:error showing up in the error.log.

I've tried "touch data1.txt" and changed its owner and group in various ways.


Solution

  • Couple of things:

    1. You are using a relative path. This is fine for local development because you know where your script will be running from. That may not be the same on your remote machine. You should use an absolute path.
    2. The user whose account is used to run the flask app may not have permissions to write in the target directory. You manually creating a file by running touch data1.txt would only be a valid permission test if you are running it with the same user/same directory as the flask app. The fact that you are using a relative path makes this difficult to verify.
    3. You should add logging and exception handling to verify from the app whether the write operation was successful.
    import logging
    import os
    
    cwd = os.getcwd()
    log_file_path = os.path.join(cwd, "app.log")
    logging.basicConfig(filename=log_file_path, level=logging.ERROR)
    
    @app.route("/json", methods=["POST"])
    def json():
        if request.is_json:
            try:
                req = request.get_json()
                file_path = os.path.join(cwd, "data1.txt")
                with open(file_path, "w") as f:
                    f.write("text here")
                res = make_response(jsonify({"result": "okeydokey"}))
                return res
            except Exception as e:
                logging.error(f"Error writing to file: {e}")
                return make_response(jsonify({"result": "error"}), 500)
    

    Note that in case of an exception the app will now return 500 indicating an internal server error.