python nginx+uwsgi+webapp2 奇葩的框架

pylist 176

下面是个奇葩的框架搭建过程
nginx+uwsgi+webapp2

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

摘自 http://kittyandbear.net/python/uwsgi-install-webapp2-POST-password.txt

nginx config

server {
    listen 80;
    server_name *.example.com;
    error_log /var/log/nginx/example-error.log;
    access_log /var/log/nginx/example-access.log;

    location / {
        uwsgi_pass 127.0.0.1:9001;
        include uwsgi_params;
    }
}

uwsgi config

[uwsgi]
chdir = /opt/sites/example/
master = true
threads = 20
socket = 127.0.0.1:9001
callable = app
module = uwsgi_app
logto = /var/log/uwsgi/example.log
# virtualenv = /opt/sites/example/
processes = 4
登录发表评论