簡體   English   中英

使用Mirror API和Python在靜態卡中附加圖像

[英]Attach image in static card with Mirror API and Python

我試圖將帶有圖像作為附件的項目卡插入時間軸。

如果我嘗試插入一個項目,則效果很好:

def notify_card(my_user, card=None):
    payload = card
    headers = {'Content-Type': 'application/json',
               'Authorization': 'Bearer {0}'.format(my_user.mirror_access_token)}
    url = OAUTH_API_BASE_URL + '/mirror/v1/timeline'
    r = requests.post(url, data=payload, headers=headers)
    if r.status_code == 401:
        new_access_token = __refresh_token(my_user.mirror_refresh_token)
        __create_or_update_user(access_token=new_access_token, refresh_token=user_vademecum.mirror_refresh_token)
        headers = {'Content-Type': 'application/json',
               'Authorization': 'Bearer {0}'.format(new_access_token)}
        r = requests.post(url, data=payload, headers=headers)

正常工作,將卡插入時間軸。

現在,當我要上傳圖像時,問題就來了:

# Send media
import os
module_dir = os.path.dirname(__file__)  # get current directory
file_path = os.path.join(module_dir, 'bodegon.jpg')
file = {'bodegon.jpg': ('bodegon.jpg', open(file_path, 'rb'), 'image/jpg')}
headers = {
           'Authorization': 'Bearer {0}'.format(my_user.mirror_access_token)}
url = OAUTH_API_BASE_URL + 'upload/mirror/v1/timeline?uploadType=multipart'

r = requests.post(url, data={"message": {"bundleId": "0000001"}}, files=file, headers=headers)
print r.text

此代碼返回錯誤消息:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "badContent",
    "message": "Media type 'application/octet-stream' is not supported. Valid media types: [image/*, audio/*, video/*]"
   }
  ],
  "code": 400,
  "message": "Media type 'application/octet-stream' is not supported. Valid media types: [image/*, audio/*, video/*]"
 }
}

如果我手動設置內容類型:

headers = {'content-type': 'image/jpg',
           'Authorization': 'Bearer {0}'.format(my_user.mirror_access_token)}

返回此消息:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "required",
    "message": "Required"
   }
  ],
  "code": 400,
  "message": "Required"
 }
}

另外,我嘗試將媒體發送到以下網址:

https://www.googleapis.com/upload/mirror/v1/timeline?uploadType=media

代替

https://www.googleapis.com/upload/mirror/v1/timeline?uploadType=multipart

為了使用簡單的上傳進行上傳: https : //developers.google.com/glass/media-upload

我做錯了什么?

使用您提供的代碼,請求將生成一個請求主體,大致類似於:

--{boundary}
Content-Disposition: form-data; message="message"


bundleId


--{boundary}

Content-Disposition: form-data; name="bodegon.jpg"



{file contents}

--{boundary}--

請注意,您為bundleId指定的ID不會出現。 這意味着您可能希望將其作為JSON編碼的數據,因為@Prisoner似乎在他的答案中提出了建議。 根據您的問題進一步判斷,您需要為上傳的文件部分提供Content-Type 可以這樣解決:

import json
r = requests.post(url, files={"message": (, json.dumps({"bundleId": "0000001"}, 'application/json'), 'file': ('filename.jpg', file, 'image/jpeg')}, headers=headers)

headers是您指定的原始詞典。

另外,如果您要上傳非常大的文件,則可能需要考慮不單獨使用請求。 該文件將全部加載到內存中。 在這種情況下,您很可能希望流式上傳。 您可以這樣使用request-toolbelt

import requests
from requests_toolbelt import MultipartEncoder
import json

fields = {
    'message': (, json.dumps({'bundleId': '0000001'}, 'application/json'),
    'file': ('filename.jpg', file, 'image/jpeg')
}

encoder = MultipartEncoder(fields)
headers = {
    'Authorization': 'Bearer <your token>',
    'Content-Type': encoder.content_type
}

r = requests.post(url, data=encoder, headers=headers)

這將負責對數據進行編碼,並允許將其流式傳輸到服務器。

注意我沒有在文檔中檢查表單部件的名稱,因此使用'file'可能不正確。 我鼓勵您自己研究這個問題。

對於初學者,您可能需要研究使用PythonGoogle客戶端庫 它包括處理Mirror API的特定方法以及進行媒體上載的一般情況。

如果您只是想創建帶有附件的時間軸項目,這可能是最簡單的。 請參閱https://developers.google.com/glass/v1/reference/timeline/insert#examples上的示例,然后單擊“ Python”標簽。

如果您真的想直接使用HTTP方法,則需要弄清楚為什么要使用簡單上傳方法(uploadType = media)與分段上傳方法(uploadType = multipart)。 簡單上傳需要您還調用timeline.attachment以指定附件的元數據,而分段版本允許您同時上傳兩者。

使用簡單的方法,您應該只能夠使用image / jpeg的內容類型和包含圖像數據的正文進行POST。 那很簡單。 可以這么說。

使用multipart方法,您必須處理多種內容類型。 您具有整體的內容類型,該內容類型為“與多部分相關”,並且包含有關每個部分之間的邊界標記的信息。 每個部分具有內容類型-第一部分將是“ application / json”並包含元數據,而第二部分將是“ image / jpeg”類型並包含圖像主體。 它可能看起來像這樣:

POST /upload/mirror/v1/timeline?uploadType=multipart HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer <your_auth_token>
Content-Type: multipart/related; boundary="foo_bar_baz"
Content-Length: <number_of_bytes_in_entire_request_body>

--foo_bar_baz
Content-Type: application/json; charset=UTF-8

{
  "text": "Hello world!"
}

--foo_bar_baz
Content-Type: image/jpeg

<JPEG data>

--foo_bar_baz--

您將需要自己建立這個身體。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM