2012-07-11 91 views
1

我的理解是,從我自己的應用程序使用API​​的版本2上傳一個大文件到谷歌驅動器,我應該發送像下面的消息。不幸的是,我不知道如何使用Python爲多部分消息實現這種格式。有沒有人有例子Python代碼可以讓我朝着正確的方向前進?POST消息上傳大文件到谷歌驅動器沒有谷歌驅動程序用戶界面

謝謝, 克里斯


POST /upload/drive/v2/files?uploadType=multipart 

Authorization: Bearer <Access token> 
Content-Length: <length> 
Content-Type: multipart/related; boundary="<a base64 encoded guid>" 

--<a base64 encoded guid> 
Content-Type: application/json 

{"title": "test.jpg", "mimeType":"image/jpeg", "parents":[]} 
--<a base64 encoded guid> 
Content-Type: image/jpeg 
Content-Transfer-Encoding: base64 

<base64 encoded binary data> 
--<a base64 encoded guid>-- 

回答

4

的谷歌雲端硬盤API的參考指南包含在許多語言包括Python所有API端點的代碼段。

爲您的使用情況,在drive.files.insert端點有答案:

from apiclient import errors 
from apiclient.http import MediaFileUpload 
# ... 

def insert_file(service, title, description, parent_id, mime_type, filename): 
    """Insert new file. 

    Args: 
    service: Drive API service instance. 
    title: Title of the file to insert, including the extension. 
    description: Description of the file to insert. 
    parent_id: Parent folder's ID. 
    mime_type: MIME type of the file to insert. 
    filename: Filename of the file to insert. 
    Returns: 
    Inserted file metadata if successful, None otherwise. 
    """ 
    media_body = MediaFileUpload(filename, mimetype=mime_type, resumable=True) 
    body = { 
    'title': title, 
    'description': description, 
    'mimeType': mime_type 
    } 
    # Set the parent folder. 
    if parent_id: 
    body['parents'] = [{'id': parent_id}] 

    try: 
    file = service.files().insert(
     body=body, 
     media_body=media_body).execute() 

    return file 
    except errors.HttpError, error: 
    print 'An error occured: %s' % error 
    return None 
+0

我對這段代碼很熟悉,並且已經嘗試過使用它。當我嘗試使用它時,我指定了一個像「test.jpeg」這樣的文件名,並得到一個錯誤,說「test.jpeg」找不到。我該如何處理文件名?這是上傳文件的名稱嗎?或者我想上傳一個名字?我的理解是,除非使用多部分POST,否則必須對API進行兩次調用,一次告訴它將發佈什麼內容,另一次是發佈實際數據。您發佈的這段代碼不會創建多部分POST,因爲我正在尋找並在問題中進行描述。 – user1501783 2012-07-12 17:10:09

+1

文件名是要讀取的硬盤中文件的名稱;如果從內存中讀取,則可以使用其他MediaUPload類型。要執行多部分請求,只需將'resumable'設置爲'False'即可。 – Alain 2012-07-12 17:19:24

+0

非常感謝Alain,但是如何獲取用戶從表單上傳的文件的名稱? – user1501783 2012-07-12 17:38:08

2

我找到答案的其他地方,這Python代碼產生的問題顯示的消息。

url = 'https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart' 

boundary = base64.b64encode(uuid.uuid4().bytes) 
parts = [] 
parts.append('--' + boundary) 
parts.append('Content-Type: application/json') 
parts.append('') 
parts.append(json.dumps({ 
    'title': name, 
    'mimeType': 'image/jpeg', 
    'parents': [{ 
     'kind': 'drive#file', 
     'id': folderId 
     }] if folderId else [] 
    })) 
parts.append('--' + boundary) 
parts.append('Content-Type: image/jpeg') 
parts.append('Content-Transfer-Encoding: base64') 
parts.append('') 
parts.append(base64.b64encode(content)) 
parts.append('--' + boundary + '--') 
parts.append('') 
body = '\r\n'.join(parts) 

headers = { 
    'Content-Type': 'multipart/related; boundary="%s"' % boundary, 
    'Content-Length': str(len(body)), 
    'Authorization': 'Bearer %s' % access_token 
    } 
response = urlfetch.fetch(url, payload=body, method='POST', headers=headers) 
assert response.status_code == 200, '%s - %s' % (response.status_code, response.content) 
r = json.loads(response.content)