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
0

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

4 Comments

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£µÇù<sõŒ¶Äf1ÂÕaa¾AOCïO ²ÈhÃÕyxé–d¢OËmÂ{oWWü¼(‘Ü# ’ÓàåžuGU¥ˆ­û" (but much longer). However, I get a 500 error from the server. I will add that traceback to my original question.
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.
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.
That worked even better than I expected. It not only worked, but it seemed to handle the upload more smoothly than other options. Thanks!

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.