Google excel api python

Время на прочтение
11 мин

Количество просмотров 136K

Довольно долго я обходился выгрузкой данных в Excel, но мода меняется, пользователи хотят в облака.

Начав переводить ряд проектов на Python, решил, что самое время сменить (или дополнить) Excel чем-то более современным.

Когда я впервые столкнулся с необходимостью работы c таблицами Google из Python, то пребывал в иллюзии, что все это можно сделать в пару кликов. Реальность оказалась менее радужной, но другого глобуса у нас нет.

Мне очень помогли статьи:

  • Генерируем красивую Google-таблицу из своей программы (используя Google Sheets API v4)
  • Начинаем работать с Google Sheets API v4/
  • Работаем с API Google Drive с помощью Python

Как обычно – когда впервые за что-то берешься, то сталкиваешься с массой вопросов, которые потом вызывают лишь недоумение – как можно было об этом вообще задумываться. Элементарно же!

Возможно, я просто шел длинным путем – буду рад, если вы меня поправите.

Все действия выполнялись на компьютере с Windows + Python 3.6.6, также использовался Jupyter Notebook.

Основные трудности у меня возникали на этапе предварительных настроек. Найти работоспособный код не представляет особого труда.

Код, использованный в статье, доступен в репозитории

Регистрация в сервисах Google и установка библиотек

Для работы с таблицами нужно зарегистрироваться на Google, настроить проект и установить необходимые библиотеки.

Официальная документация на английском языке находится здесь.

Сначала нужно зарегистрироваться на gmail.com (это вы можете сделать самостоятельно). Потом нужно создать проект (так Google предоставляет доступ к своим сервисам).

Это долгий и нудный процесс, который позволяет понять, почему интерфейсы от Google называют не самыми удобными и интуитивно понятными (некоторые считают, что социальная сеть Google+ не взлетела именно по этой причине).

Для этого зайдите на страницу console.developers.google.com/cloud-resource-manager и нажать «Создать проект»

Введите имя проекта и нажмите «Создать»

В обновленном списке проектов зайдите в меню «Права доступа»

В открывшемся окне нажмите «Добавить», внесите свой email с домена gmail.com и выберите группу «Проект» — «Владелец»

Сохраните изменения.

Может показаться странным, что вы создали проект но вынуждены сами себе выдавать права. И это на самом деле странно, но именно такой путь пришлось пройти на момент написания этого курса, чтобы все начало работать как надо.

Снова зайдите на страницу console.developers.google.com/cloud-resource-manager

Выберите на своем проекте меню «Настройки»

В открывшемся окне выберите «Сервисные аккаунты», а затем «Создать сервисный аккаунт»

Введите название аккаунта и нажмите «Создать»

Выберите роль «Владелец» и нажмите «Продолжить»

В появившемся окне нажмите «Создать ключ»

Выберите тип ключа «json» и нажмите «Создать»

Будет создан и сразу же скачан файл с ключами. Сохраните его, именно благодаря ему мы сможем получать доступ к сервисам Google.

Нажмите на кнопку с тремя горизонтальными штрихами, слева от надписи «Google APIs», выберите пункт «API и сервисы», а в нем подпункт «Панель управления».

В открывшемся окне нажмите «Включить API и сервисы»

Введите в строку поиска «google drive» и кликните на сервисе «Google Drive API»

Нажмите «Включить»

Сайт уведомит вас, что API включено и предупредит, что нужно создать учетные данные. Игнорируйте это предупреждение (ведь мы уже создали сервисный аккаунт).

Снова заходите в панель управления

В открывшемся окне нажмите «Включить API и сервисы»

Введите в строку поиска «sheet» и кликните на сервисе «Google Sheets API»

Убедитесь, что это API подключено. Оно должно включиться автоматически, при подключении Google Drive API. Если оно подключено, вы увидите кнопку «Управление API», если нет — кнопку «Включить». Включите его, при необходимости.

В последний раз зайдите на страницу console.developers.google.com/cloud-resource-manager

Выберите на своем проекте меню «Настройки»


В открывшемся окне выберите «Сервисные аккаунты», а затем скопируйте и сохраните email сервисного аккаунта. Он пригодится вам, чтобы выдавать доступ к таблицам.

Теперь переходим к установке библиотек. Выполните в консоли команду

pip3 install --upgrade google-api-python-client

а затем

pip3 install oauth2client

Возможно, что при запуске второй команды вы получите сообщение, что библиотека oauth2client уже установлена.

Зайдите на страницу raw.githubusercontent.com/gsuitedevs/python-samples/master/sheets/quickstart/quickstart.py

Нажмите правую кнопку мышки и выберите «Сохранить как»

Сохраните файл под именем quickstart.py

и запустите его командой

python quickstart.py

Откроется новая страница в браузере (возможно, он скажет, что страница небезопасная, но смело идите вперед) и вам надо будет принять условия.

На этом наш путь завершен.

Заполнение и форматирование таблицы

Создадим первую таблицу

# Подключаем библиотеки
import httplib2 
import apiclient.discovery
from oauth2client.service_account import ServiceAccountCredentials	

CREDENTIALS_FILE = 'seraphic-effect-248407-7ac2c44ec709.json'  # Имя файла с закрытым ключом, вы должны подставить свое

# Читаем ключи из файла
credentials = ServiceAccountCredentials.from_json_keyfile_name(CREDENTIALS_FILE, ['https://www.googleapis.com/auth/spreadsheets', 'https://www.googleapis.com/auth/drive'])

httpAuth = credentials.authorize(httplib2.Http()) # Авторизуемся в системе
service = apiclient.discovery.build('sheets', 'v4', http = httpAuth) # Выбираем работу с таблицами и 4 версию API 

spreadsheet = service.spreadsheets().create(body = {
    'properties': {'title': 'Первый тестовый документ', 'locale': 'ru_RU'},
    'sheets': [{'properties': {'sheetType': 'GRID',
                               'sheetId': 0,
                               'title': 'Лист номер один',
                               'gridProperties': {'rowCount': 100, 'columnCount': 15}}}]
}).execute()
spreadsheetId = spreadsheet['spreadsheetId'] # сохраняем идентификатор файла
print('https://docs.google.com/spreadsheets/d/' + spreadsheetId)

Если все прошло без ошибок — на экран будет выведена ссылка на таблицу.

В этой ссылки использован идентификатор файла, мы сохраняем его в переменной spreadsheetId и будем использовать в дальнейшем.

Переходите по ней. Google сообщит вам, что у вас нет доступа

Не запрашивайте разрешение! Вам придет уведомление, что невозможно доставить письмо с запросом на адрес, который сам Google назначил системному аккаунту. А изменить этот адрес нельзя. Возможно, это не работает только в бесплатном режиме.

Но мы можем выдать себе доступ через Google Drive. Вам нужно заменить адрес my_test_address@gmail.com на свой.

driveService = apiclient.discovery.build('drive', 'v3', http = httpAuth) # Выбираем работу с Google Drive и 3 версию API
access = driveService.permissions().create(
    fileId = spreadsheetId,
    body = {'type': 'user', 'role': 'writer', 'emailAddress': 'my_test_address@gmail.com'},  # Открываем доступ на редактирование
    fields = 'id'
).execute()

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

У каждого документа есть свой код — spreadsheetId — именно от отображается в адресной строке, когда мы открываем таблицу в браузере (в URL-е страницы с открытой таблицей он находится между «https://docs.google.com/spreadsheets/d/» и «/edit#gid=0»).

Мы сохранили его в переменной spreadsheetId и дальше будем с ним работать.

Сначала немного теории.

В каждом файле (spreadsheet) находятся листы-вкладки (sheet).

Каждый sheet имеет свой числовой код (sheetId). У первого созданного в документе листа этот Id равен 0. Остальные листы имеют сильно отличные от нуля Id (т.е. они не нумеруются подряд).

Убедимся в этом

# Добавление листа
results = service.spreadsheets().batchUpdate(
    spreadsheetId = spreadsheetId,
    body = 
{
  "requests": [
    {
      "addSheet": {
        "properties": {
          "title": "Еще один лист",
          "gridProperties": {
            "rowCount": 20,
            "columnCount": 12
          }
        }
      }
    }
  ]
}).execute()


# Получаем список листов, их Id и название
spreadsheet = service.spreadsheets().get(spreadsheetId = spreadsheetId).execute()
sheetList = spreadsheet.get('sheets')
for sheet in sheetList:
    print(sheet['properties']['sheetId'], sheet['properties']['title'])
    
sheetId = sheetList[0]['properties']['sheetId']

print('Мы будем использовать лист с Id = ', sheetId)

На экране появится нечто вроде:

0 Лист номер один
415832263 Еще один лист
Мы будем использовать лист с Id = 0

В самом деле, первый лист имеет Id равный нулю, а второй пронумерован иначе.

Еще один вопрос: как указывать диапазоны ячеек. Видимо, таблицы Google разрабатывали разные команды, под руководством разных менеджеров и при помощи разных архитекторов. Потому, что координаты ячеек задаются двумя разными способами.

Вариант 1: в формате текста «Лист номер один!B2:D5», т.е. имя листа, после него восклицательный знак, после — левая верхняя ячейка в формате «буква (колонка) + цифра (строка)» + правая нижняя ячейка в таком же формате.

{"range": "Лист номер один!B2:D5"}

Вариант 2: в json-формате, с указанием ID листа и координат левой верхней и правой нижней ячеек в числовом виде (номер строки и номер столбца)

{"range":
    {
    "sheetId": sheetId, # ID листа
    "startRowIndex": 1, # Со строки номер startRowIndex 
    "endRowIndex": 5,# по endRowIndex - 1 (endRowIndex не входит!)
    "startColumnIndex": 0, # Со столбца номер startColumnIndex 
    "endColumnIndex": 1 # по endColumnIndex - 1
    }}

Разные функции используют разные форматы.

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

results = service.spreadsheets().values().batchUpdate(spreadsheetId = spreadsheetId, body = {
    "valueInputOption": "USER_ENTERED", # Данные воспринимаются, как вводимые пользователем (считается значение формул)
    "data": [
        {"range": "Лист номер один!B2:D5",
         "majorDimension": "ROWS",     # Сначала заполнять строки, затем столбцы
         "values": [
                    ["Ячейка B2", "Ячейка C2", "Ячейка D2"], # Заполняем первую строку
                    ['25', "=6*6", "=sin(3,14/2)"]  # Заполняем вторую строку
                   ]}
    ]
}).execute()

Заполняем несколько ячеек данными. Т.к. указан параметр USER_ENTERED, таблица воспринимает эти данные так, как восприняла бы ввод руками пользователя — преобразует числовые значения в числа, а значения, начинающиеся со знака «равно» в формулы.

Посмотрите в вашу таблицу, она заполнилась данными

Зададим ширину колонок. Функция batchUpdate может принимать несколько команд сразу, так что мы одним запросом установим ширину трех групп колонок. В первой и третьей группе одна колонка, а во второй — две.

results = service.spreadsheets().batchUpdate(spreadsheetId = spreadsheetId, body = {
  "requests": [

    # Задать ширину столбца A: 20 пикселей
    {
      "updateDimensionProperties": {
        "range": {
          "sheetId": sheetId,
          "dimension": "COLUMNS",  # Задаем ширину колонки
          "startIndex": 0, # Нумерация начинается с нуля
          "endIndex": 1 # Со столбца номер startIndex по endIndex - 1 (endIndex не входит!)
        },
        "properties": {
          "pixelSize": 20 # Ширина в пикселях
        },
        "fields": "pixelSize" # Указываем, что нужно использовать параметр pixelSize  
      }
    },

    # Задать ширину столбцов B и C: 150 пикселей
    {
      "updateDimensionProperties": {
        "range": {
          "sheetId": sheetId,
          "dimension": "COLUMNS",
          "startIndex": 1,
          "endIndex": 3
        },
        "properties": {
          "pixelSize": 150
        },
        "fields": "pixelSize"
      }
    },

    # Задать ширину столбца D: 200 пикселей
    {
      "updateDimensionProperties": {
        "range": {
          "sheetId": sheetId,
          "dimension": "COLUMNS",
          "startIndex": 3,
          "endIndex": 4
        },
        "properties": {
          "pixelSize": 200
        },
        "fields": "pixelSize"
      }
    }
  ]
}).execute()

Посмотрите на таблицу, ширины колонок изменились.

Нарисуем рамку вокруг таблицы

# Рисуем рамку
results = service.spreadsheets().batchUpdate(
    spreadsheetId = spreadsheetId,
    body = {
        "requests": [
            {'updateBorders': {'range': {'sheetId': sheetId,
                             'startRowIndex': 1,
                             'endRowIndex': 3,
                             'startColumnIndex': 1,
                             'endColumnIndex': 4},
                   'bottom': {  
                   # Задаем стиль для верхней границы
                              'style': 'SOLID', # Сплошная линия
                              'width': 1,       # Шириной 1 пиксель
                              'color': {'red': 0, 'green': 0, 'blue': 0, 'alpha': 1}}, # Черный цвет
                   'top': { 
                   # Задаем стиль для нижней границы
                              'style': 'SOLID',
                              'width': 1,
                              'color': {'red': 0, 'green': 0, 'blue': 0, 'alpha': 1}},
                   'left': { # Задаем стиль для левой границы
                              'style': 'SOLID',
                              'width': 1,
                              'color': {'red': 0, 'green': 0, 'blue': 0, 'alpha': 1}},
                   'right': { 
                   # Задаем стиль для правой границы
                              'style': 'SOLID',
                              'width': 1,
                              'color': {'red': 0, 'green': 0, 'blue': 0, 'alpha': 1}},
                   'innerHorizontal': { 
                   # Задаем стиль для внутренних горизонтальных линий
                              'style': 'SOLID',
                              'width': 1,
                              'color': {'red': 0, 'green': 0, 'blue': 0, 'alpha': 1}},
                   'innerVertical': { 
                   # Задаем стиль для внутренних вертикальных линий
                              'style': 'SOLID',
                              'width': 1,
                              'color': {'red': 0, 'green': 0, 'blue': 0, 'alpha': 1}}
                              
                              }}
        ]
    }).execute()

Объединим ячейки над таблицей и впишем в них заголовок

# Объединяем ячейки A2:D1
results = service.spreadsheets().batchUpdate(
    spreadsheetId = spreadsheetId,
    body = {
        "requests": [
            {'mergeCells': {'range': {'sheetId': sheetId,
                          'startRowIndex': 0,
                          'endRowIndex': 1,
                          'startColumnIndex': 1,
                          'endColumnIndex': 4},
                'mergeType': 'MERGE_ALL'}}
        ]
    }).execute()
# Добавляем заголовок таблицы
results = service.spreadsheets().values().batchUpdate(spreadsheetId = spreadsheetId, body = {
    "valueInputOption": "USER_ENTERED",
# Данные воспринимаются, как вводимые пользователем (считается значение формул)
    "data": [
        {"range": "Лист номер один!B1",
         "majorDimension": "ROWS", # Сначала заполнять строки, затем столбцы
         "values": [["Заголовок таблицы" ] 
                   ]}
    ]
}).execute()

Установим формат у ячеек заголовка таблицы

# Установка формата ячеек
results = service.spreadsheets().batchUpdate(
    spreadsheetId = spreadsheetId,
    body = 
{
  "requests": 
  [
    {
      "repeatCell": 
      {
        "cell": 
        {
          "userEnteredFormat": 
          {
            "horizontalAlignment": 'CENTER',
            "backgroundColor": {
                "red": 0.8,
                "green": 0.8,
                "blue": 0.8,
                "alpha": 1
            },
            "textFormat":
             {
               "bold": True,
               "fontSize": 14
             }
          }
        },
        "range": 
        {
          "sheetId": sheetId,
          "startRowIndex": 1,
          "endRowIndex": 2,
          "startColumnIndex": 1,
          "endColumnIndex": 4
        },
        "fields": "userEnteredFormat"
      }
    }
  ]
}).execute()

Есть простой способ узнать, какую ширину или цвет нужно задать ячейке. Для этого достаточно вручную отформатировать одну из ячеек и прочитать ее свойства.

ranges = ["Лист номер один!C2:C2"] # 
          
results = service.spreadsheets().get(spreadsheetId = spreadsheetId, 
                                     ranges = ranges, includeGridData = True).execute()
print('Основные данные')
print(results['properties'])
print('nЗначения и раскраска')
print(results['sheets'][0]['data'][0]['rowData'] )
print('nВысота ячейки')
print(results['sheets'][0]['data'][0]['rowMetadata'])
print('nШирина ячейки')
print(results['sheets'][0]['data'][0]['columnMetadata'])

Получаем в ответ

Основные данные
{‘title’: ‘Первый тестовый документ’, ‘locale’: ‘ru_RU’, ‘autoRecalc’: ‘ON_CHANGE’, ‘timeZone’: ‘Etc/GMT’, ‘defaultFormat’: {‘backgroundColor’: {‘red’: 1, ‘green’: 1, ‘blue’: 1}, ‘padding’: {‘top’: 2, ‘right’: 3, ‘bottom’: 2, ‘left’: 3}, ‘verticalAlignment’: ‘BOTTOM’, ‘wrapStrategy’: ‘OVERFLOW_CELL’, ‘textFormat’: {‘foregroundColor’: {}, ‘fontFamily’: ‘arial,sans,sans-serif’, ‘fontSize’: 10, ‘bold’: False, ‘italic’: False, ‘strikethrough’: False, ‘underline’: False}}}

Значения и раскраска
[{‘values’: [{‘userEnteredValue’: {‘stringValue’: ‘Ячейка C2’}, ‘effectiveValue’: {‘stringValue’: ‘Ячейка C2’}, ‘formattedValue’: ‘Ячейка C2’, ‘userEnteredFormat’: {‘backgroundColor’: {‘red’: 1, ‘green’: 0.6}, ‘horizontalAlignment’: ‘CENTER’, ‘textFormat’: {‘fontSize’: 14, ‘bold’: True, ‘italic’: True}}, ‘effectiveFormat’: {‘backgroundColor’: {‘red’: 1, ‘green’: 0.6}, ‘padding’: {‘top’: 2, ‘right’: 3, ‘bottom’: 2, ‘left’: 3}, ‘horizontalAlignment’: ‘CENTER’, ‘verticalAlignment’: ‘BOTTOM’, ‘wrapStrategy’: ‘OVERFLOW_CELL’, ‘textFormat’: {‘foregroundColor’: {}, ‘fontFamily’: ‘Arial’, ‘fontSize’: 14, ‘bold’: True, ‘italic’: True, ‘strikethrough’: False, ‘underline’: False}, ‘hyperlinkDisplayType’: ‘PLAIN_TEXT’}}]}]

Высота ячейки
[{‘pixelSize’: 21}]

Ширина ячейки
[{‘pixelSize’: 150}]

Этот код выведет свойства ячейки C2. Можно выбрать шрифт и цвет заливки вручную (в таблице), в потом увидеть, как они отражаются в json.

Чтение данных из таблицы

Чтобы особенности чтения данных проявились в полной мере, я вручную заполнил ячейки B4, C7 и D5 как показано на рисунке.

Код для чтения данных

ranges = ["Лист номер один!A2:F8"] # 
          
results = service.spreadsheets().values().batchGet(spreadsheetId = spreadsheetId, 
                                     ranges = ranges, 
                                     valueRenderOption = 'FORMATTED_VALUE',  
                                     dateTimeRenderOption = 'FORMATTED_STRING').execute() 
sheet_values = results['valueRanges'][0]['values']
print(sheet_values)

Результат

[[», ‘Ячейка B2’, ‘Ячейка C2’, ‘Ячейка D2′], [», ’25’, ’36’, ‘0,9999996829’]]

Некоторые параметры функции: valueRenderOption — формат чтения числовых данных.

  • FORMATTED_VALUE — чтение с учетом формата отображения. Т.е. что было видно в таблице, то и прочитается. Например, в ячейке D3 число 0,9999999, но выбран формат «два знака после запятой», поэтому отображается «1,00», именно в таком формате оно и прочитается.
  • UNFORMATTED_VALUE — читается содержимое ячейки, без учета настроек форматирование (т.е. прочиталось бы 0,9999999)
  • FORMULA — отображается формула (в этом случае «=sin(3,14/2)». Если в ячейке введено число, то в этом режиме оно и прочитается.

Этот код читает данные и построчно выводит их на экран. Читаемый диапазон A2:F8.
Как видно на экране:

  • Если ни одна ячейка в читаемой строке не заполнена — данные по строке не выводятся.
  • Данные после последней заполненной ячейки не выводятся.

Quickstarts explain how to set up and run an app that calls a
Google Workspace API.

Google Workspace quickstarts use the API client libraries to handle some
details of the authentication and authorization flow. We recommend that
you use the client libraries for your own apps. Before you can run the sample
app, each quickstart requires that you turn on authentication and
authorization. If you’re unfamiliar with authentication and authorization for
Google Workspace APIs, read the
Authentication and authorization overview.

Create a Python command-line application that makes requests to the Google Sheets API.

Objectives

  • Set up your environment.
  • Install the client library.
  • Set up the sample.
  • Run the sample.

Prerequisites

To run this quickstart, you need the following prerequisites:

  • Python 3.10.7 or greater
  • The pip
    package management tool
  • A Google Cloud project.
  • A Google Account.

Set up your environment

To complete this quickstart, set up your environment.

Enable the API

Before using Google APIs, you need to turn them on in a Google Cloud project.
You can turn on one or more APIs in a single Google Cloud project project.

  • In the Google Cloud console, enable the Google Sheets API.

    Enable the API

To authenticate as an end user and access user data in your app, you need to
create one or more OAuth 2.0 Client IDs. A client ID is used to identify a
single app to Google’s OAuth servers. If your app runs on multiple platforms,
you must create a separate client ID for each platform.

  1. In the Google Cloud console, go to Menu > APIs & Services > Credentials.

    Go to Credentials

  2. Click Create Credentials > OAuth client ID.
  3. Click Application type > Desktop app.
  4. In the Name field, type a name for the credential. This name is only shown in the Google Cloud console.
  5. Click Create. The OAuth client created screen appears, showing your new Client ID and Client secret.
  6. Click OK. The newly created credential appears under OAuth 2.0 Client IDs.
  7. Save the downloaded JSON file as credentials.json, and move the
    file to your working directory.

Install the Google client library

  • Install the Google client library for Python:

    pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
    

Configure the sample

  1. In your working directory, create a file named quickstart.py.
  2. Include the following code in quickstart.py:

Run the sample

  1. In your working directory, build and run the sample:

    python3 quickstart.py
    
  2. The first time you run the sample, it prompts you to authorize access:

    1. If you’re not already signed in to your Google Account, you’re
      prompted to sign in. If you’re signed in to multiple accounts,
      select one account to use for authorization.
    2. Click Accept.

    Authorization information is stored in the file system, so the next time you
    run the sample code, you aren’t prompted for authorization.

You have successfully created your first Python application that makes requests to
the Google Sheets API.

Next steps

  • Troubleshoot authentication and authorization issues
  • Sheets API reference documentation
  • Google APIs Client for Python documentation
  • Google Sheets API PyDoc documentation

gspread is a Python API for Google Sheets.

Features:

  • Google Sheets API v4.

  • Open a spreadsheet by title, key or url.

  • Read, write, and format cell ranges.

  • Sharing and access control.

  • Batching updates.

Installation¶

Requirements: Python 3+.

Quick Example¶

import gspread

gc = gspread.service_account()

# Open a sheet from a spreadsheet in one go
wks = gc.open("Where is the money Lebowski?").sheet1

# Update a range of cells using the top left corner address
wks.update('A1', [[1, 2], [3, 4]])

# Or update a single cell
wks.update('B42', "it's down there somewhere, let me take another look.")

# Format the header
wks.format('A1:B1', {'textFormat': {'bold': True}})

Getting Started¶

  • Authentication
    • Enable API Access for a Project
    • For Bots: Using Service Account
    • For End Users: Using OAuth Client ID

Usage¶

  • Examples of gspread Usage
    • Opening a Spreadsheet
    • Creating a Spreadsheet
    • Sharing a Spreadsheet
    • Selecting a Worksheet
    • Creating a Worksheet
    • Deleting a Worksheet
    • Getting a Cell Value
    • Getting All Values From a Row or a Column
    • Getting All Values From a Worksheet as a List of Lists
    • Getting All Values From a Worksheet as a List of Dictionaries
    • Finding a Cell
    • Finding All Matched Cells
    • Clear A Worksheet
    • Cell Object
    • Updating Cells
    • Formatting
    • Using gspread with pandas
    • Using gspread with NumPy

Advanced¶

  • Advanced Usage
    • Custom Authentication

API Documentation¶

  • API Reference
    • Top level
    • Auth
    • Client
    • Models
    • Utils
    • Exceptions

How to Contribute¶

Please make sure to take a moment and read the Code of Conduct.

Ask Questions¶

The best way to get an answer to a question is to ask on Stack Overflow
with a gspread tag.

Report Issues¶

Please report bugs and suggest features via the GitHub Issues.

Before opening an issue, search the tracker for possible duplicates. If
you find a duplicate, please add a comment saying that you encountered
the problem as well.

Contribute code¶

Please make sure to read the Contributing Guide before making a pull
request.

Indices and tables¶

  • Index

  • Module Index

  • Search Page

Google Spreadsheets Python API v4

latest workflow
GitHub version pypi downloads doc

Simple interface for working with Google Sheets.

Features:

  • Open a spreadsheet by title, key or url.
  • Read, write, and format cell ranges.
  • Sharing and access control.
  • Batching updates.

Installation

Requirements: Python 3.6+.

Basic Usage

  1. Create credentials in Google API Console

  2. Start using gspread:

import gspread

gc = gspread.service_account()

# Open a sheet from a spreadsheet in one go
wks = gc.open("Where is the money Lebowski?").sheet1

# Update a range of cells using the top left corner address
wks.update('A1', [[1, 2], [3, 4]])

# Or update a single cell
wks.update('B42', "it's down there somewhere, let me take another look.")

# Format the header
wks.format('A1:B1', {'textFormat': {'bold': True}})

More Examples

Opening a Spreadsheet

# You can open a spreadsheet by its title as it appears in Google Docs
sh = gc.open('My poor gym results') # <-- Look ma, no keys!

# If you want to be specific, use a key (which can be extracted from
# the spreadsheet's url)
sht1 = gc.open_by_key('0BmgG6nO_6dprdS1MN3d3MkdPa142WFRrdnRRUWl1UFE')

# Or, if you feel really lazy to extract that key, paste the entire url
sht2 = gc.open_by_url('https://docs.google.com/spreadsheet/ccc?key=0Bm...FE&hl')

Creating a Spreadsheet

sh = gc.create('A new spreadsheet')

# But that new spreadsheet will be visible only to your script's account.
# To be able to access newly created spreadsheet you *must* share it
# with your email. Which brings us to…

Sharing a Spreadsheet

sh.share('otto@example.com', perm_type='user', role='writer')

Selecting a Worksheet

# Select worksheet by index. Worksheet indexes start from zero
worksheet = sh.get_worksheet(0)

# By title
worksheet = sh.worksheet("January")

# Most common case: Sheet1
worksheet = sh.sheet1

# Get a list of all worksheets
worksheet_list = sh.worksheets()

Creating a Worksheet

worksheet = sh.add_worksheet(title="A worksheet", rows="100", cols="20")

Deleting a Worksheet

sh.del_worksheet(worksheet)

Getting a Cell Value

# With label
val = worksheet.get('B1').first()

# With coords
val = worksheet.cell(1, 2).value

Getting All Values From a Row or a Column

# Get all values from the first row
values_list = worksheet.row_values(1)

# Get all values from the first column
values_list = worksheet.col_values(1)

Getting All Values From a Worksheet as a List of Lists

list_of_lists = worksheet.get_values()

Finding a Cell

# Find a cell with exact string value
cell = worksheet.find("Dough")

print("Found something at R%sC%s" % (cell.row, cell.col))

# Find a cell matching a regular expression
amount_re = re.compile(r'(Big|Enormous) dough')
cell = worksheet.find(amount_re)

Finding All Matched Cells

# Find all cells with string value
cell_list = worksheet.findall("Rug store")

# Find all cells with regexp
criteria_re = re.compile(r'(Small|Room-tiering) rug')
cell_list = worksheet.findall(criteria_re)

Updating Cells

# Update a single cell
worksheet.update('B1', 'Bingo!')

# Update a range
worksheet.update('A1:B2', [[1, 2], [3, 4]])

# Update multiple ranges at once
worksheet.batch_update([{
    'range': 'A1:B2',
    'values': [['A1', 'B1'], ['A2', 'B2']],
}, {
    'range': 'J42:K43',
    'values': [[1, 2], [3, 4]],
}])

Documentation

Contributors

How to Contribute

Please make sure to take a moment and read the Code of Conduct.

Ask Questions

The best way to get an answer to a question is to ask on Stack Overflow with a gspread tag.

Report Issues

Please report bugs and suggest features via the GitHub Issues.

Before opening an issue, search the tracker for possible duplicates. If you find a duplicate, please add a comment saying that you encountered the problem as well.

Improve Documentation

Documentation is as important as code. If you know how to make it more consistent, readable and clear, please submit a pull request. The documentation files are in docs folder, use reStructuredText markup and rendered by Sphinx.

Contribute code

Please make sure to read the Contributing Guide before making a pull request.

In this article we will discuss how to access and edit Google Sheets using Google Sheets API in Python.

Table of Contents

  • Introduction
  • Creating a sample Google Sheets spreadsheet
  • Creating Google API credentials
  • Open a Google Sheet using Python
    • Open Google Sheet by name
    • Open Google Sheet by URL
    • Open Google Sheet by key
  • Select a worksheet using Python
  • Create a worksheet using Python
  • Delete a worksheet using Python
  • Edit data in a Google Sheet using Python
    • Get a cell value
    • Update a cell value
    • Get all values from a row
    • Get all values from a column
    • Insert a new row
  • Conclusion

Introduction

Accessing data from multiple sources using Python becomes a standard requirement for nearly any position in data science and analytics. Working with Excel spreadsheets and internal CSV files happens everywhere.

But what if your data is now stored on Google Drive as a Google Sheet? Of course you can download it in any format of your choice. Yet it is not a scalable solution since it requires constant human input.

Let’s see how we can solve this in a programmatic way and even automate some of the tasks when working with Google Sheets using Python.

To continue following this tutorial we will need two Python libraries: gspread and oauth2client.

If you don’t have them installed, please open “Command Prompt” (on Windows) and install them using the following code:


pip install gspread
pip install oauth2client

Creating a sample Google Sheets spreadsheet

You probably already have a Google Sheets document if you are reading this article and you would like to work with your file.

For the purposes of this tutorial, I will create a simple Google Sheets file where I will replicate the students’ grades dataset.

Essentially we will have three columns: “first name”, “last name”, and “grade”.

To create your first Google Sheets file, go to Google Drive page and login using your Google account. Once you are in, in the top left corner, click New and then Google Sheets. This will create a blank document that looks like this:

This new document is all empty and doesn’t have any data or it’s own filename.

In the top left corner, where you see “Untitled spreadsheet”, let’s rename it to “My Google Sheet” for convenience.

And let’s add some sample data to work with. I added some simple fields:

Great. Now we have a file that we will continue working with.


Creating Google API credentials

The first step to start working with Google Sheets using Python is to create API credentials for the Google Drive and Google Sheets that will allow us to connect to our files.

To get started we are going to head to Google Cloud Console for developers and login with our Google account.

Once we are in, at the very top, you will see the following button to create a project:

Click on it and it will take you to a new page where it will ask you to create a name for your project. I called mine “gsheets-pyshark”, and click “Create“.

Now, in the top right corner, click on the “bell” icon, and you will see a notification that the project has been created. From that notification list click View to get to the project page.

This will take you to the API dashboard for your project. It should look like this:

Perfect. So far we created our own unique project for working with Google Sheets using Python. The next step is to set up the APIs.

Go to navigation menu (click the three horizontal lines in the top right corner), and choose APIs & Services and then Dashboard. You should arrive at the following page:

As you can see, we don’t have any APIs working just yet. We need to add them. Follow the blue link in the middle of the screen that says API library to get to the list of all available Google APIs:

Here we will need to add the “Google Drive” API. Find it by typing the name in the search box, click on it, and then click Enable. It may take a few seconds to load. Once it’s enabled, we arrive here:

Wonderful. The Google Drive API is now enabled. To use it we will need to generate credentials for it. Click on Create Credentials in the top right corner and fill out the form like this:

After you filled out the form above, continue with clicking the blue button What credentials do I need?

In the next form, you should choose your account name (I set it to misha-pyshark) and the account’s role for the project (I chose Owner). The “Key type” should be set to JSON, because we would like to download the credentials as a .json file:

Then, click Continue and your credentials will be downloaded automatically and you will see a pop-up saying your API credentials have been created.

Important note: Please rename the downloaded JSON file to “mycredentials” as it will be much easier to reference it later in the code. Also, you should place it in the same directory/folder where your Python code will be (so we can save time on specifying the location of the file).

So far we have enabled our Google Drive API and downloaded credentials for it. The last step is to enable the Google Sheets API. Let’s go back to Google API library and find “Google Sheets API”. Click into it and click Enable to get it running.

Now we are all set to access Google Sheets using Python.


Open a Google Sheet using Python

There are multiple ways to preform the authorization step in Python. The method I use in this tutorial is widely used across majority of the articles on this topics, so I decided to do it the same way.

As the first step, we will need to import the required libraries:


import gspread
from oauth2client.service_account import ServiceAccountCredentials

Now it’s time to configure the client with our credentials. This will create the gspread client:


gc = gspread.service_account(filename='mycredentials.json')

Everything is set up to retrieve the Google Sheet we’ve created earlier and get all the records from it.


There are 3 ways to open a Google Sheet using Python:

1. Open Google Sheet by name

Here, we simply need to input the actual name of the Google Sheet that we created:


gsheet = gc.open("my_google_sheet")

2. Open Google Sheet by URL

To open the Google Sheet using a URL, you would need to open your Google Sheet in the browser and copy its address. For my file it is: https://docs.google.com/spreadsheets/d/1L7cYfMVPIiYPkTYe1bDwKPGfhAJXp8HCeg34Bh7VYl0/

Now, we use .open_by_url() method and pass our URL as an argument:


gsheet = gc.open_by_url("https://docs.google.com/spreadsheets/d/1L7cYfMVPIiYPkTYe1bDwKPGfhAJXp8HCeg34Bh7VYl0/")

3. Open Google Sheet by key

Opening the Google Sheet by key is very similar to the previous option. What is the key to our file? It’s very easy to find. The key is the last component of the URL between the two last slashes (“/”). In my case it’s: 1L7cYfMVPIiYPkTYe1bDwKPGfhAJXp8HCeg34Bh7VYl0

Now, we use .open_by_key() method and pass our URL as an argument:


gsheet = gc.open_by_key("1L7cYfMVPIiYPkTYe1bDwKPGfhAJXp8HCeg34Bh7VYl0")

Whichever way you decided to continue with, it will create an object in our memory and store it as gsheet. Now what exactly does it contain? Simply, it’s contents are exactly what we have entered when we created this Google Sheet. Let’s now retrieve the information from it:


mydata = gsheet.sheet1.get_all_records()
print(mydata)

In the above chunk of code we opened our retrieved all the data from “Sheet 1” and printed it. It should look like this:

[{'first name': 'James', 'grade': 77, 'last name': 'Smith'},
{'first name': 'Maria', 'grade': 68, 'last name': 'Johnson'},
{'first name': 'Sam', 'grade': 59, 'last name': 'Erickson'},
{'first name': 'David', 'grade': 89, 'last name': 'Williams'}]

We ended up getting a list with values for each row. Also notice how Google Sheets by default set the first row as names for the columns.


Bonus: Google Sheet can be easily converted to a Pandas dataframe using the following code:


import pandas as pd

df= pd.DataFrame(mydata)
print(df)

And we get a much more familiar output:

first name last name grade
0 James Smith 77
1 Maria Johnson 68
2 Sam Erickson 59
3 David Williams 89

After we were able to access the Google Sheet, let’s see what we can start with. The first checkpoint is our flexibility in working with different worksheets of our Google Sheet.

My sample Google Sheet contains only one worksheet that is called “Sheet 1”. Yet, it is very common that you will have a multi worksheet file. Of course when we retrieve the data we would need to specify from which worksheet the data should be taken. And this takes us to the first interaction option.


Select a Worksheet using Python

Recall that our Google Sheet is saved in local memory as gsheet. Now we would like to access a specific worksheet by its name from the file. What we are going to do is create a subset of the main Google Sheet that only contains data from “Sheet1” and print its content:


wsheet = gsheet.worksheet("Sheet1")

mydata = wsheet.get_all_records()
print(mydata)

The result should be identical to the previous section since we only have a single worksheet in our file:

first name last name grade
0 James Smith 77
1 Maria Johnson 68
2 Sam Erickson 59
3 David Williams 89

Create a Worksheet using Python

Now, what if you wanted another empty worksheet? Of course you can login into your Google Drive via browser and create it manually. But if your script is running as a part if an automated process (which is why you are probably reading this article), we want to make everything work from our Python code.

The functionality of gspread library allows us to create new worksheets as well:


newsheet = gsheet.add_worksheet(title="New Worksheet", rows="100", cols="20")

The above code will create a new worksheet in out Google Sheet with the given parameters. Keep in mind, you must specify a new name for the worksheet being added as well as the number of rows and columns.

To check that it worked, login into your Google Drive and take a look at the Google Sheet file, and you will see that a second worksheet “New Worksheet” has been added to your file.


Delete a Worksheet using Python

Alternatively, you may want to delete the worksheet you have just created. Now, here is a little catch: you can only delete the sheets that you have created using Python. In my example, it’s newsheet and the reason is the formatting that is stored in local memory to access that particular worksheet:


gsheet.del_worksheet(newsheet)

And if you check your Google Sheet again, you will see that the “New Worksheet” has been removed.


Edit data in a Google Sheet using Python

The majority of the most useful functionality will be discussed in this section. This is where we actually get to editing data in the main file using Python. To get started, we will need to define the worksheet we will be working with:


wsheet = gsheet.worksheet("Sheet1")

Recall that the data we are working with looks like this:


Get a Cell Value

Let’s say we want to retrieve the data from a specific cell of the worksheet, and let that cell be “A2” (and the data we are looking to get is “James”). We would do it using the following code:


cval = wsheet.acell('A2').value

print(cval)

And we get exactly what we expected:

James

Update a Cell Value

There can also be a case when you would like to update a value in a cell. Let’s say we made a wrong entry and need to change the name in A2 cell from “James” to “John”. It can be simply changed using the following code:


wsheet.update('A2', 'John')

And reusing the little code chunk from the previous section to get the updated value:


cval = wsheet.acell('A2').value

print(cval)

We get:

John

Get All Values from a Row

Alternatively, you may be interested in retrieving the entire row of data (rather than a single cell). In our case, let’s assume we are interested to get the data for the first student in our worksheet.

The only caveat is that we need to know the index of the row that we want to retrieve the data from. Assuming first row is the column headers, the row of interest has an index of 2. Now we can get its values:


row_index = 2
values_row = wsheet.row_values(row_index)

print(values_row)

And we get a list of values in the row:

['John', 'Smith', '77']

Get All Values from a Column

In another scenario, you may wish to get the data from a column (instead of a row). Assume for our scenario we want to get all data from the “grade” column.

We will again need to find its index (index = 3) and run code similar to the section above:


col_index = 3
values_column = wsheet.col_values(col_index)

print(values_column)

And we get a list of values in the column:

['grade', '77', '68', '59', '89']

Insert a New Row

Probably one of the more popular tasks we usually do with spreadsheets is adding new data.

In our example, assume there is a new student who just wrote his/her exam and got a grade for it. We would like to update our Google Sheet using Python with a new entry.

To do this, we will need two pieces of information: students data (first name, last name, and grade) and the index for a row that we are going to insert:


student_data = ['Emily', 'Watson', 89]
new_row_index = 6

The reason the new index is 6 because we know that we already have 5 rows with data, and want to add at the end of the list. Keep in mind you can choose any index value, and it just push the remaining rows down.

Now, let’s add this row to our Google Sheet and check if it was added:


wsheet.insert_row(student_data, new_row_index)

values_row = wsheet.row_values(new_row_index)
print(values_row)

And we get a list of values in the row we just added:

['Emily', 'Watson', '89']

Note: the functionality of the whole package is quite extensive and a lot of it is very case specific. For a complete set of methods with examples of the gspread package is available here.


Conclusion

In this article we discussed how to access and edit Google Sheets using Python as well as covered the features of the gspread library.

Feel free to leave comments below if you have any questions or have suggestions for some edits and check out more of my Python Programming articles.

Like this post? Please share to your friends:
  • Google docs как открыть excel
  • Google docs или excel
  • Google docs word сравнение
  • Google docs word documents
  • Google docs to excel online