Bottle web framework - How to stop? Bottle web framework - How to stop? python python

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()


I had trouble closing a bottle server from within a request as bottle seems to run requests in subprocesses.

I eventually found the solution was to do:

sys.stderr.close()

inside the request (that got passed up to the bottle server and axed it).


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.