Python: Continue looping after exception - python

I have the following script (below). which will return the status code of URLs. It loops through a file and tries to connect to each host. Only problem is that it obviously stops looping when it reaches an exception.
I have tried numerous things to put the how of it in a loop, but to no avail. Any thoughts?
import urllib
import sys
import time
hostsFile = "webHosts.txt"
try:
f = file(hostsFile)
while True:
line = f.readline().strip()
epoch = time.time()
epoch = str(epoch)
if len(line) == 0:
break
conn = urllib.urlopen(line)
print epoch + ": Connection successful, status code for " + line + " is " + str(conn.code) + "\n"
except IOError:
epoch = time.time()
epoch = str(epoch)
print epoch + ": Connection unsuccessful, unable to connect to server, potential routing issues\n"
sys.exit()
else:
f.close()
EDIT:
I've come up with this in the mean-time, any issues with this? (i'm still learning :p )...
f = file(hostsFile)
while True:
line = f.readline().strip()
epoch = time.time()
epoch = str(epoch)
if len(line) == 0:
break
try:
conn = urllib.urlopen(line)
print epoch + ": Connection successful, status code for " + line + " is " + str(conn.code) + "\n"
except IOError:
print epoch + "connection unsuccessful"
Thanks,
MHibbin

You could handle the exception where it is raised. Also, use a context manager when opening files, it makes for simpler code.
with open(hostsFile, 'r') as f:
for line in f:
line = line.strip()
if not line:
continue
epoch = str(time.time())
try:
conn = urllib.urlopen(line)
print epoch + ": Connection successful, status code for " + line + " is " + str(conn.code) + "\n"
except IOError:
print epoch + ": Connection unsuccessful, unable to connect to server, potential routing issues\n"

You need to handle exception raised by urllib.urlopen(line), something like this.
try:
f = file(hostsFile)
while True:
line = f.readline().strip()
epoch = time.time()
epoch = str(epoch)
if len(line) == 0:
break
try:
conn = urllib.urlopen(line)
except IOError:
print "Exception occured"
pass
except IOError:
epoch = time.time()
epoch = str(epoch)
print epoch + ": Connection unsuccessful, unable to connect to server, potential routing issues\n"
sys.exit()
else:
f.close()

You could try catching the exception inside the while loop as something like this.
try:
f = file(hostsFile)
while True:
line = f.readline().strip()
epoch = time.time()
epoch = str(epoch)
if len(line) == 0:
break
try:
conn = urllib.urlopen(line)
print epoch + ": Connection successful, status code for " + line + " is " + str(conn.code) + "\n"
except:
epoch = time.time()
epoch = str(epoch)
print epoch + ": Connection unsuccessful, unable to connect to server, potential routing issues\n"
except IOError:
pass
else:
f.close()

Related

TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'str'

I am trying to build a network monitor using python that continually monitors internet connectivity by sending ping requests to an external resource. It also keeps logs of when the internet is down and the duration of the downtime. While running this python program, I am getting the error.
import socket
import time
import datetime
import os
import sys
LOG_FNAME = "network.log"
FILE = os.path.join(os.getcwd(), LOG_FNAME)
def send_ping_request(host="1.1.1.1", port=53, timeout=3):
try:
socket.setdefaulttimeout(timeout)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
except OSError as error:
return False
else:
s.close()
return True
def write_permission_check():
try:
with open(FILE, "a") as file:
pass
except OSError as error:
print("Log file creation failed")
sys.exit()
finally:
pass
def calculate_time(start, stop):
time_difference = stop - start
seconds = float(str(time_difference.total_seconds()))
return str(datetime.timedelta(seconds=seconds)).split(".")[0]
def mon_net_connection(ping_freq=2):
monitor_start_time = datetime.datetime.now()
def motd():
motd = "Network connection monitoring started at: " +
str(monitor_start_time).split(".")[0] + " Sending ping request in " + str(ping_freq) + " seconds"
print(motd)
with open(FILE, "a") as file:
file.write("\n")
file.write("motd" + "\n")
while True:
if send_ping_request():
time.sleep(1)
else:
down_time = datetime.datetime.now()
fail_msg = "Network Connection Unavailable at: " +str(down_time).split(".")[0]
print(fail_msg)
with open(FILE, "a") as file:
file.write(fail_msg + "\n")
i = 0
while not send_ping_request():
time.sleep(1)
i += 1
if i >= 3600:
i = 0
now = datetime.datetime.now()
continous_message = "Network Unavailabilty Persistent at: " +str(now).split(".")[0]
print(continous_message)
with open(FILE, "a") as file:
file.write(continous_message + "\n")
up_time = datetime.datetime.now()
uptime_message = "Network Connectivity Restored at: " +str(up_time).split(".")[0]
down_time = calculate_time(down_time, up_time)
_m = "Network Connection was Unavailable for " + down_time
print(uptime_message)
print(_m)
with open(FILE, "a") as file:
file.write(uptime_message + "\n")
file.write(_m + "\n")
mon_net_connection()
The error I am getting is as below.
Traceback (most recent call last):
File "C:\Users\samsung\AppData\Local\Programs\Python\Python39\checknetwork1.py", line
64, in <module>
down_time = calculate_time(down_time, up_time)
File "C:\Users\samsung\AppData\Local\Programs\Python\Python39\checknetwork1.py", line 29, in calculate_time
time_difference = stop - start
TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'str'
Please help in resolving this error. I am unable to figure out where is the error, and how to correct it.
The down_time variable is initially set to type datetime.datetime as is the up_time variable. The problem is in your while loop, the first call to calculate_time() returns a str which gets assigned to down_time, so the next time you call it in the loop, the type will not work.
I'm not entirely sure what the loop is trying to accomplish but if you want to maintain this pattern, you need calculate_time to return a datetime.datetime object and explicitly cast it to str when you need to print or log it.

Why is python looping creating double results?

I have 3 lat/lngs and a URL that I am constructing. My output should be 3 URLs, for each lat/lng, I am receiving 6. What do I need to change in my code below to print 3 URLs instead of 6? The try block and first for loops start are error handling, if the script fails, try twice. I am getting 6 values even when the script does not fail.
def main():
for i in range(2):
for attempts in range (1):
try:
for lat, lon, id_, startDate, endDate in zip(latval, lonval, idVal, startDayValStr, endDayValStr):
time_param = '?start='+ startDate +'T'+ "01:00" + 'Z' + '&end='+ endDate + 'T' + "23:00" + 'Z'
hrPrecip = 'https://insight.api.wdtinc.com/hourly-precipitation/' + str(lat)+'/' + str(lon) + time_param + '&unit=inches'
print hrPrecip
except Exception as e:
attempts = i + 1
sleep(30)
print "now trying attempt #" + " " + str(attempts) + " " + "for error" " " + str(e)
print(traceback.format_exc())
logging.exception(e)
msg = "PYTHON ERRORS:\nTraceback info:\n" + traceback.format_exc()
logging.debug("sending error email")
emailserver.email_error_msg(msg)
if __name__ == "__main__":
main()
Output:
https://insight.api.wdtinc.com/hourly-precipitation/44.797207/-95.175648?start=2019-05-13T01:00Z&end=2019-05-13T23:00Z&unit=inches
https://insight.api.wdtinc.com/hourly-precipitation/44.796302/-95.180946?start=2019-05-13T01:00Z&end=2019-05-13T23:00Z&unit=inches
https://insight.api.wdtinc.com/hourly-precipitation/44.778728/-95.23022?start=2019-05-13T01:00Z&end=2019-05-13T23:00Z&unit=inches
https://insight.api.wdtinc.com/hourly-precipitation/44.797207/-95.175648?start=2019-05-13T01:00Z&end=2019-05-13T23:00Z&unit=inches
https://insight.api.wdtinc.com/hourly-precipitation/44.796302/-95.180946?start=2019-05-13T01:00Z&end=2019-05-13T23:00Z&unit=inches
https://insight.api.wdtinc.com/hourly-precipitation/44.778728/-95.23022?start=2019-05-13T01:00Z&end=2019-05-13T23:00Z&unit=inches`
It could be the try: and except: block. failing in the first. I am guessing you do not need the second loop with attempt in range(1). In fact you do not need any loop here.

Python just let main thread sleep

I use time.sleep() in my main thread and want just this thread to sleep. The problem is, that all the other threads I created in the main are sleeping too. One problem might be that they have to access a global variable.
The aim is just to not create too many threads at one time - so I count the running threads and if they are > 200 I want to let the main thread sleep to give the other threads more time.
import requests
import ipaddress
import sys
import threading
import time
loginIndicators = ["username", "user name", "password", "passwort", "log in", "sign in", "anmelden", "signin", "login", "submit", "account", "user", "pass", "id", "authentification", "authentication", "auth", "authorization", "access", "passphrase", "key"]
scancounter = 0
def scan(ip, port, protocol):
global scancounter
global file
try:
res = requests.get(protocol + "://" + ip.exploded + ":" + port + "/", timeout=1)
except:
return
finally:
scancounter += 1
if res.status_code == 401 or any(indicator in res.text.lower() for indicator in loginIndicators):
print("Found: " + ip.exploded + ":" + port + " --> " + protocol)
file.write(protocol + "://" + ip.exploded + ":" + port + "\n")
def output_status(end):
global scancounter
if(end):
time.sleep(3)
print("Scanned: " + str(int(scancounter / len(ports) / 2)))
try:
if __name__ == "__main__":
try:
nw = ipaddress.ip_network(input("Enter the starting IP address: "))
except:
print("Invalid format - expected: IP/prefix")
sys.exit()
ports = input("Enter the ports that should be tested: ")
if ports == "":
ports = ["80","8080","443"]
else:
ports = ports.replace(" ", "")
ports = ports.split(",")
file = input("Output file path: ")
if file != "":
file = open(file, "a")
iprange = nw.hosts()
try:
skip = input("How many addresses do you want to skip: ")
if skip == "":
skip = 0
for i in range(0, int(skip)):
next(iprange)
except:
print("You can't skip more addresses than the IP range contains!")
for ip in iprange:
for port in ports:
threading.Thread(target=scan, args=(ip, port, "http",)).start()
threading.Thread(target=scan, args=(ip, port, "https",)).start()
threading.Thread(target=output_status, args=(True,)).start()
except KeyboardInterrupt:
threading.Thread(target=output_status, args=(True,)).start()
Why aren't you calling output_status in the main thread rather than starting a thread for it?
threading.Thread(target=output_status, args=(True,)).start()
If you did that the sleep would occur on the main thread.
output_status(True)

Urllib giving fake proxy

I test my proxies with this script and it gives many working but when i test the "working" proxies with an other proxy checker only a very little amount works.
Here is the part that's checking if the proxy works:
def process(self, task):
global alive
global dead
global tested
proxy = task
log_msg = str("Trying HTTP proxy%21s " % proxy)
cj = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(
urllib.request.HTTPCookieProcessor(cj),
urllib.request.HTTPRedirectHandler(),
urllib.request.ProxyHandler({'http': proxy})
)
try:
t1 = time.time()
response = opener.open(test_url, timeout=timeout_value).read()
tested += 1
t2 = time.time()
except Exception as e:
log_msg += "%s " % fail_msg
print(Fore.LIGHTRED_EX + log_msg)
dead += 1
tested += 1
return None
log_msg += ok_msg + "Response time: %d" % (int((t2-t1)*1000))
print(Fore.LIGHTGREEN_EX + log_msg)
text_file = open(out_filename, "a")
text_file.write(proxy + "\r\n")
text_file.close()
alive += 1

Correct way to handle exception on Python2.6

I had an Python script that running continuously. If there any new file on directory then the python will open url using urllib2 to do some request on specific ip.
here are the code
encoded_string = base64.b64encode(image_file.read())
values = dumps({
'image_data':encoded_string,
'requestCode':'111'
})
headers = {"Content-Type": "application/json"}
request = Request("http:/xx.xxx.xx.xxx/api/carplate_service",data=values, headers=headers)
response = urlopen(request, timeout=60)
The code are working well but on random time, let say usually happened on 1-2 AM then I got this error:
<class 'urllib2.URLError'> - <urlopen error [Errno 110] Connection timed out>
I had an exception on that function on this bellow :
try:
ip = sys.argv[1]
histId = int(sys.argv[2])
handler = ModHandler()
wm = pyinotify.WatchManager()
notifier = pyinotify.Notifier(wm, handler)
wdd = wm.add_watch('./' + ip + '/', pyinotify.IN_CLOSE_WRITE)
notifier.loop()
except BaseException as e:
with open("error.log", "a") as text_file:
exc_type, exc_obj, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
text_file.write( time.strftime("%Y-%m-%d %H:%M:%S") + " [" + str(exc_tb.tb_lineno) + " - " + fname + "] : " + str(exc_type) + " - " + str(e) + "\n")
text_file.close();
The exception not working well because application cannot continue if there are some error like above.
My question are how to make program still continue even the exception throw?
I'm using python2.6
Thanks
For function calls that go out to external services I usually find that the following basic structure works pretty well
import time
expire_time = 2
while True:
start_time = time.time()
try:
# Do something here
# ....
# If you make it to the bottom of the code, break out of the loop
break
except BaseException as e:
# Compare the start_time with the current time
now_time = time.time()
if now_time > start_time + expire_time:
raise e
# Otherwise try executing the `try` block again
Using the code that you've provided it could look something like this
import time
expire_time = 2
while True:
start_time = time.time()
try:
ip = sys.argv[1]
histId = int(sys.argv[2])
handler = ModHandler()
wm = pyinotify.WatchManager()
notifier = pyinotify.Notifier(wm, handler)
wdd = wm.add_watch('./' + ip + '/', pyinotify.IN_CLOSE_WRITE)
notifier.loop()
break
except BaseException as e:
now_time = time.time()
if now_time > start_time + expire_time:
raise e
else:
with open("error.log", "a") as text_file:
exc_type, exc_obj, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
text_file.write( time.strftime("%Y-%m-%d %H:%M:%S") + " [" + str(exc_tb.tb_lineno) + " - " + fname + "] : " + str(exc_type) + " - " + str(e) + "\n")
text_file.close();

Categories

Resources