I am using google sheets to hold data for a shared project. Using Google's Sheets API I access the data, process it in python, and I am trying to update the Sheets file using batchUpdate, in the function writer.
- If I pass this function data as a list, it works as expected.
- If I pass a dataframe (as I would like to do) I get:
TypeError: Object of type DataFrame is not JSON serializable
- If I use
.to_json()
, I get this:
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://sheets.googleapis.com/v4/spreadsheets/XXX/values:batchUpdate?alt=json returned "Invalid value at 'data[0].values' (type.googleapis.com/google.protobuf.ListValue), "{"0":{"0":1},"1":{"0":2},"2":{"0":3},"3":{"0":4}}"". Details: "[{'@type': 'type.googleapis.com/google.rpc.BadRequest', 'fieldViolations': [{'field': 'data[0].values', 'description': 'Invalid value at 'data[0].values' (type.googleapis.com/google.protobuf.ListValue), "{"0":{"0":1},"1":{"0":2},"2":{"0":3},"3":{"0":4}}"'}]}]">
Any pointers would be much appreciated.
import pickle
import os.path
import pandas as pd
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from pprint import pprint
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
# Spreadsheet ID: https://docs.google.com/spreadsheets/d/XXX/edit#gid=0
SPREADSHEET_ID = 'XXX'
RANGE_NAME = 'contacts'
def writer(df):
service = build('sheets', 'v4', credentials=gsheet_api(SCOPES))
sheet_name = 'contacts'
data = [{'range' : sheet_name, 'values' : df}]
batch_update_values_request_body = {
'value_input_option': 'RAW',
'data': data }
request = service.spreadsheets().values().batchUpdate(spreadsheetId=SPREADSHEET_ID,
body=batch_update_values_request_body)
response = request.execute()
pprint(response)
df = [[1, 2, 3, 4]]
writer(df)