Updating python 2 code to python 3 code for googleads api - python-3.x

I'm trying to use the google ads api with python 3 and I'm facing an issue with their generate_refresh_token.py file. The file has been updated for python 3 but I need to debug it as it still has some python 2 code in it. For example, print statements didn't have () in them and there was an instance of using raw_input() instead of input().
Anyway, I'm getting an error message that I can't figure out. Can someone please help me out here?
I've tried googling the solution but I'm a bit lost here.
The code starts from line 110 and ends at line 122:
print ('Access token: %s') % flow.credentials.token
print ('Refresh token: %s') % flow.credentials.refresh_token
if __name__ == '__main__':
args = parser.parse_args()
configured_scopes = [SCOPE]
if not (any([args.client_id, DEFAULT_CLIENT_ID]) and
any([args.client_secret, DEFAULT_CLIENT_SECRET])):
raise AttributeError('No client_id or client_secret specified.')
if args.additional_scopes:
configured_scopes.extend(args.additional_scopes.replace(' ', '').split(','))
main(args.client_id, args.client_secret, configured_scopes)
The code is supposed to throw out an access token that I can use but it's giving me this error:
Access token: %s
Traceback (most recent call last):
File "generate_refresh_token.py", line 122, in <module>
main(args.client_id, args.client_secret, configured_scopes)
File "generate_refresh_token.py", line 110, in main
print ('Access token: %s') % flow.credentials.token
TypeError: unsupported operand type(s) for %: 'NoneType' and 'str'
I believe that this is also a python 2 vs python 3 problem and i would appreciate it if someone could help me out with this!

Update the print statements.
print ('Access token: {}'.format(flow.credentials.token))
print ('Refresh token: {}'.format(flow.credentials.refresh_token))

You have a typo with your parentheses. Print should be:
print('Access token: %s'% flow.credentials.token)
print('Refresh token: %s' % flow.credentials.refresh_token)
To be safe use format:
print('Access token: {}'.format(flow.credentials.token))
print('Refresh token: {}'.format(flow.credentials.refresh_token))

Related

REST API exception handling with a loop and if statements

I wish to use exception handling for a REST API within a loop. The if/else loop works without the exception handling but once I add try/except my loop breaks and only processes the first couple blocks.
The code below is my attempt at this. The if statement is needed for NONE response by the API while the exception handling is for API error responses.
result of successful API and Error API Call
Printed OUTPUT
---------------------------------------------------------------
['#portland,oregon', 'Hamedan,Iran', '#United Arab Emirates', 'Irani, Brasil', 'NewYork', 'Kuwait']
THIS IS THE CURRENT URL: https://geocode.search.hereapi.com/v1/geocode?q=#portland,oregon&apikey=######
Dictionary Results: {'error': 'Unauthorized', 'error_description': 'No credentials found'}
------------------------------------------------------
Error
------------------------------------------------------
KeyError Traceback (most recent call last)
/var/folders/r5/kk4m049n3ts16vn25dwjnjxc0000gn/T/ipykernel_41052/796175789.py in <module>
27 print('Dictionary Results:',results)
28
---> 29 if results['items'] == []:
30 output = ('NULL','NULL','NULL','NULL',addresses[q])
31 #print('NULL OUTPUT:', output), '\n'
KeyError: 'items'
iter_len=len(addresses)
for q in range(iter_len):
geocode_url = "https://geocode.search.hereapi.com/v1/geocode?q{}".format(addresses[q])+ "&apikey=###"
try:
results = requests.get(geocode_url)
print('THIS IS THE CURRENT URL:', geocode_url), '\n'
except requests.exceptions.RequestException as err:
repr(err)
else:
results = results.json()
print('DICTIONARY RESULTS:',results)
if results['items'] == []:
output = ('NULL','NULL','NULL','NULL',addresses[q])
append_list_as_row(output_filename, output)
continue
else:
output = (
results['items'][0]['position']['lat'],
results['items'][0]['position']['lng'],
results['items'][0]['address']['countryCode'],
results['items'][0]['address']['countryName'],
addresses[q]
)
print('GEOCODED LIST:', output), '\n'
append_list_as_row(output_filename, output)
This question was answered by #Nullman. An IF statement to check RESULTS for the variable 'items' followed by 'continue' in the first ELSE block. The snippet is shown below.
try:
results = requests.get(geocode_url)
except requests.exceptions.RequestException, err:
# print('THIS IS THE CURRENT URL:', geocode_url), '\n'
repr(err)
else:
results = results.json()
print ('Dictionary Results:', results)
if 'items' not in results:
continue

Strange issue with Python recursive function in Chalice framework

I have defined this SNS-triggered Lambda in Chalice:
#app.on_sns_message(topic='arn:aws:sns:us-west-1:XXXXXXXX:MyTopic')
def step1_photo_url_preload(event, retry = 3):
try:
js = json.loads(event.message)
... some logic here, event object is never modified ...
except:
if retry:
print("WARNING: failed, %d retries remaining" % retry)
return step1_photo_url_preload(event, retry-1)
else:
raise
When an exception is raised, the function should retry up to 3 times.
Instead, what I get is the exception below. Look closely at the trace: Line 56 shows the error occurs when attempting the recursive call:
[ERROR] TypeError: 'SNSEvent' object is not subscriptable
Traceback (most recent call last):
File "/var/task/chalice/app.py", line 1459, in __call__
return self.func(event_obj)
File "/var/task/app.py", line 56, in step1_photo_url_preload
return step1_photo_url_preload(event, retry-1)
File "/var/task/chalice/app.py", line 1458, in __call__
event_obj = self.event_class(event, context)
File "/var/task/chalice/app.py", line 1486, in __init__
self._extract_attributes(event_dict)
File "/var/task/chalice/app.py", line 1532, in _extract_attributes
first_record = event_dict['Records'][0]
Mysteriously, the function can't work with the event object that it received the first time.
What could cause this?
I suspect this might have something to do with the magic behind #app.on_sns_message, but I'm not sure where to look next.
The problem is the fact that the function is decorated, the failure is in the code the decorator is running. Pull the functionality you want to run recursively into a separate function and the problem should go away.

Unable to delete Snapshot using boto3 using python3

I using boto3 on the python3 for delete the snapshop, Getting below error while trying to remove it (This syntax was work in the python2+boto only):
Tracebak (most recent call last):
File "./snapshotcleanup.py"m line 158, in <module>
s.delete()
AttributeError: 'dict' object has no attribute 'delete'
Code :
connection = myinternalclient (User, pass)
// Custom function for connection, you may consider ec2 = boto3.client('ec2')
res = connection.describe_snapshots(OwnersIds=[XX], Filters=[{'Name' : 'tag:Name', 'Value' : ["nonimp*"]'}])
for s in res['Snapshots']:
for tag in s['Tags']:
if 'nonprod' in tag.value():
s.delete()
print("[Deleted Snapshot]: %s" % s['SnapshotId'])
Is this syntax not in the boto3 ?
To delete the snapshot, you can use delete_snapshot method.
For example:
ec2 = boto3.client('ec2')
for s in res['Snapshots']:
for tag in s['Tags']:
if tag['Value'] == 'nonprod':
ec2.delete_snapshot(SnapshotId=s['SnapshotId'])
print("[Deleted Snapshot]: %s" % s['SnapshotId'])
Please double check the code as mistakes are possible, as one can delete wrong snapshots by accident.
The above assumes that the tags have the form (Key is not checked in the code above):
{
'Key': 'env',
'Value': 'nonprod'
}

python 3 EOFError: EOF when reading a line

The errors saying
Traceback (most recent call last):
File "rental_car-customer-data-2.py", line 18, in
odoEnd = int(input("Ending Odometer Reading:"))
EOFError: EOF when reading a line
I have tried removing int and copy paste same line from above that doesn't error odoStart and change it to odoEnd but not working??
not sure if the odoEnd - odoStart will work either?
odoStart = int(input ("Starting Odometer Reading:"))
odoEnd = int(input("Ending Odometer Reading:"))****
print(odoStart)
print(odoEnd)
totalMiles = (odoEnd - odoStart)
print (totalMiles)
This is a common error when reading a file. When you get to the end of a file when reading in python you have to go back to line one by using this command: file.seek(0), where file is the name of the file variable.

python logging.critical() to raise exception and dump stacktrace and die

I'm porting some code from perl (log4perl) and java (slf4j). All is fine except for logging.critical() does not dump stacktrace and die like it does in the other frameworks, need to add a lot of extra code, logger.exception() also only writes error.
Today I do:
try:
errmsg = "--id={} not found on --host={}".format(args.siteid, args.host)
raise GX8Exception(errmsg)
except GX8Exception as e:
log.exception(e)
sys.exit(-1)
This produces:
2018-01-10 10:09:56,814 [ERROR ] root --id=7A4A7845-7559-4F89-B678-8ADFECF5F7C3 not found on --host=welfare-qa
Traceback (most recent call last):
File "./gx8-controller.py", line 85, in <module>
raise GX8Exception(errmsg)
GX8Exception: --id=7A4A7845-7559-4F89-B678-8ADFECF5F7C3 not found on --host=welfare-qa
Is there a way to config pythonmodule logger to do this, or any other framework to do the same:
log.critical("--id={} not found on --host={}".format(args.siteid, args.host))
One approach would be to create a custom Handler that does nothing but pass log messages on to its super and then exit if the log level is high enough:
import logging
class ExitOnExceptionHandler(logging.StreamHandler):
def emit(self, record):
super().emit(record)
if record.levelno in (logging.ERROR, logging.CRITICAL):
raise SystemExit(-1)
logging.basicConfig(handlers=[ExitOnExceptionHandler()], level=logging.DEBUG)
logger = logging.getLogger('MYTHING')
def causeAProblem():
try:
raise ValueError("Oh no!")
except Exception as e:
logger.exception(e)
logger.warning('Going to try something risky...')
causeAProblem()
print("This won't get printed")
Output:
rat#pandion:~$ python test.py
ERROR:root:Oh no!
Traceback (most recent call last):
File "test.py", line 14, in causeAProblem
raise ValueError("Oh no!")
ValueError: Oh no!
rat#pandion:~$ echo $?
255
However, this could cause unexpected behavior for users of your code. It would be much more straightfoward, if you want to log an exception and exit, to simply leave the exception uncaught. If you want to log a traceback and exit wherever the code is currently calling logging.critical, change it to raise an exception instead.
I inherited some code where I could not change the handler class. I resorted to run time patching of the handler which is a variation on the solution by #nathan-vērzemnieks:
import types
def patch_logging_handler(logger):
def custom_emit(self, record):
self.orig_emit(record)
if record.levelno == logging.FATAL:
raise SystemExit(-1)
handler = logger.handlers[0]
setattr(handler, 'orig_emit', handler.emit)
setattr(handler, 'emit', types.MethodType(custom_emit, handler))
Nathans anwser is great! Been looking for this for a long time,
will just add that you can also do:
if record.levelno >= logging.ERROR:
instead of
if record.levelno in (logging.ERROR, logging.CRITICAL):
to set the minimum level that would cause an exit.

Resources