Why webapp2 replaces bottle.py on Levinux since Beta 2.0 (hint: GAE)
by Mike Levin SEO & Datamaster, 10/08/2013
Okay, that last post is what I can accomplish with about 35 minutes of thought-work. The purpose of this next journal entry is to demonstrate (as much to myself as to you) how quickly I can capitalize on these 2 successive tiny breakthroughs. The answer has to be: pretty darn quick! Or I have to start changing my image of myself. Get stuff done!
As you observed at the end of the day yesterday, it’s all about understanding a bit about the webapp2 framework. For those who haven’t reproduced my entire mental state, webapp2 is the web development framework that comes by default with a new generic virtual server instance on the Google Apple Engine. The Python programming language itself has a reputation for having an excess (and lack-of-standard) of web frameworks, and this is a fair criticism. However…
Python has made part of its very own specification a standard for passing information around in a web development environment, so all those good bits like Server variables and request information is carried around between functions in a fairly standardized format. The upshot of this, is no matter which web framework you choose, the code you write will - with minimal muss and fuss - be transportable rather easily between different web frameworks.
And there’s a bunch of these web frameworks for Python to choose from. I didn’t know this when I developed Tiger for the first time, and gravitated towards an environment that I could “instantiate” really easily on new servers, so I could easily script new server environments and make Tiger more of a travelling codebase that can run anywhere than a particular server instance. I made it so that easily reproducible “server formulas” were possible.
In that quest, I chose mod_python which is NOT a WSGI code execution environment for Python. This has become a hot-topic of discussion in the Apache and Python communities, who don’t always see things eye-to-eye. WSGI-support native in Apache is not a priority to the Apache code maintainers and mod_python contributors. It’s stable, bug-free, has certain technical advantages with its access to the internals of Apache, and has plenty of people using it. Just because the Python folks wrote an Enhancement Proposal (PEP) that’s been finalized, isn’t enough reason to update mod_python to use WSGI and potentially break everyone’s existing codebases.
And so, a rift between Python and everyone else who uses dedicated webservers for their web app code execution environments. Those other folks have flocked off of the bloated Apache, but onto a similar environment that’s mod_[your favorite extension]-compatible with Apache2: nginx, lighthttpd, Zeus, LiteSpeed and all the others that try to keep your fundamental Apache2 know-how intact and useful in your “next life”. Making the move to Python and WSGI-compatible web frameworks like bottle.py, Flask, Tornado, Twisted, web.py, web2py, webapp2, or any of the other multitudes for Python… which all essentially use the same trick… of NOT HAVING A WEBSERVER OTHER THAN PYTHON ITSELF.
Grok that for a moment: no webserver. No nginx. No Apache2. No tomcat code execution compatibility, code-bloat, and configuration nightmares. If you just install Python and can execute one pip-command to get the web framework of your choice installed, then everything is set up. A webserver is a matter of writing a single file - often 1 to 100 lines-of-code, and running directly with Python using a command like: python mywebapp.py (which ties up the command-line shell you ran it from) or in the background like Apache with a command like: nohup python mywebapp.py &.
The nohup command sends your Python program into the background and running it with the ampersand makes the command-line not wait for a response. Together, it’s like running Python as a Linux daemon. Once you really have a server set up, you want to get the requirement for a nohup command at startup out of the picture by daemonizing your task. A daemonized task becomes a parameter of the “start” and “stop” command, so you only have to run once the command: start mywebapp… or the command: stop mywebapp, and it will be a first-class daemon on the Linux system, just like Apache2 or anything else that runs constantly in the background. That’s how this stuff works. It’s not even a scheduled cron job - it’s just ALWAYS RUNNING… and that’s how Python web frameworks work.
Okay, when I got up to choosing a web framework for Levinux, I chose bottle.py, because even though it wasn’t as full-featured or slick as Flask or some of the others, it is just A SINGLE FILE, which is a great opportunity to teach about about these web frameworks, getting the mystery out of this setup, and explain a few astoundingly interesting characteristics of the Python system in the process. So, my first video tutorial on web programming on Levinux has me dropping bottle.py into the same directory as something called webapp.py, and having webapp.py import from its neighboring file, bottle.py and how that totally takes the place of Apache when Python is your programming language. Amazing!
Okay, but what about when you use a web framework that has lots of supporting files, and maybe even dependencies on other libraries in-turn? And why would you even choose such a network of dependencies to reproduce your server environment, if you don’t have to? Well, the answer to the first is features, elegance, and staying in sync with the decisions that the Google App Engine people made. The answer to the second is in /usr/local/lib/python2.7/site-packages/ (if you’re not using a virtualenv, and wherever you’ve defined if you are). However, these are precisely the sort of things that are hidden from you when you actually start out on the GAE.
And so, what I did over the last few days was to adapt my version of Levinux so that I could relatively rapidly build the entire development environment I needed to program for Google Glass in Python 2.7, with all the necessary client libraries, such as the webapp2 web development framework so that when I examine the code examples in my working Google Glass Mirror API Quickstart example, I have some chance of transposing over the code and making it work. Or probably more likely, I can at least glean insights. I also install the entire Google API Python Client, so that I can more easily access a whole variety of Google services - especially OAuth 2 login… which brings me to where I’m now at.