How to get google sheets name - python

Given a url of googlesheets like https://docs.google.com/spreadsheets/d/1dprQgvpy-qHNU5eHDoOUf9qXi6EqwBbsYPKHB_3c/edit#gid=1139845333
How could I use gspread api to get the name of the sheet?
I mean the name may be sheet1, sheet2, etc
Thanks!

I believe your goal is as follows.
You want to retrieve the sheet names from a Google Spreadsheet from the URL of https://docs.google.com/spreadsheets/d/###/edit#gid=1139845333.
From How could I use gspread api to get the name of the sheet?, you want to achieve this using gsperad for python.
In this case, how about the following sample script?
Sample script:
client = gspread.authorize(credentials)
url = "https://docs.google.com/spreadsheets/d/1dprQgvpy-qHNU5eHDoOUf9qXi6EqwBbsYPKHB_3c/edit#gid=1139845333"
spreadsheet = client.open_by_url(url)
sheet_names = [s.title for s in spreadsheet.worksheets()]
print(sheet_names)
In this script, please use your client = gspread.authorize(credentials).
When this script is run, the sheet names are returned as a list.
References:
open_by_url(url)
worksheets()
Added:
About your following new question,
May I know what if I only want the sheet name of a particular one? Usually, for each additional sheet we create, it comes with a series of number at the end (gid=1139845333), I just want the name for that sheet instead of all.
In this case, how about the following sample script?
Sample script:
client = gspread.authorize(credentials)
url = "https://docs.google.com/spreadsheets/d/1dprQgvpy-qHNU5eHDoOUf9qXi6EqwBbsYPKHB_3c/edit#gid=1139845333"
gid = "1139845333"
sheet_name = [s.title for s in spreadsheet.worksheets() if str(s.id) == gid]
if len(sheet_name) == 1:
print(sheet_name)
else:
print("No sheet of the GID " + gid)

Related

Google Drive API - Linking a spreadsheet comment or it's replies to the corresponding row in the spreadsheet

I retrieved the comments of particular cell in my google spreadsheet using their API with the OAUTH_SCOPE = "https://www.googleapis.com/auth/drive" and version 3.
I get an output which is of this form:
{'kind': 'drive#comment', 'id': 'AAAAnggKMaA', 'createdTime': '2023-01-18T08:56:39.693Z', 'modifiedTime': '2023-01-18T09:03:32.426Z', 'author': {'kind': 'drive#user', 'displayName': 'Andrew Flint', 'photoLink': '//lh3.googleusercontent.com/a/AFBCDEDF3BjIhc6Hgtsb5kDdzVt54vIjG3q0W8d1CYi=s50-c-k-no', 'me': True}, 'htmlContent': 'No version specified in current.json', 'content': 'No version specified in current.json', 'deleted': False, 'resolved': False, 'anchor': '{"type":"workbook-range","uid":0,"range":"1713668520"}', 'replies': [{'kind': 'drive#reply', 'id': 'AAAAnggKMaE', 'createdTime': '2023-01-18T09:03:32.426Z', 'modifiedTime': '2023-01-18T09:03:32.426Z', 'author': {'kind': 'drive#user', 'displayName': 'Andrew Flint', 'photoLink': '//lh3.googleusercontent.com/a/ADDDGyFTp7mR3BjIhc6Hgtsb5kDdzVt54vIjG3q0W8d1CYi=s50-c-k-no', 'me': True}, 'htmlContent': 'Unable to find a package version URLfor Mono-Extended. Found\xa0 somewhat matching package details here :\xa0https://aur.archlinux.org/packages/nerd-fonts-noto-sans-mono-extended but not sure if this is the intended package', 'content': 'Unable to find a package version URLfor Mono-Extended. Found\xa0 somewhat matching package details here :\xa0https://aur.archlinux.org/packages/nerd-fonts-noto-sans-mono-extended but not sure if this is the intended package', 'deleted': False}]}
I now want to associate this comment with that particular row from which this comment was extracted through a python script; i.e. I want to be able to know the row index of the cell from which this comment was extracted or the indices of the anchor cell.
At the moment, there does not seem to be an obvious way to do that. But, I suspect the comment-id might be able to help. Google does not seem to give a way to do that in an obvious way.
Any inputs on this will be deeply appreciated! Thanks!
I believe your goal is as follows.
You want to retrieve the row index of the row with the comment.
You want to achieve this using python.
From your previous question, you are using googleapis for python.
Issue and workaround:
When the anchor cell information is retrieved from the comment ID, in your showing sample, it's 'anchor': '{"type":"workbook-range","uid":0,"range":"1713668520"}. But, in the current stage, unfortunately, the anchor cell cannot be known from it. Ref By this, I thought that your goal cannot be directly achieved by Sheets API and Drive API. I think that if the cell coordinate is retrieved from "range":"1713668520", your goal can be achieved.
From the above situation, I would like to propose a workaround. My workaround is as follows.
Download the Google Spreadsheet using Drive API as XLSX data.
Parse XLSX data using openpyxl.
Using openpyxl, the comments are retrieved from XLSX data converted from Google Spreadsheet.
When this flow is reflected in a python script, how about the following sample script?
Sample script 1:
In this case, please use your script of authorization. The access token is retrieved from it. And, please set your Spreadsheet ID.
service = build("drive", "v3", credentials=creds)
access_token = creds.token # or access_token = service._http.credentials.token
spreadsheetId = "###" # Please set the Spreadsheet ID.
sheetName = "Sheet1" # Please set your sheet name.
url = "https://www.googleapis.com/drive/v3/files/" + spreadsheetId + "/export?mimeType=application%2Fvnd.openxmlformats-officedocument.spreadsheetml.sheet"
res = requests.get(url, headers={"Authorization": "Bearer " + access_token})
workbook = openpyxl.load_workbook(filename=BytesIO(res.content), data_only=False)
worksheet = workbook[sheetName]
res = []
for i, row in enumerate(worksheet.iter_rows()):
for j, cell in enumerate(row):
if cell.comment:
res.append({"rowIndex": i, "columnIndex": j, "comment": cell.comment.text})
print(res)
In this script, please add the following libraries.
import openpyxl
import requests
from io import BytesIO
When this script is run, the Google Spreadsheet is exported in XLSX format, and the XLSX data is parsed and retrieved the comments. And, the row and column indexes and the comment text are returned as an array as follows. Unfortunately, the comment ID of Drive API cannot be retrieved from XLSX data. So, I included the comment text.
[
{'rowIndex': 0, 'columnIndex': 0, 'comment': 'sample comment'},
,
,
,
]
Sample script 2:
As a sample script 2, in this sample script, Google Spreadsheet is exported as XLSX format using googleapis for python.
service = build("drive", "v3", credentials=creds) # Please use your client.
spreadsheetId = "###" # Please set the Spreadsheet ID.
sheetName = "Sheet1" # Please set your sheet name.
request = service.files().export_media(fileId=spreadsheetId, mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
fh = BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
print("Download %d%%" % int(status.progress() * 100))
fh.seek(0)
workbook = openpyxl.load_workbook(filename=fh, data_only=False)
worksheet = workbook[sheetName]
res = []
for i, row in enumerate(worksheet.iter_rows()):
for j, cell in enumerate(row):
if cell.comment:
res.append({"rowIndex": i, "columnIndex": j, "comment": cell.comment.text})
print(res)
In this case, googeapis for python is used. So, requests is not used.
When this script is run, the same value with the above script is obtained.
Reference:
Files: export

Trying to capture API response code from gspread_dataframe function

I have a short loop updating several gsheets, and I'd like to capture the return code from the requests to the API. I'm using the gspread and gspread_dataframe libraries. I know the function that I need to capture the response for is the set_as_dataframe() function, but I'm unable to find anything in the documentation about how to return the response code.
import os
import time
import gspread
import gspread_dataframe as gd
from oauth2client.service_account import ServiceAccountCredentials
os.chdir('C:\\mydir') # locate ourselves in the directory
# import tbls to push to gsheet
import pull_tbls
# example dataframes
tbl_1 = {'first_col': [1,2,3],
'second_col': ['apple', 'orange', 'banana']}
tbl_2 = {'first_col': [4,5,6],
'second_col': ['potato', 'carrot', 'lemon']}
tbl_1 = pull_tbls.tbl_1
tbl_2 = pull_tbls.tbl_2
# set scope
scope = ['https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/spreadsheets']
# provide credentials
credentials = ServiceAccountCredentials.from_json_keyfile_name('my_json_keyfile.json', scope)
gc = gspread.authorize(credentials)
# list of the google sheets we want to update
sheet_list = ['tbl_1', 'tbl_2']
# loop
for sheet in sheet_list:
print(sheet)
sheet = gc.open(sheet)
# sleep to avoid API limits
time.sleep(60)
wks = sheet.sheet1
# delete existing rows
wks.clear()
# when sheet matches tbl name
# replace sheet contents with tbl
sheet_name = wks.spreadsheet.title
if sheet_name == 'tbl_1':
new_data = tbl_1
elif sheet_name == 'tbl_2':
new_data = tbl_2
else:
print('sheet name not found!')
# update gsheet with new data
if new_data.empty:
print(sheet_name + ' is empty!')
continue
gd.set_with_dataframe(wks, new_data) #this is the API response I want to capture
# sleep to avoid API limits
time.sleep(100)
I'm not sure where in this process I'm able to capture the API response to updating the gsheet.
I ended up opening an issue with the maintainer. For anyone looking to see the API response for their gspread_dataframe() calls, if you add a logger and include logging.getLogger('gspread_dataframe') in your logger configuration, you should be able to see the results.

Skip header using Google Sheet Api with python and Pandas

I'm writing data to Google Sheets using their API. However, each time I append the document, I get an header. How can I write my data without each time getting a header.
This is my code :
df = pd.DataFrame(["a","b","c"])
df.columns = [''] * len(df.columns)
print(df)
def Export_Data_To_Sheets():
response_date = service.spreadsheets().values().append(
spreadsheetId=SAMPLE_SPREADSHEET_ID_input,
valueInputOption='RAW',
#insertDataOption='INSERT_ROWS',
range=SAMPLE_RANGE_NAME,
body=dict(
majorDimension='ROWS',
values=df.T.reset_index().T.values.tolist())
).execute()
print('Sheet successfully Updated')
Export_Data_To_Sheets()
I thought this was going to work, but the header seems to be added in the Export function.
Any ideas ?

Google Sheets Find Previously Created Sheet Using Name

My use-case is to use a script to create/update a sheet on my google drive and have it run everyday so the data is correct.
My code properly creates the sheet, but when I run each day it creates a different sheet with the same name. I want to add a try, except to see if the sheet was previously, and if it is, just overwrite.
I've spent a couple of hours trying to find an example where someone did this. I'm looking to return the sheetid, whether it's newly created or previously created.
def create_spreadsheet(sp_name, creds):
proxy = None
#Connect to sheet API
sheets_service = build('sheets', 'v4', http=creds.authorize(httplib2.Http(proxy_info = proxy)))
#create spreadsheet with title 'sp_title'
sp_title = sp_name
spreadsheet_req_body = {
'properties': {
'title': sp_title
}
}
spreadsheet = sheets_service.spreadsheets().create(body=spreadsheet_req_body,
fields='spreadsheetId').execute()
return spreadsheet.get('spreadsheetId')
You want to check whether the file (Spreadsheet), which has the specific filename, is existing in your Google Drive.
If the file is existing, you want to return the file ID of it.
If the file is not existing, you want to return the file ID by creating new Spreadsheet.
You want to achieve above using google-api-python-client of Python.
If my understanding is correct, how about this modification? There is the method for confirming whether the file, which has the specific filename, is existing using Drive API. In this modification, the method of Files: list Drive API is used. Please think of this as just one of several answers.
Modification points:
In this modification, the method of Files: list Drive API is used. The file is checked with the search query.
In this case, the file is searched by the filename and the mimeType and out of the trash box.
When the file is existing, the file ID is return.
When the file is NOT existing, new Spreadsheet is created and return the file ID by your script.
Modified script:
Please modify your script as follows.
def create_spreadsheet(sp_name, creds):
proxy = None
sp_title = sp_name
# --- I added blow script.
drive_service = build('drive', 'v3', http=creds.authorize(httplib2.Http(proxy_info = proxy)))
q = "name='%s' and mimeType='application/vnd.google-apps.spreadsheet' and trashed=false" % sp_title
files = drive_service.files().list(q=q).execute()
f = files.get('files')
if f:
return f[0]['id']
# ---
sheets_service = build('sheets', 'v4', http=creds.authorize(httplib2.Http(proxy_info = proxy)))
sp_title = sp_name
spreadsheet_req_body = {
'properties': {
'title': sp_title
}
}
spreadsheet = sheets_service.spreadsheets().create(body=spreadsheet_req_body,
fields='spreadsheetId').execute()
return spreadsheet.get('spreadsheetId')
Note:
In this modification, I used https://www.googleapis.com/auth/drive.metadata.readonly as the scope. So please enable Drive API and add the scope and delete the file including the access token and refresh token, then please authorize the scopes by running the script, again. By this, the additional scope can be reflected to the access token. Please be careful this.
Reference:
Files: list of Drive API
If I misunderstood your question and this was not the direction you want, I apologize.

find google spreadsheet by title via api in python

I would like to retrieve data of spreadsheet by searching for the spreadsheet by name. I wonder how it works?
result = service.spreadsheets().values().get(title=spreadsheetTitle, range=rangeName).execute()
From this example, you can open a spreadsheet by its title or url.
Example:
def open(self, title):
"""Opens a spreadsheet, returning a :class:`~gspread.Spreadsheet` instance.
:param title: A title of a spreadsheet.
If there's more than one spreadsheet with same title the first one
will be opened.
:raises gspread.SpreadsheetNotFound: if no spreadsheet with
specified `title` is found.
>>> c = gspread.Client(auth=('user#example.com', 'qwertypassword'))
>>> c.login()
>>> c.open('My fancy spreadsheet')
"""
feed = self.get_spreadsheets_feed()
for elem in feed.findall(_ns('entry')):
elem_title = elem.find(_ns('title')).text
if elem_title.strip() == title:
return Spreadsheet(self, elem)
else:
raise SpreadsheetNotFound
You can also check these links:
How do I access (read, write) to Google Sheets spreadsheets with Python?
How do I search Google Spreadsheets?
You can use pygsheets, a python library for google sheets api v4.
import pygsheets
gc = pygsheets.authorize()
# Open spreadsheet by title
sh = gc.open('my new ssheet')

Categories