1

I've looked through many questions, but I cannot seem to find one addressing my specific issue.

I am attempting to allow users (on my Google App Engine website) to upload a video to wistia (video host).

I was able to get it to work by directly opening the file, but this only works if the file is already in the app folder:

class VideoUploadHandler(webapp2.RequestHandler):
    def post(self):
        title = self.request.get('title')
        video = self.request.get('video')
        description = self.request.get('description')

        url = 'https://upload.wistia.com'
        params = {
            'api_password'    : 'my_password',
            'file'            : open(video, "rb"),  #<--- HOW TO USE FILE OBJECT?
            'project_id'      : 'my_project_id',
            'name'            : title,
            'description'     : description,
            }
        opener = urllib2.build_opener(MultipartPostHandler.MultipartPostHandler) 
        response = opener.open(url, params)

        logging.warning(response.read())

        self.redirect("https://www.my_webpage.com/")

This works if the variable 'video' is merely the file name and the file is in the same folder, but I obviously need to allow users to select any file, so I changed my HTML to this:

HTML:

<form enctype="multipart/form-data" action="/video_upload/" method="post">
<p>Title: <input type="text" name="title"/></p>
<p><input type="file" name="video"/></p>
<p>Description:<br><textarea rows="4" cols="50" name="description"></textarea></p>
<p><input type="submit" value="Upload"/></p>
</form>

However, I am having trouble understanding how to use the file object in my POST request. For some reason, I'm not able to glean this information from other answers already posted.

How do I structure my 'params' using this HTML Form method?



EDIT:

To clarify, I now have this simple HTML:

<input id="video_input" type="file" name="video"/>
<a id="video_button">SUBMIT VIDEO</a>

and this JavaScript based on this and this:

$('#video_button').click(function() {
    var file = new FormData();
    file.append('video', $('#video_input').get(0).files[0]);
    $.ajax({
        type: "POST",
        url: "/video_upload/",
        data: file,
        processData: false,
        contentType: false
    });
});

But I still have not found anything adequately explaining how to take this file object I now have in Python and pass it properly to the parameters for the wistia POST. Any ideas or links?




EDIT: Traceback when using:

params = {
            'api_password'    : 'my_password',
            'file'            : video,
            'project_id'      : 'my_project_id',
            'name'            : title,
            'description'     : description,
            }

(video.py) is the file with the VideoUploadHandler class.

WARNING  2015-09-05 07:13:16,970 urlfetch_stub.py:504] Stripped prohibited headers from URLFetch request: ['Content-Length', 'Host']
ERROR    2015-09-05 12:13:21,026 webapp2.py:1552] HTTP Error 500: Internal Server Error

Traceback (most recent call last):

  File "C:\...\webapp2-2.5.2\webapp2.py", line 1535, in __call__

    rv = self.handle_exception(request, response, e)

  File "C:\...\webapp2-2.5.2\webapp2.py", line 1529, in __call__

    rv = self.router.dispatch(request, response)

  File "C:\...\webapp2-2.5.2\webapp2.py", line 1278, in default_dispatcher

    return route.handler_adapter(request, response)

  File "C:\...\webapp2-2.5.2\webapp2.py", line 1102, in __call__

    return handler.dispatch()

  File "C:\...\webapp2-2.5.2\webapp2.py", line 572, in dispatch

    return self.handle_exception(e, self.app.debug)

  File "C:\...\webapp2-2.5.2\webapp2.py", line 570, in dispatch

    return method(*args, **kwargs)

  File "C:\...\video.py", line 84, in post

    response = opener.open(url, params)

  File "C:\...\urllib2.py", line 410, in open

    response = meth(req, response)

  File "C:\...\urllib2.py", line 523, in http_response

    'http', request, response, code, msg, hdrs)

  File "C:\...\urllib2.py", line 448, in error

    return self._call_chain(*args)

  File "C:\...\urllib2.py", line 382, in _call_chain

    result = func(*args)

  File "C:\...\urllib2.py", line 531, in http_error_default

    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)

HTTPError: HTTP Error 500: Internal Server Error

INFO     2015-09-05 07:13:21,700 module.py:788] default: "POST /video_upload/ HTTP/1.1" 500 2253
Community
  • 1
  • 1
sean
  • 3,484
  • 5
  • 27
  • 45

1 Answers1

2

EDIT: Try this:

from poster.encode import multipart_encode, MultipartParam
from google.appengine.api import urlfetch

class VideoUploadHandler(webapp2.RequestHandler):
    def post(self):
        title = self.request.get('title')
        description = self.request.get('description')
        payload = {
            'api_password'    : 'my_password',
            'project_id'      : 'my_project_id',
            'name'            : title,
            'description'     : description,
            }
        file_data = self.request.POST['video']
        payload['file'] = MultipartParam('file', filename=file_data.filename,
                                              filetype=file_data.type,
                                              fileobj=file_data.file)
        data,headers= multipart_encode(payload)
        send_url = "https://upload.wistia.com"
        resp = urlfetch.fetch(url=send_url, payload="".join(data), method=urlfetch.POST, headers=headers)       
        logging.info(resp)
        self.redirect("/")

You will need this lib and this was adapted from this post

Community
  • 1
  • 1
Ryan
  • 2,512
  • 1
  • 13
  • 20
  • Thanks for the comment Ryan! I actually tried that already, but I got an error, so I tried it again with the text file. When I logged the 'video' variable (this time the text file), it did indeed show plain text. So, I then tried the video again. When I log the 'video' variable (in the python script) when it actually is a video, I get something like: "%%5£µÇù – sean Sep 05 '15 at 12:21
  • The strange thing is that when I do: " 'file' : open(_video_name_in_current_folder_, "rb"), " It works - my video uploads to wistia without an issue. – sean Sep 05 '15 at 12:22
  • Looks like it has to do with how MultipartPostHandler.MultipartPostHandler handles files. with the open it is sending a file handle while 'video' is the raw file. That explains why one works while the other does not. This seems to be a limitation with the MultipartPostHandler handler. I will edit the above to code I got to work. – Ryan Sep 08 '15 at 18:49
  • That worked even better than I expected. It not only worked, but it seemed to handle the upload more smoothly than other options. Thanks! – sean Sep 12 '15 at 11:08