Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Web server in a separate thread?
-
Would someone know of a robust web server implementation running in a separate thread, whenever my app is running?
For the web server, I would be happy with any basic option available in Pythonista; vanilla, bottle, flask, ...
To be considered a "robust implementation", my simple wish list includes:
- Logs issues, but stays up and running
- (Can be made to) Exit cleanly with the rest of the app
- Has been used in some real app for a while
Any pointers?
-
-
@ccc, thank you. Seems simple enough, but I cannot get it to release the socket on exit, causing an error on the next run. Was this not an issue for you, or am I doing something wrong?
-
FWIW, when I've experimented with servers in Pythonista, I also found that the port would often remain "occupied" after stopping the server using the stop button (i. e.
KeyboardInterrupt
). This was easily fixed by rerunning the server twice - i. e. the first run would fail due to the port being in use, but the second run would work again. (This was a while ago when I was playing around with Python's built-in HTTP server module, no idea if this still happens in current versions, or if this even applies to your situation.)My wild guess would be that this is some sort of interaction between the "dirty" shutdown via
KeyboardInterrupt
, the garbage collector, and how Pythonista's interpreter never fully restarts. TheKeyboardInterrupt
breaks out of the server's main loop, but doesn't close or delete the socket, which is still referenced (indirectly) from a global variable. Rerunning the script clears or overwrites the global, which eventually deletes the socket, but not quick enough for that script run to reuse the port. On the next run, the port is free again and can be reused. (Again, I just came up with this explanation in my head and didn't really verify it. This may be absolute nonsense.) -
Below is a version of a bottle server that runs in a thread and can be told to shut down cleanly, based on this stackoverflow answer.
#coding: utf-8 from ui import * import bottle, threading, requests, time from bottle import Bottle, ServerAdapter class 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.shutdown() app = Bottle() @app.get('/') def bottle_get_index(): return "Test OK" if __name__ == '__main__': w = WebView() w.present('full_screen') w.load_html('Loading...') server = MyWSGIRefServer(port=80) threading.Thread(group=None, target=app.run, name=None, args=(), kwargs={'server': server, 'quiet': False}).start() time.sleep(2) req = requests.get('http://127.0.0.1/') w.load_html(req.text) server.stop()