Flask redirect with uploaded file - I/O operation on closed file
<p>This app should allow a user to upload a file and then depending on the file type it would perform a save task.  If it's a  PDF file a new selection page loads prompting the user to select a folder. Once selected the error: <strong>ValueError: I/O operation on closed file</strong> pops up and an <strong>empty PDF</strong> file is saved in the selected location.</p>

<p>".mxd" files process with no issues.  It seems to be because I have redirected to the selection template, but I'm not sure how else I would be able to use the folder selection.</p>

<p>Much code has been omitted to keep things simple. Any help would be greatly appreciated. </p>

<pre><code>@app.route("/", methods=['GET', 'POST'])  
def upload_file(): 
form = ReusableForm(request.form)  # calls on form

if request.method == 'POST':
    global folderout
    folderout = request.form['folderout']

    global file
    file = request.files['file']
        if filename.endswith((".pdf")):  # For PDF files only
            return redirect("/selection")
            return redirect("/editor")

        if filename.endswith((".mxd")):
            MXDfull.savemxd()
            MXDfull.pdf()
            MXDfull.thumb()
            return redirect("/editor")

@app.route("/selection", methods=['GET', 'POST'])
def selection1():
    form = SelectionForm(request.form)
    if request.method == 'POST':
        global selection
        selection = request.form['selection']
        pdffilesave.savepdf()

    return render_template("selection.html", form=form)

class PDFFile:
    def savepdf(self):
            self.pdffolder = os.path.join(folderout,selection)
            self.pdffilename = "K" + Fnum + ".pdf"
            file.save(os.path.join(self.pdffolder, self.pdffilename))
            return
    pdffilesave = PDFFile()
</code></pre>

<p>Page 1:</p>

<p><a href="http://i.stack.imgur.com/ChE5F.png" rel="nofollow"><img src="http://i.stack.imgur.com/ChE5F.png" alt="Upload file"></a></p>

<p>Page 2:</p>

<p><a href="http://i.stack.imgur.com/7NiJP.png" rel="nofollow"><img src="http://i.stack.imgur.com/7NiJP.png" alt="enter image description here"></a></p>

<p>Page 3:</p>

<p><a href="http://i.stack.imgur.com/MZSE1.png" rel="nofollow"><img src="http://i.stack.imgur.com/MZSE1.png" alt="enter image description here"></a></p>

<p>Flask creates a <a href="http://werkzeug.pocoo.org/docs/0.11/datastructures/#werkzeug.datastructures.FileStorage.save" rel="nofollow">FileStorage</a> object which is a thin wrapper over incoming files.</p>

<p>The stream attribute of this object usually points to an open temporary file (according to the documentation). I'm guessing that as soon as the request is served, this temporary file is closed and hence the reference to this stream from your global object <code>file</code> points to a closed file. You must have got this error
<code>ValueError: I/O operation on closed file.</code></p>

<p>One work around would be to save the file in <code>upload_file</code> method in a temporary location and store the location of this file in a global variable <code>filename</code>.</p>

<pre><code>@app.route("/", methods=['GET', 'POST'])  
def upload_file(): 
....
file = request.files['file']
global file_name = '/tmp/' + file.filename

file.save(file_name)
if file.filename.endswith((".pdf")):  # For PDF files only
    return redirect("/selection")
    return redirect("/editor")
...
</code></pre>

<p>In the selection method, you can move the file from temporary location to the desired location.</p>

<pre><code>@app.route("/selection", methods=['GET', 'POST'])
def selection1():
....
os.rename(file_name, dest_file_name)
...
</code></pre>

python flask werkzeug