My task was to select files for upload using a file input element on a web page, and then upload them to a Python script on the server that would write them to disc. It was fairly straightforward, but I got stuck trying to get it to work with binary files. The trick is to explicitly set stdin and stdout to work with binary data.
The form on my web page stored the file data in a field called 'uploaded'. I was using HTML5, so the file input was able to upload multiple files at once. In this case the value the Python script obtains from the FieldStorage object is a list of file objects. However, if you only upload a single file, the value is a single file object. I make a simple check on the data to make sure I'm dealing with a list.
#!python """ Gets passed file contents as POST data from an HTML page. Writes them to a file on disc. """ import cgi try: # Windows needs stdio set for binary mode. import msvcrt msvcrt.setmode (0, os.O_BINARY) # stdin = 0 msvcrt.setmode (1, os.O_BINARY) # stdout = 1 except ImportError: pass form = cgi.FieldStorage() fileItems = form['uploaded'] # You only get a list back if you're uploading multiple files. Make sure we're always working with a list. if type(fileItems) != type(): fileItems = [fileItems] for fileItem in fileItems: if fileItem.file: f = open(fileItem.filename, 'wb') while True: chunk = fileItem.file.read(100000) if not chunk: break f.write(chunk) f.close() # Output header. print 'Content-type: text/html' print