通过Google Drive REST API使用httplib2上传文件/元数据

时间:2015-12-21 16:52:13

标签: python python-2.7 rest google-drive-api httplib2

我正在尝试编写一个与Google Drive REST API [1]交互的简单CRUD库。我可以从我的驱动器中获取和删除,但我在上传文件时遇到问题。

我得出的结论是,httplib2不支持多部分上传而不编写我自己的逻辑,因此我将这些方法拆分为两部分来上传元数据并上传文件内容。

#ToDo: needs to be fixed to send binary data correctly, maybe set mimetype
#ToDo: add file metadata via second request (multipart not supported by httplib2)
def uploadDoc(self, filename, fileid=None):
    #ToDo: detect filetype
    data_type = 'image/png'
    # content_length //automatically detected
    url = "https://www.googleapis.com/upload/drive/v2/files"
    method = "POST"
    #replace file at this id if updating file
    if fileid:
        url += "/" + fileid
        method = "PUT"

    headers = {'Authorization' : 'Bearer ' + self.getTokenFromFile(), 'Content-type' : data_type}
    post_data = {'uploadType':'media',
                'file' :self.load_binary(filename)}

    (resp, content) = self.http.request(url,
                            method = method,
                            body = urlencode(post_data),
                            headers = headers)

    print content

#ToDo: metadata not being set, including content-type in header returns 400 status
def uploadFileMeta(self, filename, fileid=None, description=""):
    url = self.drive_api_url + "/files" 
    method = "POST"
    #replace file metadata at this id if updating file
    if fileid:
        url += "/" + fileid
        method = "PUT"

    headers = {'Authorization' : 'Bearer ' + self.getTokenFromFile()}
    post_data = {"title" : filename,
                "description": description}

    (resp, content) = self.http.request(url,
                            method = method,
                            body = urlencode(post_data),
                            headers = headers)

    print resp
    print content

#updating a specific doc will require the fileid
def updateFileMeta(self, fileid, filename, description=""):
    uploadFileMeta(fileid, filename, description)

def reuploadFile(self, fileid, filename):
    uploadDoc(filename, fileid)

def load_binary(self, filename):
    with open(filename, 'rb') as f:
        return f.read()

当我尝试设置标题或描述时,标题设置为“无标题”,并且描述不会在返回的JSON中显示。就好像我没有正确地将它们发送到服务器一样。

我的另一个问题是上传二进制文件。我相信我正在阅读文件或编码错误。

任何建议都将不胜感激。我已经好几个星期了。

谢谢!

编辑:澄清(TLDR):创建的文档标题为:“无标题”,无说明。我是否为uploadMeta函数错误地格式化了正文或标题?

1 个答案:

答案 0 :(得分:0)

我需要在我的请求中发送json,因为Gerardo建议使用元数据。

body = json.dumps(post_data)

但这不适用于发送文件内容。仍在摸索如何发送文件。

编辑:我转而使用Requests发出http请求,并设法使用this exchange中的解决方案同时上传文档和元数据。