Google API: sheets KeyError: '_module' while calling get_credentials() - python

I have pretty similar code as google on a quick start page suggest.
from __future__ import print_function
import httplib2
import os
from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/sheets.googleapis.com-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/spreadsheets.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Google Sheets API Python Quickstart'
def get_credentials():
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
the OAuth2 flow is completed to obtain the new credentials.
Returns:
Credentials, the obtained credential.
"""
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'sheets.googleapis.com-python-quickstart.json')
store = Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatibility with Python 2.6
credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
def main():
"""Shows basic usage of the Sheets API.
Creates a Sheets API service object and prints the names and majors of
students in a sample spreadsheet:
https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
"""
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
discoveryUrl = ('https://sheets.googleapis.com/$discovery/rest?'
'version=v4')
service = discovery.build('sheets', 'v4', http=http,
discoveryServiceUrl=discoveryUrl)
spreadsheetId = '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms'
rangeName = 'Class Data!A2:E'
result = service.spreadsheets().values().get(
spreadsheetId=spreadsheetId, range=rangeName).execute()
values = result.get('values', [])
if not values:
print('No data found.')
else:
print('Name, Major:')
for row in values:
# Print columns A and E, which correspond to indices 0 and 4.
print('%s, %s' % (row[0], row[4]))
if __name__ == '__main__':
main()
Firstly, I created my own secret file. Then executed without that file 'sheets.googleapis.com-python-quickstart.json' and .credentials folder was created, but faced sheets.googleapis.com-python-quickstart.json: No such file or directory error
So then I created that empty file sheets.googleapis.com-python-quickstart.json on that folder, but faced another error KeyError: '_module'. I even tried to rename my secret file as sheets.googleapis.com-python-quickstart.json - same error. I have executed this code from console and from ipython notebook - same error. Changing SCOPES by deleting .readonly - didn't help
Is there any webpage should be opened? What am I doing wrong?
My question looks the same as - but nothing helped and my question should be about a bit different think
Full error stack:
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-83-58ca95c5b364> in <module>()
----> 1 main()
<ipython-input-82-1e078df2aa91> in main()
37 https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
38 """
---> 39 credentials = get_credentials()
40 http = credentials.authorize(httplib2.Http())
41 discoveryUrl = ('https://sheets.googleapis.com/$discovery/rest?'
<ipython-input-82-1e078df2aa91> in get_credentials()
20
21 store = Storage(credential_path)
---> 22 credentials = store.get()
23
24 if not credentials or credentials.invalid:
~\AppData\Local\Continuum\Anaconda3\lib\site-packages\oauth2client\client.py in get(self)
405 self.acquire_lock()
406 try:
--> 407 return self.locked_get()
408 finally:
409 self.release_lock()
~\AppData\Local\Continuum\Anaconda3\lib\site-packages\oauth2client\file.py in locked_get(self)
52
53 try:
---> 54 credentials = client.Credentials.new_from_json(content)
55 credentials.set_store(self)
56 except ValueError:
~\AppData\Local\Continuum\Anaconda3\lib\site-packages\oauth2client\client.py in new_from_json(cls, json_data)
300 # Find and call the right classmethod from_json() to restore
301 # the object.
--> 302 module_name = data['_module']
303 try:
304 module_obj = __import__(module_name)
KeyError: '_module'

First of all proper JSON should be downloaded, it should be for web server.
Secondly that JSON should contain redirect URL "redirect_uris":"http://localhost:8080/"
That URL also should be added to settings in the google account, where you have just generated that JSON

Related

'NoneType' error while running calendar api python3

I'm working on python script which captures all my events in google calendar. this code will show the list of all the events in a day.
Below is the code.
from __future__ import print_function
import httplib2
import os
import datetime
from apiclient import discovery
import oauth2client
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
import datetime
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/calendar-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/calendar.readonly'
CLIENT_SECRET_FILE = 'credentials.json'
APPLICATION_NAME = 'Google Calendar API Python Quickstart'
def get_credentials():
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
the OAuth2 flow is completed to obtain the new credentials.
Returns:
Credentials, the obtained credential.
"""
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'calendar-python-quickstart.json')
store = oauth2client.file.Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatibility with Python 2.6
credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
def main():
"""Shows basic usage of the Google Calendar API.
Creates a Google Calendar API service object and outputs a list of the next
10 events on the user's calendar.
"""
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('calendar', 'v3', http=http)
now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time
print('Getting the upcoming 10 events')
eventsResult = service.events().list(
calendarId='primary', timeMin=now, maxResults=10, singleEvents=True,
orderBy='startTime').execute()
events = eventsResult.get('items', [])
if not events:
print('No upcoming events found.')
for event in events:
start = event['start'].get('dateTime')
# print(start)
start = start[:-9]
# print(start)
start = datetime.datetime.strptime(start,"%Y-%m-%dT%H:%M")
pretty_time = start.strftime("%I:%M")
pretty_date = start.strftime("%B %d, %Y")
print(event['summary'],"at",pretty_time,"on",pretty_date)
if __name__ == '__main__':
main()
below is the error which I'm getting. Not able to find the what is the mistake I made. please help.
below is the error which I'm getting. Not able to find the what is the mistake I made. please help.
Traceback (most recent call last):
File "/Users/mbhamidipati/python-practice/change/getevents.py", line 86, in <module>
main()
File "/Users/mbhamidipati/python-practice/change/getevents.py", line 75, in main
start = start[:-9]
TypeError: 'NoneType' object is not subscriptable
Thanks,
Sreman
It seems that the main thing you need to decide is how you're going to handle when
event['start'].get('dateTime') returns None
you can add a default value to .get('dateTime')
Something like this, assuming that you can get a value from another key, such as 'date'
start = event['start'].get('dateTime', event['start'].get('date'))

Using python for google calendar watch-requests

I want to set up a watch request for a google calendar, using python
(without setting up a separate domain).
I imported the api client, and can successfully get the authenticated credentials, following the example: https://developers.google.com/google-apps/calendar/quickstart/python.
Then I set up a calendar service, and I am able to list, insert and delete events without any issue.
The problem I am having is when I perform a watch request so that I have a webhook from within python.
I receive the error:
"googleapiclient.errors.HttpError: https://www.googleapis.com/calendar/v3/calendars/primary/events/watch?alt=json returned "WebHook callback must be HTTPS:">"
Clearly I am missing something that needs to be setup so that calendar is satisfied with the webhook I am giving it.
Is it possible to do this from within python, without setting up a separate domain with https, and if so, how?
Minimum working example:
import httplib2
import os
from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
import uuid
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
SCOPES = 'https://www.googleapis.com/auth/calendar'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Calendar API'
def get_credentials():
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'calendar-api.json')
store = Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else:
credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
def main():
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('calendar', 'v3', http=http)
## TESTING callback receiver:
eventcollect = {
'id': str(uuid.uuid1()),
'type': "web_hook"
}
service.events().watch(calendarId='primary', body=eventcollect).execute()
if __name__ == '__main__':
main()
In the documentation of watch requests, there is a Required Properties part. In this part it is clearly stated that:
An address property string set to the URL that listens and responds to notifications for this notification channel. This is your Webhook callback URL, and it must use HTTPS.
I am sorry but I do not think there is a workaround for this.

How to loop over nextPageToken using GoogleDrive's Python Quickstart

My goal is to have a list of all of the items & folders in everyone's Google Drive. I'm starting with trying to make sure the script works on my own. I have read cover-to-cover the Drive REST API documentation, and eventually found this code, which can also be found here.
from __future__ import print_function
import httplib2
import os
import sys
from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
reload(sys)
sys.setdefaultencoding('utf-8')
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/drive-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Drive API Python Quickstart'
def get_credentials():
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
the OAuth2 flow is completed to obtain the new credentials.
Returns:
Credentials, the obtained credential.
"""
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'drive-python-quickstart.json')
store = Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatibility with Python 2.6
credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
def main():
"""Shows basic usage of the Google Drive API.
Creates a Google Drive API service object and outputs the names and IDs
for up to 10 files.
"""
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('drive', 'v3', http=http)
results = service.files().list(
pageSize=1000,fields="nextPageToken, files(mimeType, name)").execute()
items = results.get('files', [])
if not items:
print('No files found.')
else:
print('Files:')
for item in items:
print('{0} ({1})'.format(item['name'], item['mimeType']))
if __name__ == '__main__':
main()
My problem is with the nextPageToken, and how to properly use it. The max PageSize is 1000, so I must loop over the nextPageToken, fetch it from the resulting JSON, put it back into the original loop (line 66?), to get another 1000 results. How do I do this?
Let's look the google drive api documentation for the File:list Method
In the fields of your request you are asking the nextPageToken, the result will contain the token for the nextPage (if the nextPage exists).
The result will be something like this :
{
...,
"nextPageToken": "V1*3|0|XXXXXX",
"files": [
{
...
},...
]
}
you can extract nextPageToken value like :
token = results.get('nextPageToken', None)
The List method can take the string parameter pageToken :
The token for continuing a previous list request on the next page.
This should be set to the value of 'nextPageToken' from the previous
response.
Just set the parameter pageToken in the next request to get the next page of results :
results = service.files().list(
pageSize=1000,
pageToken=token,
fields="nextPageToken, files(mimeType, name)").execute()
items = results.get('files', [])
Now you can easily make a loop to get all result.
I will try to demonstrate the concept for you but you'll do the implementation in Python. The short answer is, nextPageToken. nextPageTokens enable you to retrieve the results from the next page.
When you perform a GET request, a nextPageToken will always be included in the response so if you had 1000 results but you only wanted to display 20 per page, you can fetch the remaining 980 files using nextPageToken.
Run this URL and you'll see something like:
"kind": "drive#fileList",
"nextPageToken": "V1*3|0|CjkxOHY2aDdROE9JYkJGWUJEaU5Ybm1OVURSemJTcWFMa2lRQlVJSnVxYmI2YkYzMmhnVHozeWkwRnASBxCqqcG4kis",
"incompleteSearch": false,
The value of the nextPageToken here is what you use to get to the next page. When you get to the next page and you have more results, a new nextPageToken will be generated for you until you view/get all the results (980-1000).
You must looping while token (for the nextpage) is not null, like this code at the end:
(do not forget to install -->
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
Copy and paste this code (Do not forget to change your paths and your googleDrive folder ID, at the end)
from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.http import MediaFileUpload, MediaIoBaseDownload
# If modifying these scopes, delete the file token.pickle.
SCOPES = [
'https://www.googleapis.com/auth/spreadsheets',
"https://www.googleapis.com/auth/drive.file",
"https://www.googleapis.com/auth/drive"
]
# FOR AUTHENTICATION
def authenticate():
creds = None
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
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(
'YOUR PATH FOR THE CREDENTIALS JSON/credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
with open('YOUR PATH /token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('drive', 'v3', credentials=creds)
return service
# LISTS TO TAKE ALL FILES AND IDs FROM SPECIFIC FOLDER
listFilesDrive=[]
line = []
# TO TAKE ALL FILES FROM SPECIFIC FOLDER
def listFilesFromGoogleFolder(IDFolder):
service = authenticate()
# Call the Drive v3 API
results = service.files().list( q="'{}' in parents".format(FolderIDFromGDrive),
fields="nextPageToken, files(id, name)").execute()
items = results.get('files', [])
# TAKE TOKEN FROM THE NEXT PAGE (IF THERE IS NO ONE, THIS VALUE WILL BE NULL)
token = results.get('nextPageToken', None)
#print('token->>',nextPageToken)
if not items:
print('No files found.')
else:
print('Files:')
line = []
for item in items:
# TAKE FIRST PAGE IN A LIST ->> "listFilesDrive"
arquivo = item['name']
IDarquivo = item['id']
line.append(arquivo)
line.append(IDarquivo)
listFilesDrive.append(line)
line=[]
print(u'{0} ({1})'.format(item['name'], item['id']))
# LOOPING WHILE TOKEN FOR OTHER PAGES IS NOT NULL TOKEN
while token!=None:
service = authenticate()
results = service.files().list( q="'{}' in parents".format(IDFolder),
pageToken=token,
fields="nextPageToken, files(id, name)").execute()
items = results.get('files', [])
# TAKE A NEW TOKEN FOR THE NEXT PAGE, IF THERE IS NO, THIS TOKEN WILL BE NULL ("None")
token = results.get('nextPageToken', None)
if not items:
print('No files found.')
else:
print('Files:')
linha = []
for item in items:
arquivo = item['name']
IDarquivo = item['id']
line.append(arquivo)
line.append(IDarquivo)
listFilesDrive.append(line)
line=[]
print(u'{0} ({1})'.format(item['name'], item['id']))
print(len(listFilesDrive))
print(listFilesDrive)
# put your specific information
if __name__ == '__main__':
FolderIDFromGDrive='YOUR FOLDER ID'
listFilesFromGoogleFolder(FolderIDFromGDrive)
I had quite a bit of trouble with this. I didn't read the example closely enough to notice that nextPageToken & newStartPageToken were not the same thing.
I split up the functions a little and added a loop. Basically, return the startPageToken and loop over the same function / call the function as required.
from __future__ import print_function
import httplib2
import os
#julian
import time
from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/drive-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Drive API Python Quickstart'
def get_credentials():
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
the OAuth2 flow is completed to obtain the new credentials.
Returns:
Credentials, the obtained credential.
"""
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,'drive-python-quickstart.json')
store = Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatibility with Python 2.6
credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
def main():
"""Shows basic usage of the Google Drive API.
Creates a Google Drive API service object and outputs the names and IDs
for up to 10 files.
"""
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('drive', 'v3', http=http)
saved_start_page_token = StartPage_v3(service)
saved_start_page_token = DetectChanges_v3(service, saved_start_page_token)
starttime=time.time()
while True:
saved_start_page_token = DetectChanges_v3(service, saved_start_page_token)
time.sleep(10.0 - ((time.time() - starttime) % 10.0))
def StartPage_v3(service):
response = service.changes().getStartPageToken().execute()
print('Start token: %s' % response.get('startPageToken'))
return response.get('startPageToken')
def DetectChanges_v3(service, saved_start_page_token):
# Begin with our last saved start token for this user or the
# current token from getStartPageToken()
page_token = saved_start_page_token;
while page_token is not None:
response = service.changes().list(pageToken=page_token, spaces='drive').execute()
for change in response.get('changes'):
# Process change
mimeType = change.get('file').get('mimeType')
print( 'Change found for: %s' % change)
if 'newStartPageToken' in response:
# Last page, save this token for the next polling interval
saved_start_page_token = response.get('newStartPageToken')
page_token = response.get('nextPageToken')
return saved_start_page_token
if __name__ == '__main__':
main()

Not able to download google spreadsheet by google drive API using python

I am trying to download a spreadsheet file from my drive to my computer.
I am able to authenticate, get list of files and even get meta-data successfully.
But when I try to download the file, I get the following error :
downloading file starts
An error occurred: <HttpError 400 when requesting https://www.googleapis.com/dri
ve/v2/files/1vJetI_p8YEYiKvPVl0LtXGS5uIAx1eRGUupsXoh7UbI?alt=media returned "The
specified file does not support the requested alternate representation.">
downloading file ends
I couldn't get any such problem or question on SO and the other methods or solutions provided on SO for downloading the spreadsheet are outdated.Those have been deprecated by Google .
Here is the code, I am using to download the file :
import httplib2
import os
from apiclient import discovery
import oauth2client
from oauth2client import client
from oauth2client import tools
from apiclient import errors
from apiclient import http
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
#SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly'
SCOPES = 'https://www.googleapis.com/auth/drive'
CLIENT_SECRET_FILE = 'client_secrets.json'
APPLICATION_NAME = 'Drive API Quickstart'
def get_credentials():
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'drive-quickstart.json')
store = oauth2client.file.Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatability with Python 2.6
credentials = tools.run(flow, store)
print 'Storing credentials to ' + credential_path
return credentials
def main():
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('drive', 'v2', http=http)
file_id = '1vJetI_p8YEYiKvPVl0LtXGS5uIAx1eRGUupsXoh7UbI'
print "downloading file starts"
download_file(service, file_id)
print "downloading file ends "
def download_file(service, file_id):
local_fd = open("foo.csv", "w+")
request = service.files().get_media(fileId=file_id)
media_request = http.MediaIoBaseDownload(local_fd, request)
while True:
try:
download_progress, done = media_request.next_chunk()
except errors.HttpError, error:
print 'An error occurred: %s' % error
return
if download_progress:
print 'Download Progress: %d%%' % int(download_progress.progress() * 100)
if done:
print 'Download Complete'
return
if __name__ == '__main__':
main()
Google spreadsheets don't have media. Instead they have exportLinks. Get the file metadata, then look in the exportlinks and pick an appropriate URL.
This code worked for me. I only had to download client_secret.json from google developers dashboard and keep in the same directory as python script.
And in the list_of_lists variable I got a list with each row as list.
import gspread
import json
from oauth2client.client import SignedJwtAssertionCredentials
json_key = json.load(open('client_secret.json'))
scope = ['https://spreadsheets.google.com/feeds']
credentials = SignedJwtAssertionCredentials(json_key['client_email'], json_key['private_key'], scope)
gc = gspread.authorize(credentials)
sht1 = gc.open_by_key('<id_of_sheet>')
worksheet_list = sht1.worksheets()
worksheet = sht1.sheet1
list_of_lists = worksheet.get_all_values()
for row in list_of_lists :
print row

Error 403 when trying to upload file to google drive via python

So I'm new to python (and this is a first post to stack overflow). I'm trying to use python to upload and download files to and from a google drive account (and eventually reference files from this drive on a customized work tiki wiki). The code below is from google's python api resources. It will successfully list the files on my drive (as it should). However, when I attempt to upload a file (see 10th line from bottom) I am given the following error:
An error occured: <HttpError 403 "Insufficient Permission">
I've been looking around for a few hours now and I can't figure out how to get around this. I'm thinking I need to request some sort of token. Not really sure. Again, I'm new to this. Any help would be greatly appreciated!
import httplib2
import os
from apiclient import discovery
import oauth2client
from oauth2client import client
from oauth2client import tools
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Drive API Quickstart'
def get_credentials():
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
the OAuth2 flow is completed to obtain the new credentials.
Returns:
Credentials, the obtained credential.
"""
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'drive-quickstart.json')
store = oauth2client.file.Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatability with Python 2.6
credentials = tools.run(flow, store)
print 'Storing credentials to ' + credential_path
return credentials
from apiclient import errors
from apiclient.http import MediaFileUpload
# ...
def insert_file(service, title, description, parent_id, mime_type, filename):
"""Insert new file.
Args:
service: Drive API service instance.
title: Title of the file to insert, including the extension.
description: Description of the file to insert.
parent_id: Parent folder's ID.
mime_type: MIME type of the file to insert.
filename: Filename of the file to insert.
Returns:
Inserted file metadata if successful, None otherwise.
"""
media_body = MediaFileUpload(filename, mimetype=mime_type, resumable=True)
body = {
'title': title,
'description': description,
'mimeType': mime_type
}
# Set the parent folder.
if parent_id:
body['parents'] = [{'id': parent_id}]
try:
file = service.files().insert(
body=body,
media_body=media_body).execute()
# Uncomment the following line to print the File ID
# print 'File ID: %s' % file['id']
return file
except errors.HttpError, error:
print 'An error occured: %s' % error
return None
def main():
"""Shows basic usage of the Google Drive API.
Creates a Google Drive API service object and outputs the names and IDs
for up to 10 files.
"""
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('drive', 'v2', http=http)
insert_file(service, 'picture.jpg', 'no_description', False, 'image/jpeg', '/Users/ethankay/Documents/Work/Current_Work/Astrophysics/Code/Logger_Program/Master/TestUploadFiles/test3.jpg')
results = service.files().list(maxResults=10).execute()
items = results.get('items', [])
if not items:
print 'No files found.'
else:
print 'Files:'
for item in items:
print '{0} ({1})'.format(item['title'], item['id'])
if __name__ == '__main__':
main()
your Google Drive scope is
SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly'
which has no permission to upload files. You need to change it to
SCOPES = 'https://www.googleapis.com/auth/drive'
to be able to manage files. Try to re-authenticate with your Google API project.
Save this code as quickstart.py
Run it from command line using sudo. [ sudo python quickstart.py ]
Use your Windows Password
The quickstart.py will attempt to open a new window or tab in your default browser. If this fails, copy the URL from the console and manually open it in your browser.
Click the Accept button
DONE

Categories

Resources