rGil
rGil

Reputation: 3719

Why do POST file uploads in GAE not have access to the cgi.Fieldstorage methods?

While answering this question, I came across some strange behavior with GAE's handling of file uploads from form POSTs.

Question one: Unless I misunderstand, self.request.POST['filecsv'] is a cgi.FieldStorage instance, and as explained by the OP in this thread (but not answered), and in the cgi docs, keys(), len(), and every other method mentioned in the docs should be available to the object, but they throw a typeError in GAE - as the thread states.

So the first question is, why are they not available?

Question two: A simple way to access the contents of the file is through the value attribute:

my_file = self.request.POST['filecsv'].value

Why is the value attribute not listed in dir(self.request.POST['filecsv'])?

Last Question: Do all of the attributes of the FieldStorage instance actually work in GAE, and I just don't know how to use them?

Upvotes: 0

Views: 1323

Answers (1)

vikki
vikki

Reputation: 2814

Why are they not available

They certainly are

logging.error(self.request.POST['uploadimage'].keys)

prints

ERROR    2013-06-22 05:47:46,605 FileuploadHandler.py:29] <bound method FieldStorage.keys of FieldStorage(u'uploadimage', u'30.jpg')>

calling this method gives a TypeError error

TypeError: not indexable

So as not to get this error, the content-type of the object should either be application/x-www-form-urlencoded or mutlipart/*. For a single file like an image or audio file, the content-type will be the file's mimetype e.g image/jpeg, audio/ogg e.t.c, so the methods __contains__, has_keys, keys, __len__, __getitem__ will raise a TypeError for single files.

Why is the value attribute not listed in dir

Because it is not a real attribute. This is cgi.FieldStorage's __getattr__ method.

def __getattr__(self, name):
    if name != 'value':
        raise AttributeError, name
    if self.file:
        self.file.seek(0)
        value = self.file.read()
        self.file.seek(0)
    elif self.list is not None:
        value = self.list
    else:
        value = None
    return value

therefore dir() wouldn't know about it unless you implement your own __dir__ method

If you are getting the following error when trying to access the virtual value attribute

AttributeError: 'unicode' object has no attribute 'value'

Then you need to set your HTML form's enctype to multipart/form-data.

Upvotes: 3

Related Questions