Zack Yoshyaro
Zack Yoshyaro

Reputation: 2124

Trying to add an 'upload file' form field on Google App Engine webapp, what would cause it to throw a No Such File error?

New to this side of things, so I may be missing something simple. I'm attempting to create an app which allows the user to upload a csv document, which I then parse, and then perform other actions based on the data in the csv file.

I set up a very basic form with the following html.

HTML

<html> 
    <head>
        <title>
            Paginator!
        </title>
    </head>

    <body>
        <form method="post">
            Enter name of page
            <br><input type="text" name="pagename">
            <br>
            Upload page info: <input type="file" name="csvfile" size="chars"><br>
            <input type="submit">
        </form>
    </body>
</html> 

Python code:

import os
import csv
import webapp2

with open('index.html', 'rb') as f:
    HTML = f.read()
    print HTML

class MainPage(webapp2.RequestHandler):

    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        self.response.write(HTML)

    def post(self):
        self.response.write(self.request.get('pagename'))
        in_file = self.request.get('csvfile')

        if in_file:
            with open(in_file, 'rb') as f:
                csvreader = csv.reader(f, delimiter=',')
                data = [row for row in csvreader]

app = webapp2.WSGIApplication([('/', MainPage)],
                              debug=True)

So I load the HTML file with the form info, and write that to the page when there's a GET request on /.

The problem comes in when I try to handle the POST request. I'm getting a No Such File Error from GoogleApp Engine when I try to upload anything via the "Choose File" button.

Error Message:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1535, in __call__
    rv = self.handle_exception(request, response, e)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1529, in __call__
    rv = self.router.dispatch(request, response)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "C:\Users\Chris\Documents\Code\Python\iqm segmetizer\index.py", line 20, in post
    with open(in_file, 'rb') as f:
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver_import_hook.py", line 610, in __init__
    super(FakeFile, self).__init__(filename, mode, bufsize, **kwargs)
IOError: [Errno 2] No such file or directory: u'test_page_info.csv'

What do I need to do to be able to allow the user (myself in this case) to be able to upload a csv file via the form?

Upvotes: 0

Views: 1201

Answers (1)

Nathan Villaescusa
Nathan Villaescusa

Reputation: 17649

First add enctype="multipart/form-data" to your form:

<form method="post" enctype="multipart/form-data">
        Enter name of page
        <br><input type="text" name="pagename">
        <br>
        Upload page info: <input type="file" name="csvfile" size="chars"><br>
        <input type="submit">
</form>

This will ensure that your the browser correctly encodes the file to be uploaded to the server.

Then modify your Python code to use the Blobstore and BlobReader:

import csv
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
  def post(self):
    upload_files = self.get_uploads('csvfile')
    blob_info = upload_files[0]
    blob_reader = blobstore.BlobReader(blob_info.key())
    csv_data = blob_reader.read()
    csv_reader = csv.reader(csv_data)
    ...

Upvotes: 1

Related Questions