Real Time internet connection checker in python With GUI - python-3.x

so basically what i am trying to do is to check if the computer have access to internet till the end of the program....
It is in a GUI which is made with tkinter.....I tried to create new thread and run the function in a while loop(while 1:), but it says
Traceback (most recent call last):
.
.
.
RuntimeError: main thread is not in main loop
this is the program
import threading
import socket
import time
def is_connected():
try:
socket.create_connection(("www.google.com", 80))
print("Online",end="\n")
except OSError:
print("offline",end="\n")
tt3 =threading.Event()
while 1:
t3=threading.Thread(target=is_connected)
t3.start()
time.sleep(1)
This is the program with GUI
import threading
import socket
import time
import tkinter
top = tkinter.Tk()
top.title("")
l=tkinter.Label(top,text='')
l.pack()
def is_connected():
try:
socket.create_connection(("www.google.com", 80))
print("Online",end="\n")
l.config(text="Online")
except OSError:
l.config(text="offline")
print("offline",end="\n")
tt3 =threading.Event()
while 1:
t3=threading.Thread(target=is_connected)
t3.start()
time.sleep(1)
top.configure(background="#006666")
top.update()
top.mainloop()
any suggestion or help is most welcomed!!
(someone in reddit suggested me to use queue about which i have no idea )

First the while loop will block the tkinter mainloop from processing events. Second you are repeatedly creating new thread in each loop.
Better use .after():
import socket
import tkinter
top = tkinter.Tk()
top.title("Network Checker")
top.configure(background="#006666")
l=tkinter.Label(top,text='Checking ...')
l.pack()
def is_connected():
try:
socket.create_connection(("www.google.com", 80)) # better to set timeout as well
state = "Online"
except OSError:
state = "Offline"
l.config(text=state)
print(state)
top.after(1000, is_connected) # do checking again one second later
is_connected() # start the checking
top.mainloop()

Related

Tkinter AssertionError: Python3 Web App using selenium won't input search term in driver.title

I have been learning python for the past 10 months; I am also new to StackOverflow so hope you will forgive any errors in communicating here. My simple web application uses Selenium to automatically go to a specific website and enters a search term in the driver.title input box. Now all works but I get an AssertionError. I looked on StackOverflow and other websites but couldn't figure out how to solve this one. My goal was to teach myself how to use Selenium to automate. My app was built using Jupyter Notebook v6.0.1 which uses Python3.7.
I would be grateful for your help/tips. Many Thanks, Sean
Here is the error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/Users/seankerr/opt/anaconda3/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "<ipython-input-9-c3e0a628cdec>", line 38, in hackathons
assert "hackathons" in driver.title
AssertionError
Here is the python code:
import selenium
import tkinter as tk
from tkinter import *
from tkinter import messagebox #SEAN NOTE: you don't need to import message box from
#tkinter separately because you have already imported '*' all tkinter tools/widgets
import os
import subprocess
import platform
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
def ask_quit():
if messagebox.askokcancel("Quit","Are you sure you want to quit the application and close the window?"):
root.destroy()
root = tk.Tk()
root.title("Hackathon Fetcher")
root.geometry('200x200+200+200')
root.protocol("WM_DELETE_WINDOW", ask_quit)
def raise_app(root: Tk):
root.attributes("-topmost", True)
root.title("Test Title")
if platform.system() == 'Darwin':
tmpl = 'tell application "System Events" to set frontmost of every process whose unix id is {} to true'
script = tmpl.format(os.getpid())
output = subprocess.check_call(['/usr/bin/osascript', '-e', script])
root.after(0, lambda: root.attributes("-topmost", False))
def hackathons():
driver = webdriver.Chrome("./chromedriver")
driver.get("https://challengerocket.com/hackathons-and-challenges.html")
assert "hackathons" in driver.title
elem = driver.find_element_by_name("searchitems")
elem.send_keys("python")
elem.send_keys(Keys.RETURN)
Button(root, text= 'Fetch Python Hackathons', command = hackathons).pack(padx = 20)
#Button(root, text= "Quit", command = ask_quit).pack(expand=1, fill=tk.Y)
root.mainloop()

How to run two process at once using kivy

I'm struggling to simultaneously run my Kivy app alongside a python script that is being locally imported.
Full python code
import Client # Locall import
import time
from threading import Thread
from kivy.app import App
from kivy.uix.button import Button
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
class MainWindow(Screen):
pass
class SecondWindow(Screen):
pass
class WindowManager(ScreenManager):#will manage navigation of windows
pass
kv = Builder.load_file("my.kv")
class Sound(App):
def build(self):
return kv
def ipconfig(self,input_ip):
if len(input_ip) == 13:
print('Address binded!!')
Client.host = input_ip #Modify ip adress
else:
print('Invalid input_ip')```
if __name__ == '__main__':
#Sound().run()#Kivy run method
Thread(target = Sound().run()).start()
time.sleep(10)
Thread(target = Client.father_main).start()
Where the threading happens
if __name__ == '__main__':
#Sound().run()#Kivy run method
Thread(target = Sound().run()).start()
time.sleep(10)
Thread(target = Client.father_main).start() #Client is locally imported
PROBLEMS
1.Only the kivy app runs but the father_main function fails to.
2.The only time father_main runs is when I close the kivy application.
3.If i try and remove the 'run()' from Sound(). I get TypeError: 'Sound' object is not callable and father_main immediately runs
4.If i only remove the parenthesis from 'run()' so it turns into 'run'. I get Segmentation fault (core dumped)
kivy does not encourage the use of time.sleep() and i still have no clue of what exactly your program is but here a solution.
create an on_start method (A method that runs when kivy app started) and add start the ipconfig method from there but you're going to start it asynchronously.
from multiprocessing.pool import ThreadPool
class Sound(App):
def on_start(self):
pool = ThreadPool(processes=1)
async_start = pool.apply_async(self.ip_config, ("value for ip_input here"))
# do some other things inside the main thread here
if __name__ == "__main__":
Sound().run()
You need to run the App on the main thread. I would suggest something like:
def start_father_main(dt):
Thread(target = Client.father_main).start() #Client is locally imported
if __name__ == '__main__':
Clock.schedule_once(start_father_main, 10)
Sound().run()
I haven't tested this code, but it should give you the idea.

socket and multiprocessing blocking

I am trying to write a program that utilizes sockets to talk to others in the cluster. the problem I am having is that I can not seam to implment a server without blocking on accept() even though I have tried to utilize threading and multiprocessing.
server.py
import traceback
import sys, base64
from threading import Thread
import time
def server(host="", port=65098):
host= host
port= port
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.bind((host, port))
soc.listen(5)
clients = []
time.sleep(1)
while 1:
try:
clientsocket, clentaddr = soc.accept()
clients.append(Thread(target=handler, args=(clientsocket, clientaddr)))
except KeyboardInterrupt:
soc.close()
for cl in clients:
if not cl.is_active:
cl.join()
clients.remove(cl)
def handler(clientsocket, clientaddr):
while True:
data = clientsocket.recv(1024).decode('utf8')
if data.startswith('---'):
if data[0:9] == '---test---':
ping(clientsocket, data[10:])
break
clientsocket.close()
def ping(clientsocket, data):
name = base64.decode(data)
clientsocket.send(base64.encode(b'hi' + name))
then I move on to a test.py where I try to work on the noneblocking server with a test.
test.py
from lib import server
import pdb
thread1 = multiprocessing.Process(target=server.server())
pdb.set_trace()
thread1.daemon = True
thread1.start()
# pdb.set_trace()
import socket
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
pdb.set_trace()
soc.connect('localhost', 65098)
message = b'This is our message. It is very long but will only be transmitted in chunks of 16 at a time'
sock.sendall(message)
when I run test.py The program blocks. when I ctl+c it seams that the program is not advancing past line 5(test.py) and is blocking even though I have yet to call thread1.start as you can see I have a pdb trace. this is not being executed. I didn't think it should matter with threading but server.py in the stack seams to be on line 18 where it calls soc.accept().
This is strange behavior to me. any ideas?
For some reason it being inside a module is not allowing threading to run it without the second thread blocking the first thread. I was able to get around this by creating a function in tests.py called tcpserv all it dose is call server.server() instead of calling it directly as the multiprocessing target. test.py now looks like this and dumps to the debugger like I expect.
import multiprocessing
from lib import server
import pdb
def tcpserv():
server.server()
thread1 = multiprocessing.Process(target=tcpserv)
thread1.start()
pdb.set_trace()

tkinter window not closing properly

My tkinter app windows are not closing properly. I am using python 3.6.6 with tkinter 8.6
My code does basically this:
Open a process, where:
A test function is called via a thread that closes Gui window after 3s
Gui window is created
Wait for thread to complete (join) and guess window was closed
I tried to use:
quit -> window only closes when i hover my mouse over it
destroy -> destroy does not return
I stripped it down to the following code, please copy & execute and/or tell me whats wrong...
from time import sleep, time
import threading
from multiprocessing import Process, set_start_method
from tkinter import *
CtrlApplObj = None
def Start():
global CtrlApplObj
CtrlApplObj = None
CtrlApplObj = ControlApplication()
CtrlApplObj.run()
def End():
print("Quit now...")
#CtrlApplObj.root.destroy()
CtrlApplObj.root.quit()
class ControlApplication():
def __init__(self):
pass
def run(self):
self.root=Tk()
print("Mainloop...")
self.root.mainloop()
def test():
sleep(3)
End()
def execute():
T1 = threading.Thread(target=test)
T1.start()
Start()
T1.join()
if __name__ == "__main__":
set_start_method("spawn")
for i in range(2):
TestProcess = Process(target=execute)
TestProcess.start()
TestProcess.join()
My final solution was not using any tkinter operations in test thread. Then destroy worked.
I had another problem with my test process not closing. This was because a queue was not empty. That porevented process to close.

python program not exiting on exception using aiozmq

I am using aiozmq for a simple RPC program.
I have created a client and server.
When the server is running, the client runs just fine.
I have a timeout set in the client to raise an exception in the event of no server being reachable.
The client code is below. When I run it without the server running, I get an expected exception but the script doesn't actually return to the terminal. It still seems to be executing.
Could someone firstly explain how this is happening and secondly how to fix it?
import asyncio
from asyncio import TimeoutError
from aiozmq import rpc
import sys
import os
import signal
import threading
import sys
import traceback
#signal.signal(signal.SIGINT, signal.SIG_DFL)
async def client():
print("waiting for connection..")
client = await rpc.connect_rpc(
connect='tcp://127.0.0.1:5555',
timeout=1
)
print("got client")
for i in range(100):
print("{}: calling simple_add".format(i))
ret = await client.call.simple_add(1, 2)
assert 3 == ret
print("calling slow_add")
ret = await client.call.slow_add(3, 5)
assert 8 == ret
client.close()
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.set_debug(True)
future = asyncio.ensure_future(client())
try:
loop.run_until_complete(future)
except TimeoutError:
print("Timeout occurred...")
future.cancel()
loop.stop()
#loop.run_forever()
main_thread = threading.currentThread()
for t in threading.enumerate():
if t is main_thread:
print("skipping main_thread...")
continue
print("Thread is alive? {}".format({True:'yes',
False:'no'}[t.is_alive()]))
print("Waiting for thread...{}".format(t.getName()))
t.join()
print(sys._current_frames())
traceback.print_stack()
for thread_id, frame in sys._current_frames().items():
name = thread_id
for thread in threading.enumerate():
if thread.ident == thread_id:
name = thread.name
traceback.print_stack(frame)
print("exiting..")
sys.exit(1)
#os._exit(1)
print("eh?")
The result of running the above is below. Note again that the program was still running, I had to to exit.
> python client.py
waiting for connection..
got client
0: calling simple_add
Timeout occurred...
skipping main_thread...
{24804: <frame object at 0x00000000027C3848>}
File "client.py", line 54, in <module>
traceback.print_stack()
File "client.py", line 60, in <module>
traceback.print_stack(frame)
exiting..
^C
I also tried sys.exit() which also didn't work:
try:
loop.run_until_complete(future)
except:
print("exiting..")
sys.exit(1)
I can get the program to die, but only if I use os._exit(1). sys.exit() doesn't seem to cut it. I doesn't appear that there are any other threads preventing the interpreter from dying. (Unless I'm mistaken?) What else could be stopping the program from exiting?

Resources