Reputation: 21
I am working on UI app (kivy) and trying to implement python AIOHTTP Server start and stop buttons. I have found example in another post how to start aiohttp server in a thread (main thread is used by UI app). But not sure how to stop the aiohttp server running in a thread, as loop.run_forever is a blocking method.
Thanks in advance.
Python 3.7.0 aiohttp 3.6.2 OS: Windows
Code is:
Serverthread.py
import asyncio
from aiohttp import web
def aiohttp_server():
print("aiohttp_server runner created")
async def say_hello(request):
return web.Response(text='Hello, world')
app = web.Application()
app.add_routes([web.get('/', say_hello)])
runner = web.AppRunner(app)
return runner
def run_server(runner):
print("Entering run_server")
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(runner.setup())
site = web.TCPSite(runner, 'localhost', 8080)
loop.run_until_complete(site.start())
print("Loop run_forever")
loop.run_forever()
def stop_server(runner):
print("Entering stop_server")
App, my-ui.py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty, NumericProperty
from serverthread import run_server, aiohttp_server
import threading
class ServerAdmin(Widget):
active_threads = NumericProperty(0)
t = ObjectProperty(threading.Thread(target=run_server, args=(aiohttp_server(),), daemon=True))
def start_server(self):
if self.active_threads == 0:
print("starting server...")
self.t.start()
self.active_threads += 1
print("Server thread started.")
else:
print("Number of active threads: ", str(self.active_threads))
def stop_server(self):
print("stopping server...")
print(f"Check if thread active: {str(self.t.isAlive())}, {self.t.name}")
pass
class MyUiApp(App):
def build(self):
return ServerAdmin()
if __name__ == '__main__':
MyUiApp().run()
Upvotes: 2
Views: 1607
Reputation: 20596
Keep a reference to the event loop and then request a call to the same handler that AppRunner
uses for handling SIGKILL and SIGTERM
from aiohttp.web_runner import _raise_graceful_exit
loop.call_soon_threadsafe(_raise_graceful_exit)
Upvotes: 0
Reputation: 3524
Share event
class ServerAdmin(Widget):
stop = ObjectProperty(asyncio.Event())
t = ObjectProperty(threading.Thread(target=run_server, args=(aiohttp_server(),stop ), daemon=True))
def stop_server(self):
self.stop.set()
def run_server(runner, stop):
...
print("Loop run_forever")
# loop.run_forever()
loop.run_until_complete(stop.wait())
loop.close()
Upvotes: 1