Python bottle vs uwsgi/bottle vs nginx/uwsgi/bottle

BobIsNotMyName picture BobIsNotMyName · Aug 2, 2013 · Viewed 7.1k times · Source

I am developing a Python based application (HTTP -- REST or jsonrpc interface) that will be used in a production automated testing environment. This will connect to a Java client that runs all the test scripts. I.e., no need for human access (except for testing the app itself).

We hope to deploy this on Raspberry Pi's, so I want it to be relatively fast and have a small footprint. It probably won't get an enormous number of requests (at max load, maybe a few per second), but it should be able to run and remain stable over a long time period.

I've settled on Bottle as a framework due to its simplicity (one file). This was a tossup vs Flask. Anybody who thinks Flask might be better, let me know why.

I have been a bit unsure about the stability of Bottle's built-in HTTP server, so I'm evaluating these three options:

  1. Use Bottle only -- As http server + App
  2. Use Bottle on top of uwsgi -- Use uwsgi as the HTTP server
  3. USe Bottle with nginx/uwsgi

Questions:

  • If I am not doing anything but Python/uwsgi, is there any reason to add nginx to the mix?
  • Would the uwsgi/bottle (or Flask) combination be considered production-ready?
  • Is it likely that I will gain anything by using a separate HTTP server from Bottle's built-in one?

Answer

sberry picture sberry · Aug 2, 2013

Flask vs Bottle comes down to a couple of things for me.

  1. How simple is the app. If it is very simple, then bottle is my choice. If not, then I got with Flask. The fact that bottle is a single file makes it incredibly simple to deploy with by just including the file in our source. But the fact that bottle is a single file should be a pretty good indication that it does not implement the full wsgi spec and all of its edge cases.
  2. What does the app do. If it is going to have to render anything other than Python->JSON then I go with Flask for its built in support of Jinja2. If I need to do authentication and/or authorization then Flask has some pretty good extensions already for handling those requirements. If I need to do caching, again, Flask-Cache exists and does a pretty good job with minimal setup. I am not entirely sure what is available for bottle extension-wise, so that may still be worth a look.

The problem with using bottle's built in server is that it will be single process / single thread which means you can only handle processing one request at a time.

To deal with that limitation you can do any of the following in no particular order.

  1. Eventlet's wsgi wrapping the bottle.app (single threaded, non-blocking I/O, single process)
  2. uwsgi or gunicorn (the latter being simpler) which is most ofter set up as single threaded, multi-process (workers)
  3. nginx in front of uwsgi.

3 is most important if you have static assets you want to serve up as you can serve those with nginx directly.
2 is really easy to get going (esp. gunicorn) - though I use uwsgi most of the time because it has more configurability to handle some things that I want.
1 is really simple and performs well... plus there is no external configuration or command line flags to remember.