REST API exception handling with a loop and if statements - python-3.x

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

Related

Last line of STDOUT is not getting printed if there's an STDIN after it

While trying to integrate sqlmap with my automation tool, when tried to run the command and save the output into a file, the line after which user's input is required is not getting printed on the console; It is getting printed after the arguments are passed. It is required that the console output to be printed on both the places (terminal and output file). As sqlmap requires the user's input during execution cannot use subprocess.check_output()
image
Code snippet:
[try:
cmd = cmd.rstrip()
process = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
while True:
out = process.stdout.readline()\[0:\]
if out == '' and process.poll() is not None:
break
if out:
output += out
print(out.strip())
except Exception as e:
exception_message = str(e)
output += exception_message
if 'exit status 1' not in exception_message:
self.utilities.print_color("\[!\] Error executing the command: " + cmd,'red')
output += '\r\n'
print(output)
return output][1]

How to mention from string on discord.py?

i'm setting up a dicord bot i have usernames on a database so i get the user name ftrom a method that connects to database and return username in a string what i want is to mention from that string i can't get ir to work
i've tried searching on documentaton but i didnt understood it at all
async def job(channelid,message):
print('init schedule')
channel = client.get_channel(channelid)
current_apps=current_app()
usersapps=apps_user(current_apps["APPS"])
counter=0
while True:
counter= counter + 1
for i in range(0,len(usersapps)):
await discord.client.send_message("{}".format(usersapps[i]['USER']),mentions=True)
await asyncio.sleep(60) # task runs every 60 seconds
i excpect my code to mention the given user by the string that comes from my method
the error i'm getting
init schedule
Task exception was never retrieved
future: <Task finished coro=<job() done, defined at c:\Users\Nte\Desktop\rainbow army\bot.py:136> exception=TypeError("send() got an unexpected keyword argument 'mentions'",)>
Traceback (most recent call last):
File "c:\Users\Nte\Desktop\rainbow army\bot.py", line 145, in job
await discord.client.send_message("{}".format(usersapps[i]['USER']),mentions=True)
TypeError: send() got an unexpected keyword argument 'mentions'
i was able to mention a user by saving userid into database and then get it with my method and sending message like this
await channel.send("<#!{}>".format(usersapps[i]['USERID']))

Updating python 2 code to python 3 code for googleads api

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))

How do I capture all error & display an error message

In my python code, I would like to catch all the errors & display an error message. For example, I would like to do this thing
try:
'my code block
catch:
print("Error:x error occurred" )
Can you suggest me how to do this?
If you're interested in the exception type, then you can catch all exceptions using except Exception as ex (ex can be anything), and then get the exception type using type(ex).__name__:
try:
# example, dividing by zero
x = 1 / 0
except Exception as ex:
print("Error: {} error occurred".format(type(ex).__name__))
Output:
Error: ZeroDivisionError error occurred
If the type doesn't matter, then this will do:
try:
# some code
except:
print("Error:an error occurred") # any error, but you don't know which

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