I am trying to find a way to transfer the values from JSON to a Google Sheet.
The values in JSON file are something like this {"someone_name1#gmail.com": 4, "someone_name2.com": 4} and they keep updating in the different run of the script. However, I am getting an error when its trying to put the value in the sheet.
sheet4.update_cells(1, 1, results)
TypeError: update_cells() takes from 2 to 3 positional arguments but 4 were given
Here is the code below. Any ideas what am I doing wrong and how can I fix this? I tried researching this but not able to find a suitable answer. As I am new to coding and python, I am unable to figure this one out. Any help appreciated. :)
# all functions imported
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import json
from collections import Counter
# login & open sheet sheets
scope = ["https://spreadsheets.google.com/feeds", 'https://www.googleapis.com/auth/spreadsheets',
"https://www.googleapis.com/auth/drive.file", "https://www.googleapis.com/auth/drive"]
credentials = ServiceAccountCredentials.from_json_keyfile_name('myfile-b16b15370c5b.json', scope)
client = gspread.authorize(credentials)
sheet4 = client.open('Dashboard').worksheet('Sheet4') # Open the spreadsheet
counter_file_path = "counter.json"
with open(counter_file_path, "r") as f:
email_stats = json.load(f)
results = []
for key in email_stats:
results.append([key, email_stats[key]])
sheet4.update_cells(1, 1, results)
Related
I am trying to download a Google Sheets document as a Microsoft Excel document using Python. I have been able to accomplish this task using the Python module googleapiclient.
However, the Sheets document may contain some formulas which are not compatible with Microsoft Excel (https://www.dataeverywhere.com/article/27-incompatible-formulas-between-excel-and-google-sheets/).
When I use the application I created on any Google Sheets document that used any of these formulas anywhere, I get a bogus Microsoft Excel document as output.
I would like to read the cell values in the Google Sheets document before downloading it as a Microsoft Excel document, just to prevent any such errors from happening.
The code I have written thus far is attached below:
import sys
import os
from googleapiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
SCOPES = "https://www.googleapis.com/auth/drive.readonly"
store = file.Storage("./credentials/credentials.json")
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets("credentials/client_secret.json",
SCOPES)
creds = tools.run_flow(flow, store)
DRIVE = discovery.build("drive", "v3", http = creds.authorize(Http()))
print("Usage: tmp.py <name of the spreadsheet>")
FILENAME = sys.argv[1]
SRC_MIMETYPE = "application/vnd.google-apps.spreadsheet"
DST_MIMETYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
files = DRIVE.files().list(
q = 'name="%s" and mimeType="%s"' % (FILENAME, SRC_MIMETYPE),
orderBy = "modifiedTime desc,name").execute().get("files", [])
if files:
fn = '%s.xlsx' % os.path.splitext(files[0]["name"].replace(" ", "_"))[0]
print('Exporting "%s" as "%s"... ' % (files[0]['name'], fn), end = "")
data = DRIVE.files().export(fileId=files[0]['id'], mimeType=DST_MIMETYPE).execute()
if data:
with open(fn, "wb") as f:
f.write(data)
print("Done")
else:
print("ERROR: Could not download file")
else:
print("ERROR: File not found")
If you want to use python to export something from google docs, then the simplest way is to let googles own server do the job for you.
I was doing a little webscraping on google sheets, and I made this little program which will do the job for you. You just have to insert the id of the document you want to download.
I put in a temporary id, so anyone can try it out.
import requests
ext = 'xlsx' #csv, ods, html, tsv and pdf can be used as well
key = '1yEoHh7WL1UNld-cxJh0ZsRmNwf-69uINim2dKrgzsLg'
url = f'https://docs.google.com/spreadsheets/d/{key}/export?format={ext}'
res = requests.get(url)
with open(f'file.{ext}', 'wb') as f:
f.write(res.content)
That way conversion will most certainly always be correct, because this is the same a clicking the export button inside the browser version of google sheets.
If you are planning to work with the data inside python, then I recommend using csv format instead of xlsx, and then create the necessary formulas inside python.
I think the gspread library might be what you are looking for. https://gspread.readthedocs.io/en/latest/
Here's a code sample:
import tenacity
import gspread
from oauth2client.service_account import ServiceAccountCredentials
#tenacity.retry(wait=tenacity.wait_exponential()) # If you exceed the Google API quota, this waits to retry your request
def loadGoogleSheet(spreadsheet_name):
# use creds to create a client to interact with the Google Drive API
print("Connecting to Google API...")
scope = [
'https://spreadsheets.google.com/feeds',
'https://www.googleapis.com/auth/drive'
]
creds = ServiceAccountCredentials.from_json_keyfile_name('client_secret.json', scope)
client = gspread.authorize(creds)
spreadsheet = client.open(spreadsheet_name)
return spreadsheet
def readGoogleSheet(spreadsheet):
sheet = spreadsheet.sheet1 # Might need to loop through sheets or whatever
val = sheet.cell(1, 1).value # This just gets the value of the first cell. The docs I linked to above are pretty helpful on all the other stuff you can do
return val
test_spreadsheet = loadGoogleSheet('Copy of TLO Summary - Template DO NOT EDIT')
test_output = readGoogleSheet(test_spreadsheet)
print(test_output)
I am getting all the data present in google sheet using code below,
i want to write all these data to the pdf file and download that.
import gspread
import sys
print(sys.path)
import os
#sys.path.append('/usr/lib/python3/dist-packages')
from oauth2client.service_account import ServiceAccountCredentials
scope = [
'https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/drive'
]
path = os.path.abspath('cred.json')
credentials=ServiceAccountCredentials.from_json_keyfile_name('cred.json',scope)
client=gspread.authorize(credentials)
sheet=client.open('xyz').sheet1
data=sheet.get_all_records()
print(data)
I believe your goal as follows.
You want to export Google Spreadsheet of xyz as a PDF file using gspread with python and the service acccount.
Modification points:
Unfortunately, it seems that in the current stage, the Spreadsheet cannot be directly export as a PDF file using gspread. So in this case, requests library and the endpoint for exporting Spreadsheet to PDF are used.
When the points are reflected to your script, it becomes as follows.
Modified script:
import gspread
import sys
print(sys.path)
import os
#sys.path.append('/usr/lib/python3/dist-packages')
from oauth2client.service_account import ServiceAccountCredentials
scope = [
'https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/drive'
]
path = os.path.abspath('cred.json')
creds=ServiceAccountCredentials.from_json_keyfile_name('cred.json',scope)
client=gspread.authorize(creds)
# I added below script
spreadsheet_name = 'xyz'
spreadsheet = client.open(spreadsheet_name)
url = 'https://docs.google.com/spreadsheets/export?format=pdf&id=' + spreadsheet.id
headers = {'Authorization': 'Bearer ' + creds.create_delegated("").get_access_token().access_token}
res = requests.get(url, headers=headers)
with open(spreadsheet_name + ".pdf", 'wb') as f:
f.write(res.content)
Note:
In this modified script, it supposes that you hav ealready been able to get values from Google Spreadsheet using Sheets API. Please be careful this.
If an error related to Drive API, please enable Drive API at the API console.
If an error related to the service account, please modify create_delegated("") to create_delegated("email of the service account").
I'm trying to create a new spreadsheet using the gspread python package, then get its URL path (inside the google drive) and send it to other people so they could go in as well.
I tried to find an answer here and here, with no luck.
I created a brand new Spreadsheet:
import gspread
from gspread_dataframe import get_as_dataframe, set_with_dataframe
gc = gspread_connect()
spreadsheet = gc.create('TESTING SHEET')
Then i Shared it with my account:
spreadsheet.share('my_user#my_company.com', perm_type='user', role='writer')
Then i wrote some random stuff into it:
worksheet = gc.open('TESTING SHEET').sheet1
df = pd.DataFrame.from_records([{'a': i, 'b': i * 2} for i in range(100)])
set_with_dataframe(worksheet, df)
Now when i go to my google drive i can find this sheet by looking for its name ("TESTING SHEET")
But i didn't figure how do i get the URL path in my python code, so i could pass it right away to other people.
Tnx!
You can generate the URL by using Spreadsheet.id. Here's an example that uses spreadsheet variable from your code:
spreadsheet_url = "https://docs.google.com/spreadsheets/d/%s" % spreadsheet.id
I'm using Python 3 running Pycharm and the module gspread to read google sheet files in my google drive. Well, I've followed all steps from this link about how to read a file. Unfortunately, my code here below doesn't work yet.
import gspread
from oauth2client.service_account import ServiceAccountCredentials
scope =['https://docs.google.com/spreadsheets/d/1xnaOZMd2v93tY28h_hsuMnZYXC9YqCfFpQX70lwpN94/edit?usp=sharing']
credentials = ServiceAccountCredentials.from_json_keyfile_name('distech-c1e26e7150b2.json',scope)
gc = gspread.authorize(credentials)
wks = gc.open("POC").sheet1
for temp in wks:
print(temp)
How could I read the google sheet file using this module guys? thanks so much
I got it after a deep research I realize two things.
the scope in my code was wrong cause the scope is just one provided by Google API to grant right access permissions under spreadsheet.
The right scope for me was: scope =['https://spreadsheets.google.com/feeds']
the opener it's just to open the spreadsheet that will return the worksheets within my file.
So solutions thanks to #Pedro Lobito in his post here.
Solution:
I had the same issue with just a couple of spreadsheets on my account, the problem was solved by:
Opening the json key file (projectname-ca997255dada.json)
Find the value of client_email , i.e.: client_email": "278348728734832-compute#developer.gserviceaccount.com
Share your sheet(s) with that email
Now my code looks like:
import gspread
from oauth2client.service_account import ServiceAccountCredentials
scope =['https://spreadsheets.google.com/feeds']
credentials = ServiceAccountCredentials.from_json_keyfile_name('xxx.json',scope)
gc = gspread.authorize(credentials)
spreadsheet = gc.open("POC")
wks = spreadsheet.worksheet('test1')
wks2 = spreadsheet.worksheet('test2')
out = list()
out = wks.col_values(1)
for temp in out:
print(out)
I am having an issue with Gspread's get_all_values()
import json
import gspread
from oauth2client.client import SignedJwtAssertionCredentials
from gmail_variables import *
json_key = json.load(open('key7367.json'))
scope = ['https://spreadsheets.google.com/feeds']
credentials = SignedJwtAssertionCredentials(json_key['client_email'], json_key['private_key'], scope)
gc = gspread.authorize(credentials)
wks = gc.open_by_url('https://docs.google.com/a/test.com/spreadsheets/d/1-cAg..sLt5Ho/edit?usp=sharing')
recipients = wks.get_all_values()
I am trying to write an email program to pull from a Google Spreadsheet. When I try to run it; I get the error.
'Spreadsheet' object has no attribute 'get_all_values'
Any help is appreciated.
You're just opening the workbook and not specifying the worksheet you want to get_all_values from. You need to call the get_worksheet() method. Try:
wks = gc.open_by_url('https://docs.google.com/a/test.com/spreadsheets/d/1-cAg..sLt5Ho/edit?usp=sharing').get_worksheet(0)
recipients = wks.get_all_values()
Where the '0' is the index of the worksheet (0 being the first worksheet in the workbook).
Once you open the spreadsheet(open_by_url), you need to specify the worksheet you are trying to work with, even if you only have one. You can do this a few different ways:
By index (starts from 0)
sh = wks.get_worksheet(0)
By title
sh = wks.worksheet("January")
Most common case: Sheet1
sh = wks.sheet1
So the fix would be
wks = gc.open_by_url('https://docs.google.com/a/test.com/spreadsheets/d/1-cAg..sLt5Ho/edit?usp=sharing')
sh = wks.get_worksheet(0)
recipients = sh.get_all_values()