How to run bottle and a concurrent function? - python

I have a web server which creates a file upon being called. I would like to add somewhere a function, run concurently, which would check this file and act upon its contents but I do not know where to place it in the code. The code for the web server:
import bottle
import pickle
import time
class WebServer(object):
def __init__(self):
bottle.route("/", 'GET', self.root)
bottle.run(host='0.0.0.0', debug=True)
def root(self):
with open("watchdog.txt", "wb") as f:
pickle.dump(time.time(), f)
if __name__ == "__main__":
WebServer()
The function I would like to run together with the web server:
def check():
with open("watchdog.txt", "rb") as f:
t1 = pickle.load(f)
t2 = time.time()
if t2 - t1 > 10:
print("stale watchdog")
The call to WebServer() puts the program into a loop (which is OK, the web server is listening) so I would like to put check() somewhere where it could be combined with a callback (akin to self.root.after() in Tkinter). How to best do this?
NB: I omitted in the code above error checking, accounting for missing watchdog.txt, etc. for the sake of simplicity.

One solution I finally found is to use the Event Scheduler:
import bottle
import pickle
import time
import threading
class WebServer(object):
def __init__(self):
bottle.route("/", 'GET', self.root)
bottle.run(host='0.0.0.0', debug=True)
def root(self):
with open("watchdog.txt", "wb") as f:
pickle.dump(time.time(), f)
def check():
try:
with open("watchdog.txt", "rb") as f:
t1 = pickle.load(f)
except IOError:
pass
else:
t2 = time.time()
if t2 - t1 > 10:
print("stale watchdog")
else:
print("fresh watchdog")
finally:
threading.Timer(10, check).start()
if __name__ == "__main__":
check()
WebServer()

Related

wait_for and condition Python

I somehow wrote this code that allows only one writer at a time and there can't be readers while the writer is working. It works, but I don't know why, I understood that for wait_for() to wake up it was necessary to call notify() but I didn't and still works.
Thanks!
import threading
import time
condition = threading.Condition()
def test():
return True
def reader(data):
with condition:
condition.wait_for(test)
print('read')
def writer(data):
with condition:
time.sleep(5)
print('write')
def runThread(data):
if data["w"]: #writer
writer(data)
elif data["r"]: #reader
reader(data)
def run():
#something happens
threading.Thread(target=runThread, daemon=True, ).start()

Falcon, wsgiref : Unit test cases

I have the below code:
master.py
def create():
master = falcon.API(middleware=Auth())
msg = Message()
master.add_route('/message', msg)
master = create()
if __name__ == '__main__':
httpd = simple_server.make_server("127.0.0.1", 8989, master)
process = Thread(target=httpd.serve_forever, name="master_process")
process.start()
#Some logic happens here
s_process = Thread(target=httpd.shutdown(), name="shut_process")
s_process.start()
s.join()
I tried to create the below test case for the below:
from falcon import testing
from master import create
#pytest.fixture(scope='module')
def client():
return testing.TestClient(create())
def test_post_message(client):
result = client.simulate_post('/message', headers={'token': "ubxuybcwe"}, body='{"message": "I'm here!"}') --> This line throws the error
assert result.status_code == 200
I tried running the above but get the below error:
TypeError: 'NoneType' object is not callable
I actually am unable to figure out how I should go about writing the test case for this.
Based on what #hoefling said, the below fixed it:
master.py
def create():
master = falcon.API(middleware=Auth())
msg = Message()
master.add_route('/message', msg)
return master
master = create()
if __name__ == '__main__':
httpd = simple_server.make_server("127.0.0.1", 8989, master)
process = Thread(target=httpd.serve_forever, name="master_process")
process.start()
#Some logic happens here
s_process = Thread(target=httpd.shutdown(), name="shut_process")
s_process.start()
s.join()
And then the test case works:
from falcon import testing
from master import create
#pytest.fixture(scope='module')
def client():
return testing.TestClient(create())
def test_post_message(client):
result = client.simulate_post('/message', headers={'token': "ubxuybcwe"},
body='{"message": "I'm here!"}')
assert result.status_code == 200
Thanks a lot #hoefling!

Send file pointer to python thread and update file pointer

I have a python program with a thread and the thread should write into a file. I will spawn a thread from the main program. Now on new day trigger I will change the file pointer in the main program and I want the thread also to take the new file to write the data to the file.
I have a code which will take global variable and do this task. But is there any other better way of doing this?
#!/usr/bin/env python
import sys
import threading
import time
filePtr = None
import time
def fileWriteTh():
global filePtr
time.sleep(2)
filePtr.write("from the thrread this should in file 2")
def main():
global filePtr
filePtr = open("test1.txt","ab")
fileThread = threading.Thread(target=fileWriteTh)
fileThread.start()
if new_day_trigger:
filePtr.close()
filePtr = open("test2.txt","ab")
fileThread.join()
if __name__ == "__main__":
main()
This is the new code that is written:
#!/usr/bin/env python
import sys
import threading
import time
class SendPacket(object):
fileDesc = None
def __init__(self, fd):
super(SendPacket, self).__init__()
SendPacket.fileDesc = fd
def printFromInstance(self,var):
print var
SendPacket.fileDesc.write(var)
time.sleep(3)
print var
SendPacket.fileDesc.write(var)
def startabc(self, someVar):
self.printFromInstance(someVar)
#classmethod
def printVar(cls, printStr):
print printStr
cls.fileDesc.write(printStr)
#classmethod
def changeClsFile(cls, newFd):
cls.fileDesc = newFd
def main():
filePtr = open("test1.txt","ab")
sendPack_inst = SendPacket(filePtr)
fileThread = threading.Thread(target=sendPack_inst.startabc, args=("test1",))
fileThread.start()
time.sleep(2)
filePtr.close()
filePtr = open("test2.txt","ab")
SendPacket.changeClsFile(filePtr)
fileThread.join()
filePtr.close()
if __name__ == "__main__":
main()
Like this:
#!/usr/bin/env python
import sys
import thread
import time
class _fileACT :
def __init__(self):
self.trigger = 0
self.flag = True
self.msg = ""
self.files = (open("test1.txt","ab"),open("test2.txt","ab"))
def run(self,pssrg):
while self.flag :
if self.msg != "" :
self.files[self.trigger].write(self.msg)
self.msg = ""
def test(self,pssrg):
for i in range(20):
time.sleep(1)
if i %2 != 0 :
self.trigger = 0
elif i %2 != 1:
self.trigger = 1
self.msg = "%0.3d test-1,asdasdasd\n"%i
time.sleep(0.5)
print "wait..."
self.flag = False
for e in self.files : e.close()
print "can exit !"
if __name__ == "__main__":
fileACT = _fileACT()
thread.start_new_thread(fileACT.run,(None,))
thread.start_new_thread(fileACT.test,(None,))
We have three variables, filename, last opened file name and message. Two files, only False and True will be sufficient (of course you can use index for multiple files). We've written a test function into the class because we don't want our main cycle to freeze. The file selection is done with ' trigger ', but the previous and next file name is not the same, the previous closes.
The important point in the thread is that the time delay is strictly unavailable! The time delay is always applied to the trigger. The time delay cannot be placed in the main loop. An instance of access from outside the class is also attached. I hope it helps.

how to call a method on the GUI thread?

I am making a small program that gets the latest revenue from a webshop, if its more than the previous amount it makes a sound, I am using Pyglet but I get errors because its not being called from the main thread. I would like to know how to call a method on the main thread. see error below:
'thread that imports pyglet.app' RuntimeError: EventLoop.run() must
be called from the same thread that imports pyglet.app
def work ():
threading.Timer(5, work).start()
file_Name = "save.txt"
lastRevenue = 0
data = json.load(urllib2.urlopen(''))
newRevenue = data["revenue"]
if (os.path.getsize(file_Name) <= 0):
with open(file_Name, "wb") as f:
f.write('%d' % newRevenue)
f.flush()
with open(file_Name, "rb") as f:
lastRevenue = float(f.readline().strip())
print lastRevenue
print newRevenue
f.close()
if newRevenue > lastRevenue:
with open(file_Name, "wb") as f:
f.write('%f' % newRevenue)
f.flush()
playsound()
def playsound():
music = pyglet.resource.media('cash.wav')
music.play()
pyglet.app.run()
work()
It's not particularly strange. work is being executed as a separate thread from where pyglet was imported.
pyglet.app when imported sets up a lot of context variables and what not. I say what not because I actually haven't bothered checking deeper into what it actually sets up.
And OpenGL can't execute things out of it's own context (the main thread where it resides). There for you're not allowed to poke around on OpenGL from a neighboring thread. If that makes sense.
However, if you create your own .run() function and use a class based method of activating Pyglet you can start the GUI from the thread.
This is a working example of how you could set it up:
import pyglet
from pyglet.gl import *
from threading import *
# REQUIRES: AVBin
pyglet.options['audio'] = ('alsa', 'openal', 'silent')
class main(pyglet.window.Window):
def __init__ (self):
super(main, self).__init__(300, 300, fullscreen = False)
self.x, self.y = 0, 0
self.bg = pyglet.sprite.Sprite(pyglet.image.load('background.jpg'))
self.music = pyglet.resource.media('cash.wav')
self.music.play()
self.alive = 1
def on_draw(self):
self.render()
def on_close(self):
self.alive = 0
def render(self):
self.clear()
self.bg.draw()
self.flip()
def run(self):
while self.alive == 1:
self.render()
if not self.music.playing:
self.alive = 0
# -----------> This is key <----------
# This is what replaces pyglet.app.run()
# but is required for the GUI to not freeze
#
event = self.dispatch_events()
class ThreadExample(Thread):
def __init__(self):
Thread.__init__(self)
self.start()
def run(self):
x = main()
x.run()
Test_One = ThreadExample()
Note that you still have to start the actual GUI code from within the thread.
I STRONGLY RECOMMEND YOU DO THIS INSTEAD THO
Seeing as mixing threads and GUI calls is a slippery slope, I would suggest you go with a more cautious path.
from threading import *
from time import sleep
def is_main_alive():
for t in enumerate():
if t.name == 'MainThread':
return t.isAlive()
class worker(Thread):
def __init__(self, shared_dictionary):
Thread.__init__(self)
self.shared_dictionary
self.start()
def run(self):
while is_main_alive():
file_Name = "save.txt"
lastRevenue = 0
data = json.load(urllib2.urlopen(''))
newRevenue = data["revenue"]
if (os.path.getsize(file_Name) <= 0):
with open(file_Name, "wb") as f:
f.write('%d' % newRevenue)
f.flush()
with open(file_Name, "rb") as f:
lastRevenue = float(f.readline().strip())
print lastRevenue
print newRevenue
f.close()
if newRevenue > lastRevenue:
with open(file_Name, "wb") as f:
f.write('%f' % newRevenue)
f.flush()
#playsound()
# Instead of calling playsound() here,
# set a flag in the shared dictionary.
self.shared_dictionary['Play_Sound'] = True
sleep(5)
def playsound():
music = pyglet.resource.media('cash.wav')
music.play()
pyglet.app.run()
shared_dictionary = {'Play_Sound' : False}
work_handle = worker(shared_dictionary)
while 1:
if shared_dictionary['Play_Sound']:
playsound()
shared_dictionary['Play_Sound'] = False
sleep(0.025)
It's a rough draft of what you're looking for.
Basically some sort of event/flag driven backend that the Thread and the GUI can use to communicate with each other.
Essentially you have a worker thread (just as you did before), it checks whatever file you want every 5 seconds and if it detects newRevenue > lastRevenue it will set a specific flag to True. Your main loop will detect this change, play a sound and revert the flag back to False.
I've by no means included any error handling here on purpose, we're here to help and not create entire solutions. I hope this helps you in the right direction.

how to achieve - file write open on __del__?

I m trying to do a some activity on class obj destruction.
How do I achieve file open in __del__ function?
(I m using Python 3.4)
class iam(object):
def __init__(self):
print("I m born")
def __del__(self):
f = open("memory_report.txt", "w")
f.write("He gone safe")
f.close()
if __name__ == '__main__':
i = iam()
print("Script Ends. Now to GC clean memory")
Output:
I m born
Script Ends. Now to GC clean memory
Exception ignored in: <bound method iam.__del__ of <__main__.iam object at 0x00000000022F1A58>>
Traceback (most recent call last):
File "F:\Kumaresan\Code\Python\CommonLib\src\kmxPyQt\devConsole3\tet.py", line 14, in __del__
NameError: name 'open' is not defined
Below code is work fine.
class iam(object):
def __init__(self):
print("I m born")
def __del__(self):
#"open" function still in __builtins__
f = open("memory_report.txt", "w")
f.write("He gone safe")
f.close()
def write_iam():
i=iam()
if __name__ == '__main__':
write_iam()
print("Script Ends. Now to GC clean memory")
In this case:
class iam(object):
def __init__(self):
print("I m born")
def __del__(self):
#__builtins__.open has remove
f = open("memory_report.txt", "w")
f.write("He gone safe")
f.close()
if __name__ == '__main__':
i = iam()
print("Script Ends. Now to GC clean memory")
When exit the __main__ function, before GC delete the "i" instance (execute i.__delete__) "open" function has remove from __builtins__.
As others have mentioned, don't use the ____del___ method to perform such cleanup. Instead, use either contextmanagers (with-statement) or register atexit-handlers.
The problem is, as MuSheng tried to explain, that the __builtins__ are removed before your __del__ is called.
You can trigger the __del__ yourself by assigning None to the variable.
MuSheng's code could be this:
class iam():
def __init__(self):
print("I m born")
def __del__(self):
#"open" function still in __builtins__
with open("memory_report.txt", "w") as f:
f.write("He gone safe")
if __name__ == '__main__':
i = iam()
i = None # This triggers `__del__`
print("Script Ends. Now to GC clean memory")
MuSheng deserves some upvotes, IMO
Below is an alternate I used - Using atexit handlers:
import atexit
class iam(object):
def __init__(self):
print("I m born")
atexit.register(self.cleanup)
def cleanup(self):
f = open("memory_report.txt", "w")
f.write("He gone safe")
f.close()
print ("Done")
if __name__ == '__main__':
i = iam()
print("Script Ends. Now to GC clean memory")
Output:
I m born
Script Ends. Now to GC clean memory
Done

Categories