google spreadsheet CellNotFound Exception using python issue - google-apps-script

I am building Discord bot which ask user for their name and Points. My spreadsheet has two columns with first raw as header (Name, Points). my code take the name of the player and search the spreadsheet if found update the point. This works perfect when the player name already found but i get cellnotfound error when the name is not in the google sheet.
i have already tried solution in other forum but non are working like
if len(cells) > 0 and except gspread.exceptions.CellNotFound: and except gspread.CellNotFound:
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from pprint import pprint
from googleapiclient import discovery
# SET UP GSHEETS DESTINATION
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"]
creds = ServiceAccountCredentials.from_json_keyfile_name("generated.json", scope)
client1 = gspread.authorize(creds)
content = "22"
if content.isdigit():
#open spreadsheet
sh = client1.open("test")
worksheet = sh.sheet1
nameof= 'player4'
#find data with playername
cells = worksheet.find(nameof)
if cells != []:
#capture player name data column and row number
#print("found at R%s C%s" %(cells.row, cells.col))
name_row_number = ("%s"%(cells.row))
name_cell_number = ("%s"%(cells.col))
old_points_cell_number = int(name_cell_number)+1
#print(old_points_cell_number)
oldscore = worksheet.cell(name_row_number, old_points_cell_number).value
#print(oldscore)
worksheet.update_cell(name_row_number, old_points_cell_number, content)
else:
print("name not found")
[Screenshot of my google sheet][1]
[1]: https://i.stack.imgur.com/iw6O5.png
Below is the error message i get
Traceback (most recent call last):
File "C:\Python39\lib\site-packages\gspread\models.py", line 1799, in find
return self._finder(finditem, query, in_row, in_column)
File "C:\Python39\lib\site-packages\gspread\models.py", line 1761, in _finder
return func(match, cells)
File "C:\Python39\lib\site-packages\gspread\utils.py", line 97, in finditem
return next((item for item in seq if func(item)))
StopIteration
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\abc\Desktop\Discord_Python\ReadExcel.py", line 38, in <module>
cells = worksheet.find(nameof)
File "C:\Python39\lib\site-packages\gspread\models.py", line 1801, in find
raise CellNotFound(query)
gspread.exceptions.CellNotFound: player4

Related

Iterating through describe_instances() to print key & value boto3

I am currently working on a python script to print pieces of information on running EC2 instances on AWS using Boto3. I am trying to print the InstanceID, InstanceType, and PublicIp. I looked through Boto3's documentation and example scripts so this is what I am using:
import boto3
ec2client = boto3.client('ec2')
response = ec2client.describe_instances()
for reservation in response["Reservations"]:
for instance in reservation["Instances"]:
instance_id = instance["InstanceId"]
instance_type = instance["InstanceType"]
instance_ip = instance["NetworkInterfaces"][0]["Association"]
print(instance)
print(instance_id)
print(instance_type)
print(instance_ip)
When I run this, "instance" prints one large block of json code, my instanceID, and type. But I am getting an error since adding NetworkInterfaces.
instance_ip = instance["NetworkInterfaces"][0]["Association"]
returns:
Traceback (most recent call last):
File "/Users/me/AWS/describeInstances.py", line 12, in <module>
instance_ip = instance["NetworkInterfaces"][0]["Association"]
KeyError: 'Association'
What am I doing wrong while trying to print the PublicIp?
Here is the structure of NetworkInterfaces for reference:
The full Response Syntax for reference can be found here (https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.describe_instances)
Association man not always may be present. Also an instance may have more then one interface. So your working loop could be:
for reservation in response["Reservations"]:
for instance in reservation["Instances"]:
instance_id = instance["InstanceId"]
instance_type = instance["InstanceType"]
#print(instance)
print(instance_id, instance_type)
for network_interface in instance["NetworkInterfaces"]:
instance_ip = network_interface.get("Association", "no-association")
print(' -', instance_ip)

How to get the actual value of a cell with openpyxl?

I'm a beginner with Python and I need help. I'm using Python 2.7 and I'm trying to retrieve the cell values of an excel file and store it into a csv file. My code is the following:
import os, openpyxl, csv
aggname = "deu"
wb_source = openpyxl.load_workbook(filename, data_only = True)
app_file = open(filename,'a')
dest_file = csv.writer(app_file, delimiter=',', lineterminator='\n')
calib_sheet = wb_source.get_sheet_by_name('Calibration')
data = calib_sheet['B78:C88']
data = list(data)
print(data)
for i in range(len(data)):
dest_file.writerow(data[i])
app_file.close()
In my csv file, I get this, instead of the actual value (for example in my case: SFCG, 99103).
<Cell Calibration.B78>,<Cell Calibration.C78>
<Cell Calibration.B79>,<Cell Calibration.C79>
<Cell Calibration.B80>,<Cell Calibration.C80>
<Cell Calibration.B81>,<Cell Calibration.C81>
<Cell Calibration.B82>,<Cell Calibration.C82>
<Cell Calibration.B83>,<Cell Calibration.C83>
<Cell Calibration.B84>,<Cell Calibration.C84>
<Cell Calibration.B85>,<Cell Calibration.C85>
<Cell Calibration.B86>,<Cell Calibration.C86>
<Cell Calibration.B87>,<Cell Calibration.C87>
<Cell Calibration.B88>,<Cell Calibration.C88>
I tried to set the data_only = True, when opening the excel file as suggested in answers to similar questions but it doesn't solve my problem.
---------------EDIT-------------
Taking into account the first two answers I got (thank you!), I tried several things:
for i in range(len(data)):
dest_file.writerows(data[i].value)
I get this error message :
for i in range(len(data)):
dest_file.writerows(data[i].values)
Traceback (most recent call last):
File "<ipython-input-78-27828c989b39>", line 2, in <module>
dest_file.writerows(data[i].values)
AttributeError: 'tuple' object has no attribute 'values'
Then I tried this instead:
for i in range(len(data)):
for j in range(2):
dest_file.writerow(data[i][j].value)
and then I have the following error message:
for i in range(len(data)):
for j in range(2):
dest_file.writerow(data[i][j].value)
Traceback (most recent call last):
File "<ipython-input-80-c571abd7c3ec>", line 3, in <module>
dest_file.writerow(data[i][j].value)
Error: sequence expected
So then, I tried this:
import os, openpyxl, csv
wb_source = openpyxl.load_workbook(filename, data_only=True)
app_file = open(filename,'a')
dest_file = csv.writer(app_file, delimiter=',', lineterminator='\n')
calib_sheet = wb_source.get_sheet_by_name('Calibration')
list(calib_sheet.iter_rows('B78:C88'))
for row in calib_sheet.iter_rows('B78:C88'):
for cell in row:
dest_file.writerow(cell.value)
Only to get this error message:
Traceback (most recent call last):
File "<ipython-input-81-5bed62b45985>", line 12, in <module>
dest_file.writerow(cell.value)
Error: sequence expected
For the "sequence expected" error I suppose python expects a list rather than a single cell, so I did this:
import os, openpyxl, csv
wb_source = openpyxl.load_workbook(filename, data_only=True)
app_file = open(filename,'a')
dest_file = csv.writer(app_file, delimiter=',', lineterminator='\n')
calib_sheet = wb_source.get_sheet_by_name('Calibration')
list(calib_sheet.iter_rows('B78:C88'))
for row in calib_sheet.iter_rows('B78:C88'):
dest_file.writerow(row)
There is no error message but I only get the reference of the cell in csv file and changing it to dest_file.writerow(row.value) brings me back to the tuple error.
I obviously still need your help!
You've forgot to get the cell's value! See the documentation
I found a way around it using numpy, which allows me to store my values as a list of lists rather than a list of tuples.
import os, openpyxl, csv
import numpy as np
wb_source = openpyxl.load_workbook(filename, data_only=True)
app_file = open(filename,'a')
dest_file = csv.writer(app_file, delimiter=',', lineterminator='\n')
calib_sheet = wb_source.get_sheet_by_name('Calibration')
store = list(calib_sheet.iter_rows('B78:C88'))
print store
truc = np.array(store)
print truc
for i in range(11):
for j in range(1):
dest_file.writerow([truc[i][j].value, truc[i][j+1].value])
app_file.close()
I actually have a sequence as my argument in "writerow()" and with the list object I can also use the double index and the value method to retrieve the value of my cell.
Try using data.values instead of just data when you are printing it.
Hope it helps !!
**
***An example :
import openpyxl
import re
import os
wc=openpyxl.load_workbook('<path of the file>') wcsheet=wc.get_sheet_by_name('test')
store=[]
for data in wcsheet.columns[0]:
store=data
print(store.value)***
=======================
=================================================
**
Live Life Buddha Size

How to pass urls from CSV list into a python GET request

I have a CSV file, which contains a list of Google extension IDs.
I'm writing a code that will read the extension IDs, add the webstore url, then perform a basic get request:
import csv
import requests
with open('small.csv', 'rb') as f:
reader = csv.reader(f)
for row in reader:
urls = "https://chrome.google.com/webstore/detail/" + row[0]
print urls
r = requests.get([urls])
Running this code results in the following Traceback:
Traceback (most recent call last):
File "C:\Users\tom\Dropbox\Python\panya\test.py", line 9, in <module>
r = requests.get([urls])
File "C:\Python27\lib\site-packages\requests\api.py", line 69, in get
return request('get', url, params=params, **kwargs)
File "C:\Python27\lib\site-packages\requests\api.py", line 50, in request
response = session.request(method=method, url=url, **kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 465, in request
resp = self.send(prep, **send_kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 567, in send
adapter = self.get_adapter(url=request.url)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 641, in get_adapter
raise InvalidSchema("No connection adapters were found for '%s'" % url)
InvalidSchema: No connection adapters were found for '['https://chrome.google.com/webstore/detail/blpcfgokakmgnkcojhhkbfbldkacnbeo']'
How can revise the code, so that it would accept the urls in the list, and make the GET request?
requests.get expects a string, but you're creating and passing a list [urls]
r = requests.get([urls])
Change it to just
r = requests.get(urls)
and it should work.

Read csv files and calculate the total sum

import glob
import csv
def read_with_csv(filename):
data = []
for x in csv.reader(open(filename, 'r')):
data.append(x)
return data
def calculate_sum(data_sample):
total = 0
for row in data_sample[1:]:
price = float(row[9])
total += price
return total
files = [file for file in glob.glob("*.csv") if 'Invoice-Item-Adjustment_' in file]
data_from_csv = read_with_csv(files)
the_sum = data_from_csv(calculate_sum)
print(the_sum)
I have multiple files in directory and read to list and loop through the amount in the column and telly up the monthly total sum. I have erros and not sure how to deal with.
Traceback (most recent call last):
File "listing.py", line 18, in <module>
data_from_csv = read_with_csv(files)
File "listing.py", line 6, in read_with_csv
for x in csv.reader(open(filename, 'r')):
TypeError: invalid file: ['JEExport_20141201-20141218_Invoice-Item-Adjustment_20
150208164027.csv', 'JEExport_20150116-20150128_Invoice-Item-Adjustment_201502021
70516.csv'
]
List comprehensions in python would return a collection - not the file itself.
Hence
files = [file for file in glob.glob("*.csv") if 'Invoice-Item-Adjustment_' in file]
returns a list of files whose names contain Invoice-Item-Adjustment. You would have to iterate through the files one by one and then process it.
Your function read_with_csv() takes a filename as an argument NOT a list of files. So instead, the following might work depending on what you want to do exactly
data_from_csv = [read_with_csv(file) for file in files]

500 error when trying to list files from Drive with query parameter

I'm trying to pull list of files from Google Drive using Python Api.
Whenever I try to add parameter q to the files().list() I get error 500. Is there something I can do about it? When I don't add the q parameter I do see a lot of files in the response.
Initially I tried with scope https://www.googleapis.com/auth/drive, but different thread on SO suggested limit it to https://www.googleapis.com/auth/drive.readonly.metadata. Unfortunately this diddn't help.
I'm getting following error:
Traceback (most recent call last):
File "weekly_reporting.py", line 52, in <module>
main()
File "weekly_reporting.py", line 47, in main
connectToGoogleDrive()
File "weekly_reporting.py", line 38, in connectToGoogleDrive
file = drive_service.files().list(q="Google").execute()
File "/usr/local/lib/python2.7/dist-packages/oauth2client-1.4.5-py2.7.egg/oauth2client/util.py", line 135, in positional_wrapper
File "/usr/local/lib/python2.7/dist-packages/google_api_python_client-1.3.1-py2.7.egg/googleapiclient/http.py", line 723, in execute
googleapiclient.errors.HttpError: <HttpError 500 when requesting https://www.googleapis.com/drive/v2/files?q=Google&alt=json returned "">
Below is my python request for the record
flow = OAuth2WebServerFlow(CLIENT_ID, CLIENT_SECRET, OAUTH_SCOPE,redirect_uri=REDIRECT_URI)
authorize_url = flow.step1_get_authorize_url()
print 'Go to the following link in your browser: ' + authorize_url
code = raw_input('Enter verification code: ').strip()
credentials = flow.step2_exchange(code)
# Create an httplib2.Http object and authorize it with our credentials
http = httplib2.Http()
http = credentials.authorize(http)
drive_service = build('drive', 'v2', http=http)
file = drive_service.files().list(q="Google").execute()
pprint.pprint(file)
Your search query doesn't look valid. See https://developers.google.com/drive/web/search-parameters for valid examples.