Составной POST-запрос Google Glass

Я пытаюсь добавить вложение на свою временную шкалу с многокомпонентной кодировкой. Я делал что-то вроде следующего:

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

И он отлично работает для application/json. Однако я не уверен, как отформатировать тело для составных частей. Я также использовал некоторые библиотеки: запросы и плакат, и они оба почему-то возвращают 401.

Как я могу сделать составной запрос либо с библиотекой (предпочтительно надстройкой для urllib2), либо с самой urllib2 (например, блок кода выше)?

РЕДАКТИРОВАТЬ: Я также хотел бы, чтобы это могло поддерживать API-интерфейс зеркала "video/vnd.google-glass.stream-url" из https://developers.google.com/glass/timeline

Для запроса с использованием библиотеки плакатов вот код:

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

Здесь он использует запросы:

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

Возвращает 401 -> заголовок

Спасибо


person Clocker    schedule 08.07.2013    source источник
comment
401 - ошибка авторизации. Можете ли вы опубликовать код, который вы использовали для запросов и / или плакат, который дал 401? Мне интересно, прикрепили ли вы токен авторизации.   -  person J Wang    schedule 09.07.2013
comment
Совершенно верно, я не думал об этом. Как мне прикрепить access_token к любому из них?   -  person Clocker    schedule 09.07.2013
comment
Есть ли причина не использовать клиентскую библиотеку Python? У нас есть пример кода, показывающий, как вставить элемент временной шкалы с вложение.   -  person Alain    schedule 09.07.2013
comment
да. Я хочу больше попрактиковаться в запросах и кодировках POST/GET и знаю, что клиентская библиотека делает почти все за вас. Я думал только об использовании библиотеки.   -  person Clocker    schedule 09.07.2013
comment
К вашему сведению, это часть кода в клиентской библиотеке, которая создает составной запрос: code.google.com/p/google-api-python-client/source/browse/   -  person Alain    schedule 10.07.2013
comment
@ Ален, эта ссылка была золотой, я получил 200.   -  person Clocker    schedule 16.07.2013


Ответы (3)


Вот рабочий пример Curl составного запроса, который использует функцию URL-адреса потокового видео:

Предыдущий ответ на потоковое видео пример с Curl

Он делает именно то, что вы пытаетесь сделать, но с Curl. Вам просто нужно адаптировать это к вашему стеку технологий.

Ошибка 401, которую вы получаете, помешает вам, даже если вы используете правильный синтаксис. Ответ 401 означает, что у вас нет прав на изменение временной шкалы. Сначала убедитесь, что вы можете вставить простую открытку с текстом hello world. Как только вы преодолеете ошибку 401 и перейдете к ошибкам синтаксического анализа и проблемам с форматированием, приведенная выше ссылка должна быть всем, что вам нужно.

И последнее замечание: вам не нужен urllib2, команда Mirror API отказалась жемчужина функции у нас на коленях, и нам не нужно беспокоиться о получении двоичного файла видео, проверьте приведенный выше пример. Я только предоставил URL-адрес в составной полезной нагрузке, нет необходимости поток двоичных данных! Google делает за нас всю магию в XE6 и выше.

Спасибо команде Стекло!

Я думаю, вы обнаружите, что это проще, чем вы думаете. Попробуйте пример curl и следите за несовместимыми типами видео, когда вы доберетесь до этого, если вы не используете совместимый тип, он не будет работать в Glass, убедитесь, что ваше видео закодировано в формате, удобном для Glass.

Удачи!

person Mark Scheel    schedule 09.07.2013
comment
Для меня это работает, вплоть до просмотра потокового видео на Glass. Мое единственное предположение: у вас ошибка 401, что означает, что ваш токен на предъявителя неисправен. Убедитесь, что вы ввели действительный токен авторизации. - person Mark Scheel; 10.07.2013
comment
Оно работает. Сделайте это: возьмите команду curl и вставьте ее в текстовый документ. Убедитесь, что вы удалили все новые строки и все это одна строка. Затем замените только текст your_token_here допустимым токеном. Затем создайте файл в том же каталоге, что и ваша командная строка, с именем input.txt с содержимым в поле под командой curl. Затем вставьте команду curl в командную строку. Вы получите ответ 200 с json, который включает идентификатор временной шкалы вставленной карты. - person Mark Scheel; 11.07.2013

Как добавить вложение на временную шкалу с помощью составного кодирования:

Самый простой способ добавить на временную шкалу вложения с составным кодированием — использовать клиентскую библиотеку Google API. для Python. С помощью этой библиотеки вы можете просто использовать следующий пример кода, представленный в Mirror API. документация по вставке временной шкалы (перейдите на вкладку 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

На самом деле вы не можете использовать запросы или poster для автоматического кодирования ваших данных, потому что эти библиотеки кодируют вещи в multipart/form-data, тогда как Mirror API хочет в multipart/related.


Как отладить текущий код ошибки:

Ваш код дает 401, что является ошибкой авторизации. Это означает, что вы, вероятно, не включаете свой токен доступа в свои запросы. Чтобы включить токен доступа, установите в поле Authorization значение Bearer: YOUR_ACCESS_TOKEN в своем запросе (документация здесь).

Если вы не знаете, как получить токен доступа, в документации для разработчиков Glass есть страница с объяснением как получить токен доступа. Убедитесь, что ваш процесс авторизации запросил следующую область действия для многокомпонентной загрузки, иначе вы получите ошибку 403. https://www.googleapis.com/auth/glass.timeline

person J Wang    schedule 10.07.2013
comment
То же самое можно сделать, проще с использованием библиотеки MIMEMultipart, включенной в python. Как и в исходном коде code.google.com/p/google-api-python-client/source/browse/ - person Clocker; 16.07.2013

Вот как это сделал я и как это делает клиентская библиотека 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 Я использовал ваше видео для тестирования :) Спасибо.

person Clocker    schedule 31.07.2013