Использование Google API для создания и публикации электронной таблицы - PullRequest
0 голосов
/ 19 ноября 2018

У меня есть скрипт, через который я пытаюсь передать данные, который создаст электронную таблицу Google и поделится ею с группой людей.У меня проблема с ошибкой, которая отклоняет мои разрешения, хотя я не знаю почему.

Я прошел консоль разработчика Google, создал проект и включил API-интерфейсы электронных таблиц и диск.апи.Я загрузил один набор учетных данных oauth2 и назвал его «credentials.json»

. Оттуда я написал этот скрипт на основе примеров API Google, используя листы v4 и версии дисков v3:

from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

SCOPES = ['https://www.googleapis.com/auth/drive',
          'https://www.googleapis.com/auth/spreadsheets']
CREDENTIALS = r'google_api\credentials.json'
TEST_ADD_EMAIL = <the test gmail address>

class GoogleManager:
    def __init__(self):
        self.sheets_service = None
        self.drive_service = None

    def connect(self):
        store = file.Storage(r'google_api\token.json')
        creds = store.get()

        if not creds or creds.invalid:
            flow = client.flow_from_clientsecrets(CREDENTIALS, SCOPES)
            creds = tools.run_flow(flow, store)

        self.sheets_service = build('sheets', 'v4', http=creds.authorize(Http()))
        self.drive_service = build('drive', 'v3', http=creds.authorize(Http()))

    def drive_add_writer_perm(self, fileId, emails):
        def callback(request_id, response, exception):
            if exception:
                raise exception
            else:
                print(f"Permission Id: {response.get('id')}")

        if isinstance(emails, str):
            emails = [emails]
        elif not isinstance(emails, (list,tuple)):
            raise TypeError('Emails must be str or list-like object')

        batch = self.drive_service.new_batch_http_request(callback=callback)
        for email in emails:
            user_permission = ({'type': 'user',
                                'role': 'writer',
                                'emailAddress': email
                                })
            batch.add(self.drive_service.permissions().create(fileId=fileId,
                                                      body=user_permission,
                                                      fields='id'))
        res = batch.execute()
        return res

    def create_new_sheet(self, workbook_name):
        spreadsheet = {'properties': {'title': workbook_name}
                       }
        gSheet = self.sheets_service.spreadsheets()
        newsheet = gSheet.create(body=spreadsheet, fields='spreadsheetId').execute()
        return newsheet

Оттуда я запускаю:

gmanager = GoogleManager()
gmanager.connect()

new_sheet = gmanager.create_new_sheet('Test Sheet')

sheet_id = new_sheet.get('spreadsheetId')
gmanager.drive_add_writer_perm(sheet_id, TEST_ADD_EMAIL)

Но я получаю эту ошибку:

raise HttpError(resp, content, uri=request.uri).errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/drive/v3/files/1PuxZR0Cx2tGi7c1worVc_Ivj9kZijq_xwwndix6I9as/permissions?fields=id&alt=json returned "Insufficient Permission">

Может кто-нибудь объяснить, почему?Что я делаю неправильно?

edit: когда я перехожу по этой ссылке в исключении, мне дают следующий ответ:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "required",
    "message": "Login Required",
    "locationType": "header",
    "location": "Authorization"
   }
  ],
  "code": 401,
  "message": "Login Required"
 }
}

Я не получаю экран входа, что происходит?

1 Ответ

0 голосов
/ 19 ноября 2018

После небольшой игры кажется, что создание двух сервисов одновременно не рекомендуется.Я не могу объяснить, почему, и, надеюсь, кто-то может, но построив оба, а затем вызвав один раньше другого, другой сервис не работает.

Изменение моего кода на это работает:

from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

SCOPES = ['https://www.googleapis.com/auth/drive',
          'https://www.googleapis.com/auth/spreadsheets']
CREDENTIALS = r'google_api\credentials.json'
TEST_ADD_EMAIL = <my_test_email>

class GoogleManager:
    def __init__(self):
        self.store = None
        self.flow = None
        self.creds = None

    def connect(self):
        self.store = file.Storage(r'google_api\token.json')
        self.creds = self.store.get()

        if not self.creds or self.creds.invalid:
            self.flow = client.flow_from_clientsecrets(CREDENTIALS, SCOPES)
            self.creds = tools.run_flow(self.flow, self.store)

    def add_writer_perm(self, fileId, email):
        def callback(request_id, response, exception):
            if exception:
                raise exception
            else:
                print(f"Permission Id: {response.get('id')}")

        user_permission = ({'type': 'user',
                            'role': 'writer',
                            'emailAddress': email
                            })
        drive_service = build('drive', 'v3', http=self.creds.authorize(Http()))
        res = drive_service.permissions().create(fileId=fileId,
                                                  body=user_permission,
                                                  fields='id').execute()
        return res

    def create_new_sheet(self, workbook_name):
        spreadsheet = {'properties': {'title': workbook_name}
                       }
        sheets_service = build('sheets', 'v4', http=self.creds.authorize(Http()))
        gSheet = sheets_service.spreadsheets()
        newsheet = gSheet.create(body=spreadsheet, fields='spreadsheetId').execute()
        return newsheet


def main():
    gmanager = GoogleManager()
    gmanager.connect()

    new_sheet = gmanager.create_new_sheet('Test Sheet')
    sheet_id = new_sheet.get('spreadsheetId')

    gmanager.drive_add_writer_perm(sheet_id, TEST_ADD_EMAIL)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...