Права доступа к API Google с использованием Python - PullRequest
0 голосов
/ 24 сентября 2019

Мне нужно сделать некоторые функции для разных пользователей моего сайта, чтобы автоматически загружать html-файлы на диск Google и открывать их для просмотра и редактирования в документах Google.Для этого я создаю документ, передаю его на диск Google и использую идентификатор созданного документа, чтобы открыть его в Google Docs.
Для доступа к API я использую файл json, взятый из учетной записи службы Google.Я пытался выполнить свой код с правами владельца и , но результат тот же.

class CvView(AuthorizedMixin, View):
    """Here I check if the file format is html, I temporarily save it on disk and pass it to the file_to_drive function (to save it to google disk and open it in google docs) and delete it from disk"""


    def get(self, request, employee_id, format_):
        """Returns employee's CV in format which is equal to `format_`
        parameter."""

        employee = get_object_or_404(Employee, pk=employee_id)
        user = request.user
        content_type, data = Cv(employee, format_, user).get()

        if isinstance(data, BytesIO):
            return FileResponse(
                data, as_attachment=True, filename=f'cv.{format_}',
                content_type=content_type)
        if content_type == 'text/html':
            try:
                name = uuid.uuid4().hex + '.html'
                with open(name, 'w+') as output:
                    output.write(str(data))
                return HttpResponseRedirect(file_to_drive(import_file=name))
            finally:
                os.remove(os.path.join(settings.BASE_DIR, name))
        return HttpResponse(data, content_type=content_type)

file_to_drive

from google.oauth2 import service_account
from django.conf import settings
from googleapiclient.discovery import build

SCOPES = [
    'https://www.googleapis.com/auth/documents',
    'https://www.googleapis.com/auth/drive',
]
ACCOUNT_FILE = os.path.join(settings.BASE_DIR, 'cv-base-gapi.json')
def file_to_drive(import_file=None):
    credentials=service_account.Credentials.from_service_account_file(ACCOUNT_FILE, scopes=SCOPES)
    service = build('drive', 'v3', credentials=credentials)
    file_metadata = {
        'name': 'My Report',
        'mimeType': 'application/vnd.google-apps.spreadsheet'
    }
    media = MediaFileUpload(import_file,
                            mimetype='text/html',
                            resumable=True)
    file = service.files().create(body=file_metadata,
                                        media_body=media,
                                        fields='id').execute()
    print('File ID: %s' % file.get('id'))
    return (f"https://docs.google.com/document/d/{file.get('id')}/edit")

И, похоже, работает, но есть неясный момент.

Прежде всего, я не вижу сохраненный файл на диске Google, но строка print('File ID: %s' % file.get('id')) дает мне идентификатор нового документа.

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

enter image description here

1 Ответ

1 голос
/ 25 сентября 2019
  • Вы хотите создать новый документ Google из данных HTML.
  • Вы хотите, чтобы пользователи просматривали и редактировали созданный документ Google.
  • Вы используете учетную запись службы для этогоситуация.
  • Вы хотите добиться этого с помощью google-api-python-client с Python.

Я могу понять вашу ситуацию, как описано выше.И у вашего вопроса есть 2 вопроса.

  1. Вы хотите узнать причину, по которой созданный Документ Google нельзя увидеть на вашем Google Диске.
  2. Вы хотите узнать причину, по которой разрешениятребуется открыть созданный документ.

Если мое понимание верно, как насчет этого ответа?Пожалуйста, подумайте об этом как об одном из нескольких ответов.

Проблема:

В качестве основной причины ваших обоих вопросов, я думаю, что использование учетной записи службы является причиной.Учетная запись службы отличается от вашей собственной учетной записи Google.Так, например, когда файл создается учетной записью службы, файл создается в Google Диске учетной записи службы.При этом файл не может быть виден на вашем диске Google.Я думаю, что это ответ на ваш вопрос 1. И файл, созданный на Google Диске служебной учетной записи, не может быть доступен напрямую, потому что только служебная учетная запись может получить к нему доступ.Я думаю, что это ответ на ваш вопрос 2.

Решение:

Чтобы увидеть созданный Документ Google на вашем Google Диске и заставить пользователей просматривать и редактировать созданный Документ Google, яхотел бы предложить добавить разрешения к созданному Документу Google с помощью Permissions: create in Drive API.Когда это отражается на вашем скрипте, оно становится следующим:

Модифицированный скрипт:

Пожалуйста, измените ваш скрипт следующим образом.

С:
def file_to_drive(import_file=None):
    credentials=service_account.Credentials.from_service_account_file(ACCOUNT_FILE, scopes=SCOPES)
    service = build('drive', 'v3', credentials=credentials)
    file_metadata = {
        'name': 'My Report',
        'mimeType': 'application/vnd.google-apps.spreadsheet'
    }
    media = MediaFileUpload(import_file,
                            mimetype='text/html',
                            resumable=True)
    file = service.files().create(body=file_metadata,
                                        media_body=media,
                                        fields='id').execute()
    print('File ID: %s' % file.get('id'))
    return (f"https://docs.google.com/document/d/{file.get('id')}/edit")
Кому:
def file_to_drive(import_file=None):
    credentials=service_account.Credentials.from_service_account_file(ACCOUNT_FILE, scopes=SCOPES)
    service = build('drive', 'v3', credentials=credentials)
    file_metadata = {
        'name': 'My Report',
        'mimeType': 'application/vnd.google-apps.document'  # Modified
    }
    media = MediaFileUpload(import_file,
                            mimetype='text/html',
                            resumable=True)
    file = service.files().create(body=file_metadata,
                                        media_body=media,
                                        fields='id').execute()
    fileId = file.get('id')  # Added
    print('File ID: %s' % fileId)

    # --- I added below script.
    permission1 = {
        'type': 'user',
        'role': 'writer',
        'emailAddress': '###',  # Please set your email of Google account.
    }
    service.permissions().create(fileId=fileId, body=permission1).execute()
    permission2 = {
        'type': 'anyone',
        'role': 'writer',
    }
    service.permissions().create(fileId=fileId, body=permission2).execute()
    # ---

    return (f"https://docs.google.com/document/d/{file.get('id')}/edit")
  • В этой модификации после создания Документа Google разрешения добавляются в созданный Документ.
    • На permission1 ваша учетная запись добавляется в качестве автора.Таким образом, вы можете увидеть созданный Документ на вашем Google Диске.Пожалуйста, укажите свой адрес электронной почты учетной записи Google здесь.
    • На permission2, чтобы пользователи могли просматривать и редактировать созданный Документ, разрешение добавляется в виде anyone.Это контрольный пример. Если вы хотите добавить электронные письма пользователя в качестве разрешений, установите их как permission1.

Примечание:

  • Если вы хотите создать Документ Google, измените значение application/vnd.google-apps.spreadsheet на application/vnd.google-apps.document.Но в вашем случае, когда text/html конвертируется в application/vnd.google-apps.spreadsheet, он автоматически конвертируется в application/vnd.google-apps.document.Поскольку text/html можно преобразовать в application/vnd.google-apps.document.

Ссылка:

Если я неправильно понял ваш вопрос, а это не то направление, которое вы хотите, я прошу прощения.

...