Bottle web framework - How to stop?
For the default (WSGIRef) server, this is what I do (actually it is a cleaner approach of Vikram Pudi's suggestion):
from bottle import Bottle, ServerAdapterclass MyWSGIRefServer(ServerAdapter): server = None def run(self, handler): from wsgiref.simple_server import make_server, WSGIRequestHandler if self.quiet: class QuietHandler(WSGIRequestHandler): def log_request(*args, **kw): pass self.options['handler_class'] = QuietHandler self.server = make_server(self.host, self.port, handler, **self.options) self.server.serve_forever() def stop(self): # self.server.server_close() <--- alternative but causes bad fd exception self.server.shutdown()app = Bottle()@app.route('/')def index(): return 'Hello world'@app.route('/stop') # not working from here, it has to come from another threaddef stopit(): server.stop() server = MyWSGIRefServer(port=80)try: app.run(server=server)except: print('Bye')
When I want to stop the bottle application, from another thread, I do the following:
server.stop()
An updated version of mike's answer.
from bottlepy.bottle import WSGIRefServer, runfrom threading import Threadimport timeclass MyServer(WSGIRefServer): def run(self, app): # pragma: no cover from wsgiref.simple_server import WSGIRequestHandler, WSGIServer from wsgiref.simple_server import make_server import socket class FixedHandler(WSGIRequestHandler): def address_string(self): # Prevent reverse DNS lookups please. return self.client_address[0] def log_request(*args, **kw): if not self.quiet: return WSGIRequestHandler.log_request(*args, **kw) handler_cls = self.options.get('handler_class', FixedHandler) server_cls = self.options.get('server_class', WSGIServer) if ':' in self.host: # Fix wsgiref for IPv6 addresses. if getattr(server_cls, 'address_family') == socket.AF_INET: class server_cls(server_cls): address_family = socket.AF_INET6 srv = make_server(self.host, self.port, app, server_cls, handler_cls) self.srv = srv ### THIS IS THE ONLY CHANGE TO THE ORIGINAL CLASS METHOD! srv.serve_forever() def shutdown(self): ### ADD SHUTDOWN METHOD. self.srv.shutdown() # self.server.server_close()def begin(): run(server=server)server = MyServer(host="localhost", port=8088)Thread(target=begin).start()time.sleep(2) # Shut down server after 2 secondsserver.shutdown()
The class WSGIRefServer is entirely copied with only 1 line added to the run() method is added. Also add a simple shutdown() method. Unfortunately, this is necessary because of the way bottle creates the run() method.