A fully worked example showing you how to upload an item with python. Code has been tested and works with python 2.x (though it should mostly be compatible with python 3) and is taken from G3Remote.
def uploadItem(self, parent, filetype, fileLocation, filename, title, description, tags): ''' Function to upload files to Gallery 3. parent: rest url for the new items parent filetype: type of file: "photo" or "movie" fileLocation: location of the file on disc filename: name of file, used as the filename filetitle: file title description: description for new file Required imports httplib2, json, mimetypes, os, urllib ''' # Load httplib2 and set a cache directory. # httplib2 is an improved version of the httplib included # with python, can be downloaded from # http://code.google.com/p/httplib2/ h = httplib2.Http('.cache') # Set up our entity. entity = { 'name' : filename, 'type' : filetype, 'title' : title, 'description' : description, } # Check to make sure our file exists. if not os.path.isfile(fileLocation): print "file {0} does not exist".format(fileLocation) return # Load our file and read it. with file(fileLocation, 'rb') as f: # item is the file to be uploaded item = f.read() # Set content type. content_type = mimetypes.guess_type(item)[0] or \ 'application/octet-stream' # Set boundary. boundary = "roPK9J3DoG4ZWP6etiDuJ97h-zeNAph" # Convert entity into a usable form. entity = json.dumps(entity, separators=(',',':')) # Build custom multipart request. parts = [] parts.append("--{0}".format(boundary)) parts.append('Content-Disposition: form-data; name="entity"') parts.append('Content-Type: text/plain; charset=UTF-8') parts.append('Content-Transfer-Encoding: 8bit') parts.append('') parts.append(entity) parts.append("--{0}".format(boundary)) parts.append('Content-Disposition: form-data; name="file"; filename="{0}"'.format(os.path.basename(fileLocation))) parts.append('Content-Type: {0}'.format(content_type)) parts.append('Content-Transfer-Encoding: binary') parts.append('') parts.append(item) parts.append("--{0}--".format(boundary)) data = '\r\n'.join(parts) # Send request response, content = h.request(parent, 'POST', data, headers={'X-Gallery-Request-Method': 'post', 'X-Gallery-Request-Key': self.gRequestKey, 'Content-Type': 'multipart/form-data; boundary={0}'.format(boundary), 'Content-Length': '{0}'.format(len(data)) }) content = content.decode("utf-8") # Return both status and the content # This can be tested against in your code to make sure the upload # completed. content is the url to your file. return response.status, content