uwsgi is a very performant web server for python (and compatible with nginx, cherokee, etc.)
`sudo apt-get install uwsgi on ubuntu 12.04 only installs 1.0.3 **so not good enough!**`
Ensure you have python and pip installed
python --version; pip --version
- - -
### Install UWSGI and Dependencies
`apt-get install build-essential python-dev libxml2-dev`
`sudo pip install uwsgi ` # 1.4.5 or better =)
`vi /var/www/hello.py`
def application( env , start_response ):
start_response( '200 OK' , [('Content-Type','text/html')] )
return "Hello World"
`uwsgi --http :9090 --wsgi-file /var/www/hello.py`
`http://localhost:9090`
> Hello World
- - -
### GOOGLE WEBAPP2 FRAMEWORK ON UBU12.04 WITH UWSGI
`sudo pip install WebOb webapp2`
mkdir /tmp/helloworld # /var/www/helloworld is more likely in production
`vi /tmp/helloworld/helloworld.py`
import webapp2
class MainPage( webapp2.RequestHandler ):
def get( self ):
self.response.headers[ 'Content-Type' ] = 'text/plain'
self.response.write( 'john pfeiffer webapp2 with uwsgi' ) # self.response.out.write is webapp v1
application = webapp2.WSGIApplication([ # note the variable MUST be named application
('/', MainPage)
], debug=True)
uwsgi --logto2 /var/www/uwsgi.log --http :9090 --wsgi-file /var/www/hello.py
http://localhost:9090 # Hello, webapp2 World!
NOTE: you must manually stop the uwsgi and start again to reload new code
- - -
### MORE ADVANCED EXAMPLE: CONFIG, ROUTES, POST, etc.
import webapp2
import cgi
class MainHandler( webapp2.RequestHandler ):
def get( self ):
self.response.headers[ 'Content-Type' ] = 'text/html'
self.response.write( """
<html><head><title>hello</title>
<body>
<form action="/passworded" method="post">
<div><label>password</label><input type="password" id="password" name="password" />
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit"></div>
</form>
</body>
</html>
""");
class Passworded( webapp2.RequestHandler ):
def get( self ):
self.response.headers['Content-Type'] = 'text/plain'
self.response.write( 'Passworded' )
def post( self ):
self.response.headers[ 'Content-Type' ] = 'text/plain'
parameters = self.request.params # works for both GET and POST
if parameters and cgi.escape( parameters[ "password"] ) == "ThePassword":
self.response.write( 'received parameters: %s' % ( str( cgi.escape( parameters[ "password"] ) ) ) )
else:
self.response.write( 'Passworded' )
def another( self ):
self.response.headers[ 'Content-Type' ] = 'text/plain'
self.response.write( 'another' )
routes = [
( '/' , MainHandler ),
( '/passworded' , Passworded ),
webapp2.Route( r'/another' , handler = Passworded , handler_method = 'another' , methods = ['GET'] )
]
config = dict()
config['template.dir'] = 'templates/'
config['assets.dir'] = 'assets/'
config[ 'webapp2_extras.sessions' ] = {'secret_key': 'my-super-secret-key' }
application = webapp2.WSGIApplication( routes = routes , debug = True , config = config )
- - -
### IMPORTANT NOTE ABOUT PYTHON LIBRARIES (IMPORT FROM A MODULE OR PACKAGE)
IF your hello.py uses a subdirectory package for all of your handlers
import handlers
THEN ensure that the uwsgi startup script knows about the correct path...
- - -
`chmod +x SCRIPTNAME.sh`
`cd /etc/init.d THEN update-rc.d SCRIPTNAME.sh defaults`
#!/bin/bash
start(){
/usr/local/bin/uwsgi --pidfile /var/www/python-john/pidfile-uwsgi.pid --touch-reload=/var/www/python-john/pidfile-uwsgi.pid --logto2 /var/www/python-john/uwsgi.log --http :8080 --wsgi-file /var/www/python-john/listing.py --pythonpath /var/www/python-john &
}
stop(){
kill -INT `cat /var/www/python-john/pidfile-uwsgi.pid`
sleep 1
}
status(){
ps aux | grep uwsgi
}
case "$1" in
status)
status
exit 0
;;
start)
start
exit 0
;;
stop)
stop
exit 0
;;
reload|restart|force-reload)
stop
start
exit 0
;;
**)
echo "Usage: $0 {start|stop|reload}" 1>&2
exit 1
;;
esac