Google Slides возвращает сообщение «Предоставленное изображение в неподдерживаемом формате» даже при настроенных полях авторизации.

Самая близкая ветка -

https://stackoverflow.com/questions/60160794/getting-the-provided-image-is-in-an-unsupported-format-error-when-trying-to-in

Но я не хочу открывать доступ к изображению для остального мира. Итак, я настраиваю с доменом

file_id = uploaded_file.get('id')
drive_service.permissions().create(fileId=file_id, body={
    'type': 'domain',
    'domain': 'mydomain.com', # this is the domain I use the gsuite user e.g. [email protected] to login
    'role': 'reader'
}).execute()

Ресурс слайдов создан

def build_request(http, *args, **kwargs):
    import google_auth_httplib2
    new_http = google_auth_httplib2.AuthorizedHttp(credentials=drive_creds)
    auth_header = {
        'Authorization': 'Bearer '+ drive_creds.token
    }
    headers = kwargs.get('headers', {})
    if not headers:
        kwargs['headers'] = auth_headers
    else:
        kwargs['headers'].update(auth_header)
    http_req = googleapiclient.http.HttpRequest(new_http, *args, **kwargs)
    return http_req
slides_service = build('slides', 'v1', credentials=slides_creds, requestBuilder=build_request)

При выполнении я могу заметить, что kwargs передаются в HttpRequest с правильно настроенными полями авторизации, например

{'headers': {'Authorization': 'Bearer <google drive token>', ... }

Однако во время выполнения функция создания изображения (я уверен, что моя функция создания изображения работает правильно, потому что, как только я использую общедоступное изображение, например логотип Google, нет проблем с размещением изображения на странице слайдов Google), всегда возвращается код состояния 400 с сообщением ' Представленное изображение имеет неподдерживаемый формат ». Я открываю личное окно и вставляю ссылку, похоже, она все еще перенаправила запрос на вход на страницу.

Какие-либо дополнительные шаги, которые мне нужно настроить, чтобы получить эту работу? Большое спасибо за помощь.

Обновление 1:

Приведенный ниже код используется для создания соответствующего слайда и управления ресурсом на основе документа Google.

slides_scopes = ['https://www.googleapis.com/auth/drive',
                 'https://www.googleapis.com/auth/drive.file',
                 'https://www.googleapis.com/auth/drive.readonly',
                 'https://www.googleapis.com/auth/presentations',
                 'https://www.googleapis.com/auth/spreadsheets',
                 'https://www.googleapis.com/auth/spreadsheets.readonly']

drive_scopes =  ['https://www.googleapis.com/auth/drive',
                 'https://www.googleapis.com/auth/drive.appdata',
                 'https://www.googleapis.com/auth/drive.file',
                 'https://www.googleapis.com/auth/drive.metadata',
                 'https://www.googleapis.com/auth/drive.metadata.readonly',
                 'https://www.googleapis.com/auth/drive.photos.readonly',
                 'https://www.googleapis.com/auth/drive.readonly']


def auth(token_file='token.pickle', credentials_json='cred.json',scopes=[]):

    creds = None
    if os.path.exists(token_file):
        with open(token_file, 'rb') as token:
            creds = pickle.load(token)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                credentials_json, scopes)
            creds = flow.run_local_server(port=0)
        with open(token_file, 'wb') as token:
            pickle.dump(creds, token)
    return creds

slides_creds = auth(token_file='slides_t.pickle', credentials_json='slides_t.json', scopes=slides_scopes)
drive_creds = auth(token_file='drive_t.pickle', credentials_json='drive_t.json', scopes=drive_scopes)
def build_request(http, *args, **kwargs):
    import google_auth_httplib2
    new_http = google_auth_httplib2.AuthorizedHttp(credentials=drive_creds)
    auth_header = {
        'Authorization': 'Bearer '+ drive_creds.token
    }
    headers = kwargs.get('headers', {})
    if not headers:
        kwargs['headers'] = auth_headers
    else:
        kwargs['headers'].update(auth_header)
    http_req = googleapiclient.http.HttpRequest(new_http, *args, **kwargs)
    return http_req
slides_service = build('slides', 'v1', credentials=slides_creds, requestBuilder=build_request)
drive_service = build('drive', 'v3', credentials=drive_creds)

Обновление 2:

При переключении на показ изображения с помощью локального http-сервера (он доступен с http://<intranet ip or localhost>:<port>/path/to/img.png, API слайдов Google возвращает следующую ошибку

"Invalid requests[0].createImage: There was a problem retrieving the image. The provided image should be publicly accessible, within size limit, and in supported formats."

Это заставляет меня задуматься, возможно, API слайдов Google больше не позволяет получить доступ к webContentLink со специальным разрешением (например, доменом). Вместо этого разрешен только общедоступный URL.

Обновление 3:

  • Параметры функции create_image:

    • slide_object_id: g6f1c6c22f2

      https://stackoverflow.com/questions/60160794/getting-the-provided-image-is-in-an-unsupported-format-error-when-trying-to-in
      
      69

    • web_content_link: https://drive.google.com/a/ {{domain name}} / uc? id = {{id изображения}} & export = скачать

    • size: {'height': {'magnitude': 10800, 'unit': 'EMU'}, 'width': {'magnitude': 19800, 'unit': 'EMU'}}

    • преобразовать: {'scaleY': 171.9097, 'scaleX': 212.4558, 'translateY': 937125, 'translateX': 2347875, 'unit': 'EMU'}

  • функция создания изображения

    def create_image(slides_service=None, slide_object_id=None, web_content_link=None, size_height_magnitude=4000000, size_width_magnitude=4000000,  transform_scale_x=1,  transform_scale_y=1, transform_translate_x=100000,  transform_translate_y=100000):
        requests = []
        requests.append({
            'createImage': {
                'url': web_content_link,
                'elementProperties': {
                    'pageObjectId': slide_object_id,
                    'size': {
                        'height': {
                            'magnitude': size_height_magnitude,
                            'unit': 'EMU'
                        },
                        'width': {
                            'magnitude': size_width_magnitude,
                            'unit': 'EMU'
                        }
                    },
                    'transform': {
                        'scaleX': transform_scale_x,
                        'scaleY': transform_scale_y,
                        'translateX': transform_translate_x,
                        'translateY': transform_translate_y,
                        'unit': 'EMU'
                    }
                }
            }
        })
        body = {
            'requests': requests
        }
        response = slides_service.presentations() \
            .batchUpdate(presentationId=presentation_id, body=body).execute()
        return response.get('replies')[0].get('createImage')
    

person Richard Jackson    schedule 08.04.2020    source источник
comment
Не могли бы вы поделиться кодом, связанным с вашим запросом, с slides_service?   -  person Iamblichus    schedule 09.04.2020
comment
@Iamblichus Извините, что ответил с опозданием. Обновляю код в разделе обновлений. В основном код следует (скопировать / вставить с некоторыми изменениями) за документом Google без каких-либо существенных изменений.   -  person Richard Jackson    schedule 13.04.2020
comment
Я имел в виду, если бы вы могли поделиться самим вызовом API, то есть телом и параметрами, которые вы предоставляете для запроса, а также методом, который вы используете. Я предполагаю, что вы делаете batchUpdate: createImage, но было бы полезно знать, какие параметры и тело вы предоставляете. Я не вижу этого в предоставленном вами коде.   -  person Iamblichus    schedule 14.04.2020
comment
Параметры, переданные в createImage API, и функция находятся в разделе «Обновление 3». Пожалуйста, дайте мне знать, если потребуется дополнительная информация.   -  person Richard Jackson    schedule 14.04.2020


Ответы (1)


Проблема:

На слайд можно добавлять только изображения с общедоступным URL-адресом. Недостаточно поделиться изображением с учетной записью, из которой сделан запрос. Как вы можете видеть в официальной документации:

Если вы хотите добавить к слайду частные или локальные изображения, сначала необходимо сделать их доступными по общедоступному URL.

Обходные пути:

  • Как объясняется в ответе Танаике, вы могли бы: (1) опубликовать изображение публично, (2) добавить изображение на слайд, используя общедоступный URL-адрес, и (3) удалите Разрешение, созданное на шаге 1. Таким образом, изображение станет общедоступным только в течение короткого времени, которое требуется программе для выполнения шагов 2 и 3.

  • Другой вариант, представленный в указанной документации, - это:

загрузите изображения в Google Cloud Storage и используйте подписанные URL-адреса с периодом жизни 15 минут. Загруженные изображения автоматически удаляются через 15 минут.

Ссылка:

person Iamblichus    schedule 15.04.2020
comment
Благодарю за информацию. Вот как я проверял, работает ли функция добавления изображения слайдов Google (временно разрешите общедоступный URL-адрес, а затем удалите это разрешение с логотипом Google для Instatnce); и это сработало без проблем. Но это действительно заставляет меня задуматься, если у пользователя, у которого есть требование о том, что изображения не могут быть общедоступными, остается единственный вариант - временно сделать изображение общедоступным, а затем удалить это разрешение - мне кажется, такая операция просто увеличит риск ( утечка деловой информации). В любом случае спасибо за информацию. - person Richard Jackson; 23.04.2020
comment
@RichardJackson, пожалуйста. Также помните, что вы можете принять ответы, которые считаете полезными. Это полезно, потому что другие пользователи могут столкнуться с этой проблемой. StackOverflow полагается на это, чтобы делиться знаниями с другими пользователями. - person Iamblichus; 23.04.2020