8

I have an HTML form and I am using Python to generate a log file based on the input. I'd like to also be able to allow the user to upload an image if they choose. I can figure out how to manipulate it with Python once it's there, but I'm not sure how to get the image uploaded. This has most certainly been done before, but I'm having a hard time finding any examples. Can any of you point me in the right direction?

Basically, I'm using cgi.FieldStorage and csv.writer to make the log. I want to get an image from the user's computer and then save it to a directory on my server. I will then rename it and append the title to the CSV file.

I know there are a lot of options for this. I just don't know what they are. If anyone could direct me toward some resources I would be very appreciative.

7
  • you're more likely to get an answer if you post some code that's not working, rather than asking broadly "how do i do this" Commented Aug 28, 2012 at 19:28
  • 1
    There are so many ways this could be done, with different libs...We need to know exactly what you are working with. Commented Aug 28, 2012 at 19:30
  • I'm not asking "how do I do this." I know that is frowned upon. I'm asking for direction toward some resources so I don't waste everyone's time. I'll edit to make that more clear. Commented Aug 28, 2012 at 19:31
  • 1
    Yep. That was the missing piece :-) Commented Aug 28, 2012 at 19:45
  • 1
    Edited in. Sorry for the initial defensiveness. Ignorance. :/ Thanks again! Commented Aug 28, 2012 at 19:47

2 Answers 2

8

Since you said that your specific application is for use with the python cgi module, a quick google turns up plenty of examples. Here is the first one:

Minimal http upload cgi (Python recipe) (snip)

def save_uploaded_file (form_field, upload_dir):
    """This saves a file uploaded by an HTML form.
       The form_field is the name of the file input field from the form.
       For example, the following form_field would be "file_1":
           <input name="file_1" type="file">
       The upload_dir is the directory where the file will be written.
       If no file was uploaded or if the field does not exist then
       this does nothing.
    """
    form = cgi.FieldStorage()
    if not form.has_key(form_field): return
    fileitem = form[form_field]
    if not fileitem.file: return
    fout = file (os.path.join(upload_dir, fileitem.filename), 'wb')
    while 1:
        chunk = fileitem.file.read(100000)
        if not chunk: break
        fout.write (chunk)
    fout.close()

This code will grab the file input field, which will be a file-like object. Then it will read it, chunk by chunk, into an output file.

Update 04/12/15: Per comments, I have added in the updates to this old activestate snippet:

import shutil

def save_uploaded_file (form_field, upload_dir):
    form = cgi.FieldStorage()
    if not form.has_key(form_field): return
    fileitem = form[form_field]
    if not fileitem.file: return

    outpath = os.path.join(upload_dir, fileitem.filename)

    with open(outpath, 'wb') as fout:
        shutil.copyfileobj(fileitem.file, fout, 100000)
Sign up to request clarification or add additional context in comments.

5 Comments

fout = open(pathname, 'wb') is better than fout = file(pathname, 'wb'); see Why is open() preferable over file() in Python?. Even better: with open(pathname, 'wb') as fout:, and then fout will be closed automatically when you leave the context of the with block.
also use shutil.copyfileobj to copy the file contents
Thanks for the comments. It was an old activestate recipe that I copied the snip from. I've updated it.
if not form.has_key(form_field) did not work with Python 3.5. Use if form_field not in form instead.
@MCF yes as I recall they deprecated has_key in py3
3

The web frame work Pyramid has a good example. http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/forms/file_uploads.html

Here is my example code that I use with a working project.

    extension = os.path.splitext(request.POST[form_id_name].filename)[1]
    short_id = str(random.randint(1, 999999999))
    new_file_name =  short_id + extension
    input_file = request.POST[form_id_name].file
    file_path = os.path.join(os.environ['PROJECT_PATH'] + '/static/memberphotos/', new_file_name)

    output_file = open(file_path, 'wb')
    input_file.seek(0)
    while 1:
        data = input_file.read(2<<16)
        if not data:
            break
        output_file.write(data)
    output_file.close()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.