【问题标题】:Multipart POST request Google Glass多部分 POST 请求 Google Glass
【发布时间】:2013-07-08 21:16:56
【问题描述】:

我正在尝试使用多部分编码将附件添加到我的时间线。我一直在做类似以下的事情:

req = urllib2.Request(url,data={body}, header={header})
resp = urllib2.urlopen(req).read()

它在应用程序/json 中运行良好。但是,我不确定如何格式化多部分的正文。我还使用了一些库:requests 和 poster,它们都出于某种原因返回 401。

如何使用库(最好是 urllib2 的插件)或 urllib2 本身(如上面的代码块)发出多部分请求?

编辑: 我也希望它能够支持来自 https://developers.google.com/glass/timeline

的 mirror-api "video/vnd.google-glass.stream-url"

对于使用海报库的请求,代码如下:

register_openers()
datagen, headers = multipart_encode({'image1':open('555.jpg', 'rb')})

这里使用requets:

headers = {'Authorization' : 'Bearer %s' % access_token}
files = {'file': open('555.jpg', 'rb')}
r = requests.post(timeline_url,files=files, headers=headers)

返回 401 -> 标题

谢谢

【问题讨论】:

  • 401 是授权错误。您可以发布您用于请求和/或提供 401 的海报的代码吗?我想知道您是否附加了身份验证令牌。
  • 非常正确,我没有想到这一点。我如何将 access_token 附加到任何一个?
  • 有什么理由不使用 Python 客户端库吗?我们有一些sample code 展示了如何插入带有附件的时间线项目。
  • 仅供参考,这是客户端库中构建多部分请求的代码部分:code.google.com/p/google-api-python-client/source/browse/…
  • @Alain 那个链接是黄金,我得到了 200 个。

标签: python django google-mirror-api


【解决方案1】:

这里有一个使用流式视频 url 功能的多部分请求的工作 Curl 示例:

Previous Streaming Video Answer with Curl example

它完全符合您的要求,但使用 Curl。您只需要根据您的技术堆栈进行调整即可。

即使您使用正确的语法,您收到的 401 也会阻止您。 401 响应表示您无权修改时间线。确保您可以先插入一个简单的 hello world 纯文本卡片。一旦您克服 401 错误并遇到解析错误和格式问题,上面的链接应该就是您需要的一切。

最后一点,您不需要urllib2,Mirror API 团队在我们的圈子里丢下了一个功能的宝石,我们不需要为获取视频的二进制文件而烦恼,请查看链接的示例上面我在多部分payload中提供了一个URL,不需要流二进制数据! Google 为我们做了 XE6 及更高版本的所有魔法。

感谢玻璃团队!

我想你会发现这比你想象的要简单。尝试 curl 示例并注意不兼容的视频类型,当你走到那一步时,如果你不使用兼容的类型,它似乎无法在 Glass 中工作,请确保你的视频以 Glass 友好的格式编码。

祝你好运!

【讨论】:

  • 它适用于我,一直到在 Glass 上观看流媒体视频。我唯一的猜测是你得到了一个 401 错误,这意味着你的不记名令牌是坏的。确保输入有效的授权令牌。
  • 它有效。执行此操作:获取 curl 命令并将其粘贴到文本文档中。确保删除所有新行及其全部一行。然后将文本“your_token_here”替换为有效令牌。接下来在与命令提示符相同的目录中创建一个名为 input.txt 的文件,其内容位于 curl 命令下方的框中。然后将 curl 命令粘贴到命令提示符中。您将收到带有 json 的 200 响应,其中包括插入的卡片的时间线 ID。
【解决方案2】:

如何使用多部分编码将附件添加到时间轴:

将带有多部分编码的附件添加到时间轴的最简单方法是使用 Google APIs Client Library for Python。使用这个库,您可以简单地使用Mirror API timeline insert documentation 中提供的以下示例代码(单击示例下的 Python 选项卡)。

from apiclient.discovery import build
service = build('mirror', 'v1')

def insert_timeline_item(service, text, content_type=None, attachment=None,
                         notification_level=None):
  timeline_item = {'text': text}
  media_body = None
  if notification_level:
    timeline_item['notification'] = {'level': notification_level}
  if content_type and attachment:
    media_body = MediaIoBaseUpload(
        io.BytesIO(attachment), mimetype=content_type, resumable=True)
  try:
    return service.timeline().insert(
        body=timeline_item, media_body=media_body).execute()
  except errors.HttpError, error:
    print 'An error occurred: %s' % error

您实际上不能使用requestsposter 自动编码您的数据,因为这些库在multipart/form-data 中编码内容,而Mirror API 需要在multipart/related 中的内容。


如何调试您当前的错误代码:

您的代码给出了 401,这是一个授权错误。这意味着您可能无法在请求中包含访问令牌。要包含访问令牌,请在您的请求中将Authorization 字段设置为Bearer: YOUR_ACCESS_TOKEN(文档here)。

如果您不知道如何获取访问令牌,Glass 开发者文档有一个page here 解释如何获取访问令牌。确保您的授权过程为多部分上传请求了以下范围,否则您将收到 403 错误。 https://www.googleapis.com/auth/glass.timeline

【讨论】:

【解决方案3】:

这就是我的做法,python 客户端库也是这样做的。

from email.mime.multipart import MIMEMultipart
from email.mime.nonmultipart import MIMENonMultipart
from email.mime.image import MIMEImage

mime_root = MIMEMultipart('related', '===============xxxxxxxxxxxxx==')
headers= {'Content-Type': 'multipart/related; '
          'boundary="%s"' % mime_root.get_boundary(),
          'Authorization':'Bearer %s' % access_token}
setattr(mime_root, '_write_headers', lambda self: None)
#Create the metadata part of the MIME
mime_text = MIMENonMultipart(*['application','json'])
mime_text.set_payload("{'text':'waddup doe!'}")
print "Attaching the json"
mime_root.attach(mime_text)

if method == 'Image':
    #DO Image
    file_upload = open('555.jpg', 'rb')
    mime_image = MIMENonMultipart(*['image', 'jpeg'])
    #add the required header
    mime_image['Content-Transfer-Encoding'] = 'binary'
    #read the file as binary
    mime_image.set_payload(file_upload.read())
    print "attaching the jpeg"
    mime_root.attach(mime_image)

elif method == 'Video':
    mime_video = MIMENonMultipart(*['video', 'vnd.google-glass.stream-url'])
    #add the payload
    mime_video.set_payload('https://dl.dropboxusercontent.com/u/6562706/sweetie-wobbly-cat-720p.mp4')
    mime_root.attach(mime_video)

Mark Scheel 我将您的视频用于测试目的 :) 谢谢。

【讨论】:

    猜你喜欢
    • 2020-04-25
    • 1970-01-01
    • 2013-11-26
    • 2017-10-05
    • 2012-11-27
    • 2016-10-19
    • 2015-09-22
    • 1970-01-01
    相关资源
    最近更新 更多