Прежде всего создаем сервисный аккаунт в консоли Google Cloud и для email сервисного аккаунта открываем доступ на редактирование необходимых папок. Не забудьте добавить в папку файлы, если их там нет, потому что файл нам понадобится, когда мы будем выполнять первый пример - скачивание файлов из Google Drive.

Как сделать сервисный аккаунт - https://youtu.be/Lxxge05UP8M

Сначала устанавливаем клиентскую библиотеку Google API для Python pip install --upgrade google-api-python-client

In [ ]:
!pip install --upgrade google-api-python-client

И импортируем нужные модули или отдельные функции из библиотек.

Ниже будет небольшое описание импортируемых модулей. Это для тех кто хочет понимать, что импортирует, но большинство просто может скопировать импорты и вставить в ноутбук :)

Модуль service_account (https://github.com/googleapis/google-auth-library-python/blob/master/google/oauth2/service_account.py) из google.oauth2 понадобится нам для авторизации с помощью сервисного аккаунта. Классы MediaIoBaseDownload и MediaFileUpload, как ясно из названий, пригодятся, чтобы скачать или загрузить файлы. Эти классы импортируются из googleapiclient.http (https://github.com/googleapis/google-api-python-client/blob/master/googleapiclient/http.py) Функция build из googleapiclient.discovery (https://github.com/googleapis/google-api-python-client/blob/master/googleapiclient/discovery.py) позволяет создать ресурс для обращения к API, то есть это некая абстракция над REST API (https://developers.google.com/drive/api/v3/about-sdk), чтобы удобнее обращаться к методам API

In [1]:
from google.oauth2 import service_account
from googleapiclient.http import MediaIoBaseDownload,MediaFileUpload
from googleapiclient.discovery import build
import pprint
import io

pp = pprint.PrettyPrinter(indent=4)

Указываем Scopes. Scopes - это перечень возможностей, которыми будет обладать сервис, созданный в скрипте. Ниже приведены Scopes, которые относятся к API Google Drive (из официальной документации https://developers.google.com/identity/protocols/googlescopes). 01_drive_scopes.png Как видно, разные Scope предоставляют разный уровень доступа к данным. Нас интересует Scope "https://www.googleapis.com/auth/drive", который позволяет просматривать, редактировать, удалять или создавать файлы на Google Диске.

Также указываем в переменной SERVICE_ACCOUNT_FILE путь к файлу с ключами сервисного аккаунта.

In [2]:
SCOPES = ['https://www.googleapis.com/auth/drive']
SERVICE_ACCOUNT_FILE = '/home/makarov/local-grove-232309-ba66e9c14c1f.json'

Создаем Credentials (учетные данные), указав путь к сервисному аккаунту, а также заданные Scopes. А затем создаем сервис, который будет использовать 3ю версию REST API Google Drive, отправляя запросы из-под учетных данных credentials.

In [3]:
credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

service = build('drive', 'v3', credentials=credentials)

Теперь можно получить список файлов и папок, к которым имеет доступ сервис. Для этого выполним запрос list, выдающий список файлов, со следующими параметрами:

  • pageSize - количество результатов выдачи. Можете смело ставить максимальное значение 1000. У меня стоит 10 результатов, чтобы показать как быть, когда нужно получить результаты по следующей страницы результатов
  • параметр files() в fields - параметр, указывающий, что нужно возвращать список файлов, где в скобках указан список полей для файлов, которые нужно показывать в результатах выдачи. Со всеми возможными полями можно познакомиться в документации (https://developers.google.com/drive/api/v3/reference/files) в разделе "Valid fields for files.list". У меня указаны поля для файлов: id (идентификатор файла в Drive), name (имя) и mimeType (тип файла). Чуть дальше мы рассмотрим пример запроса с большим количеством полей
  • nextPageToken в fields - это токен следующей страницы, если все результаты не помещаются в один ответ
In [4]:
results = service.files().list(pageSize=10,
                               fields="nextPageToken, files(id, name, mimeType)").execute()

Получили вот такие результаты

In [5]:
pp.pprint(results)
{   'files': [   {   'id': '1xq6Ler0ypPimEFMxer_wtYlklNB7MCBoM6aSZft5dAc',
                     'mimeType': 'application/vnd.google-apps.spreadsheet',
                     'name': 'Sheet from csv'},
                 {   'id': '0B7TyWvrAtxvgc3RhcnRlcl9maWxl',
                     'mimeType': 'application/pdf',
                     'name': 'Getting started'},
                 {   'id': '1uuecd6ndiZlj3d9dSVeZeKyEmEkC7qyr',
                     'mimeType': 'application/vnd.google-apps.folder',
                     'name': 'Folder'},
                 {   'id': '1HKC4U1BMJTsonlYJhUKzM-ygrIVGzdBr',
                     'mimeType': 'text/csv',
                     'name': 'Data.csv'},
                 {   'id': '10MM2f3V98wTu7GsoZSxzr9hkTGYvq_Jfb2HACvB9KjE',
                     'mimeType': 'application/vnd.google-apps.spreadsheet',
                     'name': 'Sheet'},
                 {   'id': '1fWhi4Jigrwl5oY_iJw9KJ-Eqr7D71UkY',
                     'mimeType': 'application/octet-stream',
                     'name': 'Dashboard.pbix'},
                 {   'id': '1NL1V_32OtQfB7zqe6t-xvTbbLQYXv6WYn5oPCpbPlPM',
                     'mimeType': 'application/vnd.google-apps.presentation',
                     'name': 'Great data'},
                 {   'id': '1RCTL5RyvTO2N5YYZHvB6xVqOgmpMVi5Z',
                     'mimeType': 'text/plain',
                     'name': 'Query_2.sql'},
                 {   'id': '1zV9hyUJpCKiz2KNksyLH4JPMeX0H3e93',
                     'mimeType': 'text/csv',
                     'name': 'data (4).csv'},
                 {   'id': '1oVSIGdm37p73MRb6ZFu5b0Nu2WsNallG',
                     'mimeType': 'text/csv',
                     'name': 'data.csv'}],
    'nextPageToken': '~!!~AI9FV7TeUokGsREbeTF26g2i2s7iQLD3phGpP-R1uTPIKLMTborvzj2sMiYYIkLRq8gV6ddiGSB8F635Lib8dAAeWnkTCQ_ydfDKHa6hhVAsy_DEfjNKvGDdKBwm0s4ME2HFox_glSWG4tIFLHqDJwaIOWCeeWhoTd95UgCAXqRyYuP7bn8LaIRmTY6aRRcP9gUMDvbCrmJ1OuqeGZZrYBwy04s3mkmgbASixrLIlE6W11_zayVIsbQ7awocrjqA4LkJvrIixB8Khe6wJuDbr0K7SBVkSN2BSgGMno85mKKB1jrzRz_BO9Veu9w6UNo4BBP7622LjUjYGeOKAULsJZVrLhMSZQXreh3ma26YzZ9x8knqZd74pY07737ermtZ-JRm2gDFwGLF'}
In [6]:
print(len(results.get('files')))
10

Получив из результатов nextPageToken мы можем передать его в следущий запрос в параметре pageToken, чтобы получить результаты следующей страницы. Если в результатах будет nextPageToken, это значит, что есть ещё одна или несколько страниц с результатами

In [7]:
nextPageToken = results.get('nextPageToken')
results_for_next_page = service.files().list(pageSize=10,
                               fields="nextPageToken, files(id, name, mimeType)",
                               pageToken=nextPageToken).execute()
print (results_for_next_page.get('nextPageToken'))
~!!~AI9FV7TeUokGsREbeTF26g2i2s7isfxV23d97r1_sbiwijI5J8KEW4bunZPFAOkihbDOmmzPJWXnGAfGeKjXPaslWWpbf3wmA3v2aRuZDAIxU_hFQceBEsE5H5b442BMyN53F0bCL-IYD7Hm3CjuVhtBLJfAwP7WEQxktiTNBfKS03TxdPcSwgo_fI2YH5MGPoy29AJetqc28uC0QAhZ_ARrEIIJY6H27AxAlzeY8AGQgv2wOruRZv_C2YlwshsLcDBEpTQ8nMTrGhFE78hW1X7lhUqvxR9orrM6E39fNY8mLhksNLsSyneBl0Iq0vhcC5xzh3dxPZPENQp3-ONJtY4QQ6qGIO2f6t68UQDxAo5Z_nZGO1DjfNonUTzulNKihzLiBPYqr9TN

Таким образом, мы можем сделать цикл, который будет выполняться до тех пор, пока в результатах ответа есть nextPageToken. Внутри цикла будем выполнять запрос для получения результатов страницы и сохранять результаты к первым полученным результатам

In [8]:
results = service.files().list(pageSize=10,
                               fields="nextPageToken, files(id, name, mimeType)").execute()
nextPageToken = results.get('nextPageToken')
while nextPageToken:
        nextPage = service.files().list(pageSize=10,
                                        fields="nextPageToken, files(id, name, mimeType, parents)",
                                        pageToken=nextPageToken).execute()
        nextPageToken = nextPage.get('nextPageToken')
        results['files'] = results['files'] + nextPage['files']
print(len(results.get('files')))
25

Дальше давайте рассмотрим какие ещё поля можно использовать для списка возвращаемых файлов. Как я уже писал выше, со всеми полями можно ознакомиться по ссылке https://developers.google.com/drive/api/v3/reference/files. Давайте рассмотрим самые полезные из них:

  • parents - ID папки, в которой расположен файл/подпапка
  • createdTime - дата создания файла/папки
  • permissions - перечень прав доступа к файлу
  • quotaBytesUsed - сколько места от квоты хранилища занимает файл (в байтах)
In [9]:
results = service.files().list(
        pageSize=10, fields="nextPageToken, files(id, name, mimeType, parents, createdTime, permissions, quotaBytesUsed)").execute()

Отобразим один файл из результатов с расширенным списком полей. Как видно permissions содержит информацию о двух юзерах, один из которых имеет role = owner, то есть владелец файла, а другой с role = writer, то есть имеет право записи.

In [10]:
pp.pprint(results.get('files')[0])
{   'createdTime': '2019-02-20T10:58:34.010Z',
    'id': '1xq6Ler0ypPimEFMxer_wtYlklNB7MCBoM6aSZft5dAc',
    'mimeType': 'application/vnd.google-apps.spreadsheet',
    'name': 'Sheet from csv',
    'parents': ['1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ'],
    'permissions': [   {   'deleted': False,
                           'displayName': 'mamby-pamby',
                           'emailAddress': '[email protected]',
                           'id': '08455172423570013795',
                           'kind': 'drive#permission',
                           'role': 'writer',
                           'type': 'user'},
                       {   'deleted': False,
                           'displayName': 'Alexey Makarov',
                           'emailAddress': '[email protected]',
                           'id': '15194547887078870598',
                           'kind': 'drive#permission',
                           'photoLink': 'https://lh3.googleusercontent.com/a-/AAuE7mC0AQU5BwnLOBCG2aXOFeYMZLn4DzvfXC3NFTLp7g=s64',
                           'role': 'writer',
                           'type': 'user'},
                       {   'deleted': False,
                           'displayName': 'namby-pamby',
                           'emailAddress': '[email protected]',
                           'id': '13173508647601803619',
                           'kind': 'drive#permission',
                           'role': 'writer',
                           'type': 'user'},
                       {   'deleted': False,
                           'displayName': '[email protected]',
                           'emailAddress': '[email protected]',
                           'id': '10834532000195393990',
                           'kind': 'drive#permission',
                           'role': 'owner',
                           'type': 'user'}],
    'quotaBytesUsed': '0'}

Очень удобная штука, позволяющая сократить количество результатов в запросе, чтобы получать только то, что действительно нужно - это возможность задать параметры поиска для файлов. Например, мы можем задать в какой папке искать файлы, зная её id:

In [11]:
results = service.files().list(
    pageSize=5, 
    fields="nextPageToken, files(id, name, mimeType, parents, createdTime)",
    q="'1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ' in parents").execute()
pp.pprint(results['files'])
[   {   'createdTime': '2019-02-20T10:58:34.010Z',
        'id': '1xq6Ler0ypPimEFMxer_wtYlklNB7MCBoM6aSZft5dAc',
        'mimeType': 'application/vnd.google-apps.spreadsheet',
        'name': 'Sheet from csv',
        'parents': ['1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ']},
    {   'createdTime': '2019-02-19T15:16:27.052Z',
        'id': '1RCTL5RyvTO2N5YYZHvB6xVqOgmpMVi5Z',
        'mimeType': 'text/plain',
        'name': 'Query_2.sql',
        'parents': ['1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ']},
    {   'createdTime': '2019-02-19T15:16:08.602Z',
        'id': '1zV9hyUJpCKiz2KNksyLH4JPMeX0H3e93',
        'mimeType': 'text/csv',
        'name': 'data (4).csv',
        'parents': ['1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ']},
    {   'createdTime': '2019-02-19T15:16:08.602Z',
        'id': '1oVSIGdm37p73MRb6ZFu5b0Nu2WsNallG',
        'mimeType': 'text/csv',
        'name': 'data.csv',
        'parents': ['1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ']},
    {   'createdTime': '2019-02-19T15:16:08.602Z',
        'id': '1dLFxGYn198eIpdrPoD47b0BhHT9umWeJ',
        'mimeType': 'text/csv',
        'name': 'data (2).csv',
        'parents': ['1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ']}]

С особенностями функционирования поиска можно ознакомиться в документации (https://developers.google.com/drive/api/v3/search-parameters). Ещё один удобный способ поиска нужных файлов - по имени. Вот пример запроса, где мы ищем все файлы, содержащие в названии "data":

In [12]:
results = service.files().list(
    pageSize=10, 
    fields="nextPageToken, files(id, name, mimeType, parents, createdTime)",
    q="name contains 'data'").execute()
pp.pprint(results['files'])
[   {   'createdTime': '2019-02-19T15:38:59.907Z',
        'id': '1HKC4U1BMJTsonlYJhUKzM-ygrIVGzdBr',
        'mimeType': 'text/csv',
        'name': 'Data.csv',
        'parents': ['1uuecd6ndiZlj3d9dSVeZeKyEmEkC7qyr']},
    {   'createdTime': '2019-02-19T15:22:16.418Z',
        'id': '1NL1V_32OtQfB7zqe6t-xvTbbLQYXv6WYn5oPCpbPlPM',
        'mimeType': 'application/vnd.google-apps.presentation',
        'name': 'Great data',
        'parents': ['1uuecd6ndiZlj3d9dSVeZeKyEmEkC7qyr']},
    {   'createdTime': '2019-02-19T15:16:08.602Z',
        'id': '1zV9hyUJpCKiz2KNksyLH4JPMeX0H3e93',
        'mimeType': 'text/csv',
        'name': 'data (4).csv',
        'parents': ['1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ']},
    {   'createdTime': '2019-02-19T15:16:08.602Z',
        'id': '1oVSIGdm37p73MRb6ZFu5b0Nu2WsNallG',
        'mimeType': 'text/csv',
        'name': 'data.csv',
        'parents': ['1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ']},
    {   'createdTime': '2019-02-19T15:16:08.602Z',
        'id': '1dLFxGYn198eIpdrPoD47b0BhHT9umWeJ',
        'mimeType': 'text/csv',
        'name': 'data (2).csv',
        'parents': ['1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ']},
    {   'createdTime': '2019-02-19T15:16:08.602Z',
        'id': '1bYubUxVCNXm0l2R8bckITKCeymxaBBX8',
        'mimeType': 'text/csv',
        'name': 'data (5).csv',
        'parents': ['1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ']},
    {   'createdTime': '2019-02-19T15:16:08.602Z',
        'id': '1udviwdMiKrzTAXb4SulJQ10-mczy5m3V',
        'mimeType': 'text/csv',
        'name': 'data (3).csv',
        'parents': ['1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ']},
    {   'createdTime': '2019-02-19T15:16:07.316Z',
        'id': '1HLIzBEdsb3uozK6OTuX1Mexhy0kSKnVv',
        'mimeType': 'text/csv',
        'name': 'data (1).csv',
        'parents': ['1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ']}]

Условия поиска можно комбинировать. Возьмем условие поиска в папке и совместим с условием поиска по названию:

In [13]:
results = service.files().list(
    pageSize=10, 
    fields="nextPageToken, files(id, name, mimeType, parents, createdTime)",
    q="'1uuecd6ndiZlj3d9dSVeZeKyEmEkC7qyr' in parents and name contains 'data'").execute()
pp.pprint(results['files'])
[   {   'createdTime': '2019-02-19T15:38:59.907Z',
        'id': '1HKC4U1BMJTsonlYJhUKzM-ygrIVGzdBr',
        'mimeType': 'text/csv',
        'name': 'Data.csv',
        'parents': ['1uuecd6ndiZlj3d9dSVeZeKyEmEkC7qyr']},
    {   'createdTime': '2019-02-19T15:22:16.418Z',
        'id': '1NL1V_32OtQfB7zqe6t-xvTbbLQYXv6WYn5oPCpbPlPM',
        'mimeType': 'application/vnd.google-apps.presentation',
        'name': 'Great data',
        'parents': ['1uuecd6ndiZlj3d9dSVeZeKyEmEkC7qyr']}]

Теперь рассмотрим как скачивать файлы из Google Drive. Для этого нам понадобится создать запрос request для получения файла. После этого задаем интерфейс fh для записи в файл с помощью библиотеки io, указав в filename название файла (таким образом, можно сохранять файлы из Google Drive сразу с другим названием). Затем создаем экземпляр класса MediaIoBaseDownload, передав наш интерфейс для записи файла fh и запрос для скачивания файла request. Следующим шагом скачиваем файл по небольшим кусочкам (чанкам) с помощью метода next_chunk.

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

In [14]:
file_id = '1HKC4U1BMJTsonlYJhUKzM-ygrIVGzdBr'
request = service.files().get_media(fileId=file_id)
filename = '/home/makarov/File.csv'
fh = io.FileIO(filename, 'wb')
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
    status, done = downloader.next_chunk()
    print ("Download %d%%." % int(status.progress() * 100))
Download 100%.

Файлы Google Sheets или Google Docs можно конвертировать в другие форматы, указав параметр mimeType в функции export_media (обратите внимание, что в предыдущем примере скачивания файла мы использоали другую функцию get_media). Например, файл Google Sheets можно конвертировать и скачать в виде файла Excel.

In [15]:
file_id = '10MM2f3V98wTu7GsoZSxzr9hkTGYvq_Jfb2HACvB9KjE'
request = service.files().export_media(fileId=file_id,
                                             mimeType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
filename = '/home/makarov/Sheet.xlsx'
fh = io.FileIO(filename, 'wb')
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
    status, done = downloader.next_chunk()
    print ("Download %d%%." % int(status.progress() * 100))
Download 100%.

Затем скачанный файл можно загнать в датафрейм. Это достаточно простой способ получить данные из Google Sheet в pandas-dataframe, но есть и другие способы, например, воспользоваться библиотекой gspread (https://riptutorial.com/pandas/example/24056/collect-google-spreadsheet-data-into-pandas-dataframe).

In [16]:
import pandas as pd
df = pd.read_excel('/home/makarov/Sheet.xlsx')
df.head(5)
Out[16]:
id count
0 .p43DqAlRavBbg1oDFSFzu 98
1 5NAEhw4KIcYpCdNzA/6xcu 24
2 HGnqYBm9w1egayK9eDHgBe 12
3 h52zj8PC1XJ1naMxhUyqE. 11
4 JbPx9urrduW6335HK4ljiu 10

Рассмотрим простой пример загрузки файла в папку. Во-первых, нужно указать folder_id - id папки (его можно получить в адресной строке браузера, зайдя в папку, либо получив все файлы и папки методом list). Также нужно указать название name, с которым файл загрузится на Google Drive. Это название может быть отличным от исходного названия файла. Параметры folder_id и name передаем в словарь file_metadata, в котором задаются метаданные загружаемого файла. В переменной file_path указываем путь к файлу. Создаем объект media, в котором будет указание по какому пути находится загружаемый файл, а также указание, что мы будем использовать возобновляемую загрузку, что позволит нам загружать большие файлы. Google рекомендует (https://developers.google.com/drive/api/v3/manage-uploads) использовать этот тип загрузки для файлов больше 5 мегабайт. Затем выполняем функцию create, которая позволит загрузить файл на Google Drive.

In [22]:
folder_id = '1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ'
name = 'Script_2.py'
file_path = '/home/makarov/Script.py'
file_metadata = {
                'name': name,
                'parents': [folder_id]
            }
media = MediaFileUpload(file_path, resumable=True)
r = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
pp.pprint(r)
{'id': '1i4k58QfB7TxhUcAHYo_vGHR1SjRy3Gub'}

Как видно выше, при вызове функции create возвращается id созданного файла. Можно удалить файл, вызвав функцию delete. Но мы этого делать не будет так как файл понадобится в следующем примере

In [19]:
service.files().delete(fileId='1GDvLONfizF6VR7DKQaZsg_Wpdh2GFD5f').execute()
Out[19]:
''

Сервисный аккаунт может удалить ли те файлы, которые были с помощью него созданы. Таким образом, даже если у сервисного аккаунта есть доступ на редактирование папки, то он не может удалить файлы, созданные другими пользователями. Понять что файл был создан помощью сервисного аккаунта можно задав поисковое условие с указанием email нашего сервисного аккаунта. Узнать email сервисного аккаунта можно вызвав атрибут signer_email у объекта credentials

In [20]:
print (credentials.signer_email)
In [24]:
results = service.files().list(
    pageSize=10, 
    fields="nextPageToken, files(id, name, mimeType, parents, createdTime)",
    q="'[email protected]' in owners").execute()
pp.pprint(results['files'][0:3])
[   {   'createdTime': '2019-02-20T11:09:17.156Z',
        'id': '1i4k58QfB7TxhUcAHYo_vGHR1SjRy3Gub',
        'mimeType': 'text/x-python',
        'name': 'Script_2.py',
        'parents': ['1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ']},
    {   'createdTime': '2019-02-20T10:58:34.010Z',
        'id': '1xq6Ler0ypPimEFMxer_wtYlklNB7MCBoM6aSZft5dAc',
        'mimeType': 'application/vnd.google-apps.spreadsheet',
        'name': 'Sheet from csv',
        'parents': ['1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ']},
    {   'createdTime': '2019-02-20T09:35:18.684Z',
        'id': '0B7TyWvrAtxvgc3RhcnRlcl9maWxl',
        'mimeType': 'application/pdf',
        'name': 'Getting started',
        'parents': ['0ALTyWvrAtxvgUk9PVA']}]

Дальше - больше. С помощью API Google Drive мы можем загрузить файл с определенным mimeType, чтобы Drive понял к какому типу относится файл и предложил соответсвующее приложение для его открытия.

In [25]:
folder_id = '1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ'
name = 'Sample data.csv'
file_path = '/home/makarov/sample_data_1.csv'
file_metadata = {
                'name': name,
                'mimeType': 'text/csv',
                'parents': [folder_id]
            }
media = MediaFileUpload(file_path, mimetype='text/csv', resumable=True)
r = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
pp.pprint(r)
{'id': '1BxoPJhwEfp2SrNupf_gSbqyjcscqizDC'}

Но ещё более классная возможность - это загрузить файл одного типа с конвертацией в другой тип. Таким образом, мы можем залить csv файл из примера выше, указав для него тип Google Sheets. Это позволит сразу же конвертировать файл для открытия в Гугл Таблицах. Для этого надо в словаре file_metadata указать mimeType "application/vnd.google-apps.spreadsheet".

In [26]:
folder_id = '1mCCK9QGQxLDED8_pgq2dyvkmGRXhWEtJ'
name = 'Sheet from csv'
file_path = '/home/makarov/notebooks/sample_data_1.csv'
file_metadata = {
                'name': name,
                'mimeType': 'application/vnd.google-apps.spreadsheet',
                'parents': [folder_id]
            }
media = MediaFileUpload(file_path, mimetype='text/csv', resumable=True)
r = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
pp.pprint(r)
{'id': '1HpM2Pm6wP5RhizcRyVpcainG9ThZ_TL1bnSbodebiww'}

Ещё одна часто необходимая функция - это создание папок. Тут всё просто, создание папки также делается с помощью метода create, надо только в file_metadata указать mimeType "application/vnd.google-apps.folder"

In [27]:
folder_id = '1uuecd6ndiZlj3d9dSVeZeKyEmEkC7qyr'
name = 'New Folder'
file_metadata = {
    'name': name,
    'mimeType': 'application/vnd.google-apps.folder',
    'parents': [folder_id]
}
r = service.files().create(body=file_metadata,
                                    fields='id').execute()
pp.pprint(r)
{'id': '1VSa_V3hBIkHASHc1pl8ykoChn968AGu5'}

В этой статье мы рассмотрели лишь немногие возможности API Google Drive, но одни из самых необходимых:

  • Просмотр списка файлов
  • Скачивание документов из Google Drive (в том числе, скачивание с конвертацией, например, документов Google Sheets в формате Excel)
  • Загрузка документов в Google Drive (также как и в случае со скачиванием, с возможностью конвертации в нативные форматы Google Drive)
  • Удаление файлов
  • Создание папок