Code is below. this isnt the full code but the basis of it. Im trying to take data from Twitter's API and Write it to my Google Sheets API. Below is the Code.
from googleapiclient import discovery
from google.oauth2 import service_account
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
SERVICE_ACCOUNT_FILE = 'twitter.json' #json File should be in the same folder as this Python Script.
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
creds = None
creds = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE, scopes=SCOPES)
# The ID and range of a sample spreadsheet.
SAMPLE_SPREADSHEET_ID = '1f4iqVHljytmRSC2EZcApEiA2lE1cHa1o6Fr4s3t0AKg'
#SAMPLE_RANGE_NAME = 'Class Data!A2:A60'
service = build('sheets', 'v4', credentials=creds)
sheet = service.spreadsheets()
# Call the Sheets API
result = sheet.values().get(spreadsheetId=SAMPLE_SPREADSHEET_ID,
range='twitterData!A1:A180').execute()
#ERROR HERE BELOW
request = sheet.values().update(spreadsheetId = SAMPLE_SPREADSHEET_ID,
range = 'twitterData!B2:B180', valueInputOption='USER_ENTERED', body={"values": 8}).execute()
the one Line im getting an Error for has the comment above it Error Below. and this is the Error Message:
Traceback (most recent call last):
File "C:\Users\John Doe\Desktop\Code\Python\Twitter\test.py", line 27, in <module>
request = sheet.values().update(spreadsheetId = SAMPLE_SPREADSHEET_ID,
File "C:\Users\John Doe\AppData\Local\Programs\Python\Python38-32\lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "C:\Users\John Doe\AppData\Local\Programs\Python\Python38-32\lib\site-packages\googleapiclient\http.py", line 938, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://sheets.googleapis.com/v4/spreadsheets/1f4iqVHljytmRSC2EZcApEiA2lE1cHa1o6Fr4s3t0AKg/values/twitterData%21B2%3AB180?valueInputOption=USER_ENTERED&alt=json returned "Invalid value at 'data.values' (type.googleapis.com/google.protobuf.ListValue), 8". Details: "[{'#type': 'type.googleapis.com/google.rpc.BadRequest', 'fieldViolations': [{'field': 'data.values', 'description': "Invalid value at 'data.values' (type.googleapis.com/google.protobuf.ListValue), 8"}]}]">
Ive used Google Sheets API before. Im not sure why this code isnt working. Its just that one line.
I think that the reason for your current issue of "Invalid value at 'data.values' (type.googleapis.com/google.protobuf.ListValue), 8" is due to body={"values": 8}. In this case, it is required to use a 2-dimensional array. So, please modify it as follows.
From:
request = sheet.values().update(spreadsheetId = SAMPLE_SPREADSHEET_ID,
range = 'twitterData!B2:B180', valueInputOption='USER_ENTERED', body={"values": 8}).execute()
To:
request = sheet.values().update(spreadsheetId = SAMPLE_SPREADSHEET_ID, range = 'twitterData!B2:B180', valueInputOption='USER_ENTERED', body={"values": [[8]]}).execute()
In this modification, body={"values": 8} is modified to body={"values": [[8]]}.
By this modification, 8 is put to the cell "B2" of "twitterData" sheet.
Reference:
Method: spreadsheets.values.update
Related
I was try to create google sheet using python in Pycharm but I try very had didn't out bugs.
here I submit my full code and show my error result.
# [START sheets_create]
from __future__ import print_function
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
def create(title):
"""
Creates the Sheet the user has access to.
Load pre-authorized user credentials from the environment.
TODO(developer) - See https://developers.google.com/identity
for guides on implementing OAuth2 for the application.\n"
"""
creds = 'conof.json'
# pylint: disable=maybe-no-member
try:
service = build('sheets', 'v4', credentials=creds)
spreadsheet = {
'properties': {
'title': title
}
}
spreadsheet = service.spreadsheets().create(body=spreadsheet,
fields='spreadsheetId') \
.execute()
print(f"Spreadsheet ID: {(spreadsheet.get('spreadsheetId'))}")
return spreadsheet.get('spreadsheetId')
except HttpError as error:
print(f"An error occurred: {error}")
return error
if __name__ == '__main__':
# Pass: title
create("mysheet1")
# [END sheets_create]
This is default code I found from google sheet development site I just added here my json file from google cloud console generated. I was hard to manage to solve library error's. I am using windows platform.
And my error's
C:\Users\pc\PycharmProjects\createShee\venv\Scripts\python.exe C:/Users/pc/PycharmProjects/createShee/mumu.py
Traceback (most recent call last):
File "C:\Users\pc\PycharmProjects\createShee\mumu.py", line 37, in <module>
create("mysheet1")
File "C:\Users\pc\PycharmProjects\createShee\mumu.py", line 19, in create
service = build('sheets', 'v4', credentials=creds)
File "C:\Users\pc\PycharmProjects\createShee\venv\lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "C:\Users\pc\PycharmProjects\createShee\venv\lib\site-packages\googleapiclient\discovery.py", line 298, in build
service = build_from_document(
File "C:\Users\pc\PycharmProjects\createShee\venv\lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "C:\Users\pc\PycharmProjects\createShee\venv\lib\site-packages\googleapiclient\discovery.py", line 604, in build_from_document
http = _auth.authorized_http(credentials)
File "C:\Users\pc\PycharmProjects\createShee\venv\lib\site-packages\googleapiclient\_auth.py", line 124, in authorized_http
return credentials.authorize(build_http())
AttributeError: 'str' object has no attribute 'authorize'
Process finished with exit code 1
Please help me to solve this project.
The credential parameter of build() method can only accept the following objects:
credentials: oauth2client.Credentials or
google.auth.credentials.Credentials, credentials to be used for
authentication.
An easy way to create a credential object is to use the authentication in the Python Quickstart of Google Sheets API.
Just follow the Quickstart guide, change the scope to 'https://www.googleapis.com/auth/spreadsheets' and replace the try-except block with the try-except block in the Create a spreadsheet.
Your code should look like this:
from __future__ import print_function
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
def create(title):
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())
try:
service = build('sheets', 'v4', credentials=creds)
spreadsheet = {
'properties': {
'title': title
}
}
spreadsheet = service.spreadsheets().create(body=spreadsheet,
fields='spreadsheetId') \
.execute()
print(f"Spreadsheet ID: {(spreadsheet.get('spreadsheetId'))}")
return spreadsheet.get('spreadsheetId')
except HttpError as error:
print(f"An error occurred: {error}")
return error
if __name__ == '__main__':
create("mysheet1")
Output:
Notes: Make sure to install the necessary package included in the Quickstart guide, download the credential json file, save it in the same directory as your script and rename it to credentials.json
Reference:
Module discovery
Try replacing creds = 'conof.json' with
credentials = google.oauth2.credentials.Credentials.from_authorized_user_file('conof.json)
and adding the import as necessary.
You are currently passing a string to the credentials parameter in build; however, build expects you to pass a specific type of credentials object to it. You can obtain this credential object from a JSON file using the line of code above. See this answer for more detail.
I am trying to access Google Sheet (read write mode) from Python (runs in GKE). I have tried both outh2client as well as google-auth approach but it gives the same error every time:
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://sheets.googleapis.com/v4/spreadsheets/1kvHv1OBCzr9GnFxRu9RTJC7jjQjc9M4rAiDnhyak2Sg/values/vm_metrics%21A10?alt=json returned "Request had insufficient authentication scopes.". Details: "[{'#type': 'type.googleapis.com/google.rpc.ErrorInfo', 'reason': 'ACCESS_TOKEN_SCOPE_INSUFFICIENT', 'domain': 'googleapis.com', 'metadata': {'method': 'google.apps.sheets.v4.SpreadsheetsService.GetValues', 'service': 'sheets.googleapis.com'}}]">
This is my code using outh2client:
from googleapiclient.discovery import build
from oauth2client import client
creds=client.GoogleCredentials.get_application_default().create_scoped(
['https://www.googleapis.com/auth/spreadsheets'])
service = build('sheets', 'v4', credentials=creds)
sheet = service.spreadsheets()
sheet.values().get(spreadsheetId='whatev', range='Sheet1!A:C').execute()
This is my code using google-auth:
import google.auth
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
creds, project=google.auth.default(scopes=SCOPES)
service = build('sheets', 'v4', credentials=creds)
sheet = service.spreadsheets()
sheet.values().get(spreadsheetId='XXXXXXXXXX', range='Sheet1!A:C').execute()
AFAICT, this is the same question as Google Sheet API access with Application Default credentials. The solution (from that SO post) is
from googleapiclient.discovery import build
from oauth2client import client
creds = client.GoogleCredentials.get_application_default().create_scoped(
['https://www.googleapis.com/auth/spreadsheets.readonly']
)
response = service.spreadsheets().values().get(
spreadsheetId='XXXXXXXXXX',
range='Sheet1!A:C'
).execute()
rows = response['values']
However, this will not work with a human user's application default credentials. You cannot run gcloud auth application-default login and use your user credentials. You'll get this error:
Traceback (most recent call last):
File "<ipython-input-2-2a9ba7e9e38f>", line 8, in <module>
sheet.values().get(spreadsheetId='1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms', range='Class Data!A2:E''....').execute()
File "/Users/dking/miniconda3/lib/python3.7/site-packages/googleapiclient/_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "/Users/dking/miniconda3/lib/python3.7/site-packages/googleapiclient/http.py", line 855, in execute
raise HttpError(resp, content, uri=self.uri)
HttpError: <HttpError 403 when requesting https://sheets.googleapis.com/v4/spreadsheets/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/values/Class%20Data%21A2%3AE....?alt=json returned "Request had insufficient authentication scopes.">
AFAICT, there is no way to use a human user's application default credentials, which is tremendously annoying.
I'm trying to apply filter on my google sheet using python sheets API. I'm getting this error, and there are no any hints to debug this error. My code looks like this. I tried to print the requests body, which is exactly in the same format as that suggested on API documentation(https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#setbasicfilterrequest).
My code looks like this :
from __future__ import print_function
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
import pandas as pd
import json
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
# The ID and range of a sample spreadsheet.
SAMPLE_SPREADSHEET_ID = '1ViILuxI3MD3vT7efWYDmlo5A67dIIDJbWXh6Pm9myPQ'
SAMPLE_RANGE_NAME = 'Sheet1!A2:I'
def main():
"""Shows basic usage of the Sheets API.
Prints values from a sample spreadsheet.
"""
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())
service = build('sheets', 'v4', credentials=creds)
_filter = {
"range": {
"sheetId": 0,
"startRowIndex": 1,
"startColumnIndex": 9,
"endColumnIndex": 10
},
"criteria" : {
9 : {
"hiddenValues" : [
"Closed"
]
}
}
}
setBasicFilterRequest = {
'setBasicFilter' : {
'filter' : _filter
}
}
body = {
'requests' : [setBasicFilterRequest],
'includeSpreadsheetInResponse' : True,
}
# print(json.dumps(body, indent=4))
resp = service.spreadsheets() \
.batchUpdate(spreadsheetId="Sheet1", body=body).execute()
print(resp)
if __name__ == '__main__':
main()
I'm getting following error when I run this :
Traceback (most recent call last):
File "poll_sheets.py", line 79, in <module>
main()
File "poll_sheets.py", line 72, in main
resp = service.spreadsheets() \
File "/Users/mike/Desktop/redash/myenv/lib/python3.8/site-packages/googleapiclient/_helpers.py", line 134, in positional_wrapper
return wrapped(*args, **kwargs)
File "/Users/mike/Desktop/redash/myenv/lib/python3.8/site-packages/googleapiclient/http.py", line 920, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 404 when requesting https://sheets.googleapis.com/v4/spreadsheets/Sheet1:batchUpdate?alt=json returned "Requested entity was not found.". Details: "Requested entity was not found.">
(myenv) (base) mike#Mikes-MacBook-Pro redash %
Modification points:
When I saw your script, it seems that SAMPLE_SPREADSHEET_ID is not used.
About resp = service.spreadsheets().batchUpdate(spreadsheetId="Sheet1", body=body).execute(), it seems that you use the sheet name as the Spreadsheet ID. I think that this is the reason of your issue.
When above points are reflected to your script, it becomes as follows.
Modified script:
From:
resp = service.spreadsheets().batchUpdate(spreadsheetId="Sheet1", body=body).execute()
To:
resp = service.spreadsheets().batchUpdate(spreadsheetId=SAMPLE_SPREADSHEET_ID, body=body).execute()
Note:
When you run above modified script and the same error occurs, please confirm the Spreadsheet ID again.
Reference:
Method: spreadsheets.batchUpdate
I've been struggling with this error for a number of weeks now and have tried solutions from previously posted questions relating to the Python API for Google Sheets.
I continuously get an error when I make a "write" request to my spreadsheet through the Google Sheets API for python. The error says that I'm submitting an invalid JSON, but I've tested the JSON structure against the interactive test window (Google APIs Explorer) and the request from there updates my sheet properly.
The code is below
from __future__ import print_function
from apiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools
import datetime
import json
# Call the Sheets API
SPREADSHEET_ID = #mySheetID
RANGE_NAME = '2018_Raw Data!A3:A367'
months = { 0:"Jan", 1:"Feb",2:"Mar",4:"Apr",5:"May",6:"Jun",7:"Jul",8:"Aug",9:"Sep",10:"Oct",11:"Nov",12:"Dec"}
now = datetime.datetime.now()
date = str(now.day) +"-"+ months[now.month] + "-"+str(now.year)
day_of_year = now.timetuple().tm_yday
myRow = day_of_year+2
print (date)
print (myRow)
BWRange= '2018_Raw Data!B' + str(myRow)
BFRange= '2018_Raw Data!C' + str(myRow)
myBodyWeight=150
myBF="10%"
print (BWRange)
print (BFRange)
BWData = {}
BWData['values']= [[myBodyWeight]]
BWData['majorDimension']="ROWS"
BWData['range']= BWRange
BWJson= json.dumps(BWData)
BFData = {}
BFData['values']= [[myBF]]
BFData['majorDimension']="ROWS"
BFData['range']= BFRange
BFJson= json.dumps(BFData)
print (BWJson)
print (BFJson)
# Setup the Sheets API
SCOPES = 'https://www.googleapis.com/auth/spreadsheets'
store = file.Storage('token.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
creds = tools.run_flow(flow, store)
service = build('sheets', 'v4', http=creds.authorize(Http()))
#bw
request = service.spreadsheets().values().update(spreadsheetId=SPREADSHEET_ID,range=BWRange, valueInputOption="USER_ENTERED", body=BWJson)
response = request.execute()
pprint(response)
#bf
request = service.spreadsheets().values().update(spreadsheetId=SPREADSHEET_ID, range=BFRange,valueInputOption="USER_ENTERED", body=BFJson)
response = request.execute()
pprint(response)
Error is below:
Traceback (most recent call last):
File "C:\sheets\mySheets.py", line 65, in <module>
response = request.execute()
File "C:\Python27\lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "C:\Python27\lib\site-packages\googleapiclient\http.py", line 842, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://sheets.googleapis.com/v4/spreadsheets/1demD8sm5-Jvi7ImHcOu03sHaU7PF61ym1eyvjN1bGfw/values/2018_Raw%20Data%21B234?alt=json&valueInputOption=USER_ENTERED returned "Invalid JSON payload received. Unknown name "": Root element must be a message.">
I've reviewed the following posts below:
Python3 google spreadsheet api batchUpdate Json formatting
Invalid JSON Payload error with python google sheets API
Any help is appreciated - thanks!
I think that your request body is correct. So how about this modification?
From :
request = service.spreadsheets().values().update(spreadsheetId=SPREADSHEET_ID,range=BWRange, valueInputOption="USER_ENTERED", body=BWJson)
request = service.spreadsheets().values().update(spreadsheetId=SPREADSHEET_ID, range=BFRange,valueInputOption="USER_ENTERED", body=BFJson)
To :
request = service.spreadsheets().values().update(spreadsheetId=SPREADSHEET_ID,range=BWRange, valueInputOption="USER_ENTERED", body=BWData)
request = service.spreadsheets().values().update(spreadsheetId=SPREADSHEET_ID, range=BFRange,valueInputOption="USER_ENTERED", body=BFData)
Note :
In this modification, json.dumps() was removed.
This script supposes that Sheets API is enabled at API console, and your access token can be used for spreadsheets().values().update().
If this didn't work, please tell me. I would like to modify it.
I can't write data to google sheets via python. I did everything like in Google Sheets Api example but it still doesn't work. This is my project:
from __future__ import print_function
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file as oauth_file, client, tools
SCOPES = ['https://www.googleapis.com/auth/spreadsheets','https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/drive.file']
SAMPLE_SPREADSHEET_ID = 'ID'
SAMPLE_RANGE = 'Sheet2!A1:A10'
def main():
store = oauth_file.Storage('token.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
creds = tools.run_flow(flow, store)
service = build('sheets', 'v4', http=creds.authorize(Http()))
values = {'values': [['one','two','three']]}
result = service.spreadsheets().values().append(
spreadsheetId=SAMPLE_SPREADSHEET_ID, range=SAMPLE_RANGE,
valueInputOption='RAW',
body=values).execute()
print('{0} cells updated.'.format(result.get('updatedCells')));
if __name__ == '__main__':
main()
And it gives me this errors:
C:\Users\Victor\Anaconda3\python.exe "C:/Users/Victor/Desktop/NEW try/try1.py"
Traceback (most recent call last):
File "C:/Users/Victor/Desktop/NEW try/try1.py", line 31, in <module>
main()
File "C:/Users/Victor/Desktop/NEW try/try1.py", line 27, in main
body=values).execute()
File "C:\Users\Victor\Anaconda3\lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "C:\Users\Victor\Anaconda3\lib\site-packages\googleapiclient\http.py", line 842, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://sheets.googleapis.com/v4/spreadsheets/1RaeZ4QpT3-ZCcIfBDKdtQJt0WDJKiLnBsB3dTC2PoGg/values/Sheet2%21A1%3AA10:append?valueInputOption=RAW&alt=json returned "Request had insufficient authentication scopes.">
Process finished with exit code 1
I pin a screenshot that prooves that i have all the permisions in the api.
Google API
Thank you in advance.
From my understanding, exit code 1 "means there was some issue / problem which caused the program to exit." Trying to debug your code, it seems like your indentation is off. Everything between lines 11 and 25 should have at least one indent so it's considered to be apart of the main() function. Like so:
from __future__ import print_function
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file as oauth_file, client, tools
SCOPES = ['https://www.googleapis.com/auth/spreadsheets','https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/drive.file']
SAMPLE_SPREADSHEET_ID = 'ID'
SAMPLE_RANGE = 'Sheet2!A1:A10'
def main():
store = oauth_file.Storage('token.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
creds = tools.run_flow(flow, store)
service = build('sheets', 'v4', http=creds.authorize(Http()))
values = {'values': [['one','two','three']]}
result = service.spreadsheets().values().append(
spreadsheetId=SAMPLE_SPREADSHEET_ID, range=SAMPLE_RANGE,
valueInputOption='RAW',
body=values).execute()
print('{0} cells updated.'.format(result.get('updatedCells')));
if __name__ == '__main__':
main()
Also, the Google Sheets API Quick Start for Python gets updated frequently, so I would try using the new code featured here. Let us know what happens after you fix the indentation or you decide to go with Google's updated code.