I have full edit access to a Google Sheet not owned by me. I want to be able to write to the spreadsheet using Python without Google API authorization. I checked several available packages (gdata, gspread etc.) and seems all of them ask for the credentials.
I was also able to read the content of a spreadsheet without authorization using requests or pd.read_csv() by pandas (I tweaked the URL by changing the last part saying ...edit#gid=... to ...export?format=csv&gid=...). Yet, when sending a POST request to the same URL I received 200 status code but the same old empty spreadsheet.
Any help is highly appreciated.
I believe your goal as follows.
You want to put the values to the publicly shared Google Spreadsheet using python.
In this case, you want to access to the Spreadsheet without authorization.
For this, how about this answer?
Issue and workaround:
In order to put the values to the publicly shared Google Spreadsheet, the POST method is used. In this case, it is required to use the access token. On the other hand, in the case of the GET method, when the Sheets API is used, an API key can be used. And the endpoints like exportLinks, you can retrieve the values without the API key. These are the specification of Google side.
Under this condition, in order to achieve your goal, I would like to propose the following 2 patterns.
Pattern 1:
In this pattern, I would like to propose to access to the Spreadsheet using the access token retrieved from the service account. In this case, the script can be simpler.
Sample script:
import gspread
from oauth2client.service_account import ServiceAccountCredentials
spreadsheetId = "###" # Please set the Spreadsheet ID.
scope = ['https://www.googleapis.com/auth/spreadsheets']
credentials = ServiceAccountCredentials.from_json_keyfile_name('credentials.json', scope)
client = gspread.authorize(credentials)
spreadsheet = client.open_by_key(spreadsheetId)
worksheet = spreadsheet.sheet1
worksheet.update_acell('A1', 'sample')
In this sample script, sample is put to the cell "A1" of the 1st tab in the publicly shared Spreadsheet using gspread.
Pattern 2:
In this pattern, I would like to propose to access to the Spreadsheet using the Web Apps created by Google Apps Script as the wrapper API. In this case, the python script is more simpler.
Usage:
Please do the following flow.
1. Create new project of Google Apps Script.
Sample script of Web Apps is a Google Apps Script. So please create a project of Google Apps Script.
If you want to directly create it, please access to https://script.new/. In this case, if you are not logged in Google, the log in screen is opened. So please log in to Google. By this, the script editor of Google Apps Script is opened.
2. Prepare script.
Please copy and paste the following script (Google Apps Script) to the script editor. And please enable Google Sheets API at Advanced Google services. This script is for the Web Apps.
function doPost(e) {
try {
const spreadsheetId = e.parameter.spreadsheetId;
const obj = JSON.parse(e.postData.contents);
const resource = obj.body;
const range = obj.arguments.range;
const valueInputOption = obj.arguments.valueInputOption;
Sheets.Spreadsheets.Values.update(resource, spreadsheetId, range, {valueInputOption: valueInputOption});
return ContentService.createTextOutput("ok");
} catch(e) {
return ContentService.createTextOutput(JSON.stringify(e));
}
}
In this case, the POST method is used.
In this sample script, as a test script, the values are put to the Spreadsheet using the method of spreadsheets.values.update in Sheets API.
3. Deploy Web Apps.
On the script editor, Open a dialog box by "Publish" -> "Deploy as web app".
Select "Me" for "Execute the app as:".
By this, the script is run as the owner.
Select "Anyone, even anonymous" for "Who has access to the app:".
In this case, no access token is required to be request. I think that I recommend this setting for your goal.
Of course, you can also use the access token. At that time, please set this to "Anyone".
Click "Deploy" button as new "Project version".
Automatically open a dialog box of "Authorization required".
Click "Review Permissions".
Select own account.
Click "Advanced" at "This app isn't verified".
Click "Go to ### project name ###(unsafe)"
Click "Allow" button.
Click "OK".
Copy the URL of Web Apps. It's like https://script.google.com/macros/s/###/exec.
When you modified the Google Apps Script, please redeploy as new version. By this, the modified script is reflected to Web Apps. Please be careful this.
4. Run the function using Web Apps.
This is a sample python script for requesting Web Apps. Please set your Web Apps URL, Spreadsheet ID and range.
import json
import requests
spreadsheet_id = '###' # Please set the Spreadsheet ID.
body = {
"arguments": {"range": "Sheet1!A1", "valueInputOption": "USER_ENTERED"},
"body": {"values": [["sample"]]}
}
url = 'https://script.google.com/macros/s/###/exec?spreadsheetId=' + spreadsheet_id
res = requests.post(url, json.dumps(body), headers={'Content-Type': 'application/json'})
print(res.text)
In this sample script, sample is put to the cell "A1" of the 1st tab in the publicly shared Spreadsheet.
In this case, no authorization is required in the python script, because it has already been done when Web Apps is deployed.
Note:
When you modified the script of Web Apps, please redeploy the Web Apps as new version. By this, the latest script is reflected to the Web Apps. Please be careful this.
References:
Web Apps
Taking advantage of Web Apps with Google Apps Script
Advanced Google services
publish a Google Spreadsheet through Google Apps Scripts
spreadsheets.values.update
Can I read a google spreadsheet which is open to people, but doesn't have a share option? There's a discussion here, but it's I need to have an authorization to click the share option.
Even copying by URL to my own Google spreadsheet may serve the purpose.
Update:
The idea was once I create a Google API, I should be able to create a .json file with a client email. In the share option, I'm supposed to provide the client email of .json file. You may see: Accessing Google Spreadsheet Data using Python.
This is the spreadsheet page where I'm not finding any Share option: https://docs.google.com/spreadsheets/d/e/2PACX-1vSc_2y5N0I67wDU38DjDh35IZSIS30rQf7_NYZhtYYGU1jJYT6_kDx4YpF-qw0LSlGsBYP8pqM_a1Pd/pubhtml#
Issue:
Publishing the contents of a spreadsheet to the web is not the same as making a spreadsheet public.
The URL you shared refers to spreadsheet contents that were published to the web following these steps. This published website is not the same as the original file where the data comes from, and so it doesn't have most of its functionalities, like a Share button (it doesn't make sense to have a Share button anyway, since this URL is already public).
Solution:
If you want to access the spreadsheet data using a Service Account, you would have to do one of the following (better to use method 1 if you have access to the spreadsheet):
Share the spreadsheet itself (not the published contents) with the Service Account, as explained in the link you referenced.
Use your application to fetch the website contents from the provided URL.
Reference:
Make Google Docs, Sheets, Slides & Forms public
So with the google sheets api, I can use a credentials json file to edit a google sheet. I don't have to login again and again. Is it possible to do this same thing with the google drive api? I am making a Python webapp, and it is very inefficient to need to log into a google account every time I want to upload a file. I plan on only uploading files to one drive, and not multiple accounts. I have looked on stack overflow a couple times, and can only find documentation on how to login with a user account and this requires I login every time.
Best wishes,
Jake
You can do the same thing as in Sheets, follow the official Python Quickstart from the docs for instructions on how to do it.
I'm trying to create a chatbot using dialog flow , for this i have my data in excel sheet and i want to use this as a database source for my bot! Is there any way that i can do it without writing several intents?
Dialogflow has no direct connection to Google Sheets or the Sheets API. If you want to use a Sheet as the source of some answers, you will need to integrate it through Dialogflow Intents and a Fulfillment webhook.
In your webhook, you will need to make calls to the Sheets API to get the info you want to be able to return.
I have an access to the not-mine private spreadsheet on the Google Sheet. When I access to that spreadsheet from browser, everything is fine. But, when I try to retrieve the content of that spreadsheet through Google Sheets API using Python, I am getting 403 error - "The caller does not have permission".
The problem is I can not ask the owner to give me one more permission for my API.
Can I retrieve the content of that spreadsheet somehow? Maybe using some tools?
You prolly can access it because you got the link from someone. But to access it using the API will require you to be added in the permissions. Worth checking would be this Google Drive SDK: Sharing Files tutorial video and the Permissions docs.