Running Python CGI Scripts on the Raspberry Pi

Python is the language of choice for controlling the Raspberry Pi’s GPIO pins. It seems only natural then that to interact with your Pi over the web it should run a web server able to handle Python CGI scripts. Following the steps below will get the lightweight nginx web server running on your Pi, handing Python requests off to a uwsgi helper process.

  1. Install nginx
    sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get install nginx
  2. Add a location to the /etc/nginx/sites-available/default to pass Python requests on to uwsgi. This needs to be placed inside the “server” block of the configuration, for example right after one of the existing “location” sections.
    location ~ \.py$ {
    include uwsgi_params;
    uwsgi_modifier1 9;
  3. Create a Python CGI script at /usr/share/nginx/www/
    #!/usr/bin/env python
    print "Content-type: text/html\n\n"
    print "<h1>Hello World</h1>"
  4. Start nginx
    sudo /etc/init.d/nginx start
  5. Build and install the uwsgi with the cgi plugin
    curl | bash -s cgi /home/pi/uwsgi
    sudo mv /home/pi/uwsgi /usr/local/bin
  6. Create the file /etc/uwsgi.ini
    plugins = cgi
    socket =
    module = pyindex
    cgi = /usr/share/nginx/www
    cgi-allowed-ext = .py
    cgi-helper = .py=python
  7. Create the file /usr/share/nginx/www/
    #!/usr/bin/env python
    print "Content-type: text/html\n\n"
    print "<h1>Hello World</h1>"
  8. Create an init script for uwsgi at /etc/init.d/uwsgi
    #!/bin/sh### BEGIN INIT INFO
    # Provides: uwsgi
    # Required-Start: $local_fs $remote_fs $network $syslog
    # Required-Stop: $local_fs $remote_fs $network $syslog
    # Default-Start: 2 3 4 5
    # Default-Stop: 0 1 6
    # Short-Description: starts the uwsgi cgi socket
    # Description: starts uwsgi using start-stop-daemon
    test -x $DAEMON || exit 0
    set -e
    . /lib/lsb/init-functions
    case "$1" in
    echo -n "Starting $DESC: "
    start-stop-daemon --start --quiet --pidfile /var/run/$ \
    --make-pidfile --chuid www-data --background \
    --exec $DAEMON -- $DAEMON_OPTS || true
    echo "$NAME."
    echo -n "Stopping $DESC: "
    start-stop-daemon --stop --quiet --pidfile /var/run/$ \
    --exec $DAEMON || true
    echo "$NAME."
    echo -n "Restarting $DESC: "
    start-stop-daemon --stop --quiet --pidfile \
    /var/run/$ --exec $DAEMON || true
    sleep 1
    start-stop-daemon --start --quiet --pidfile /var/run/$ \
    --chuid www-data --background \
    --exec $DAEMON -- $DAEMON_OPTS || true
    echo "$NAME."
    status_of_proc -p /var/run/$ "$DAEMON" uwsgi && exit 0 || exit $?
    echo "Usage: $NAME {start|stop|restart|status}" >&2
    exit 1
    exit 0
  9. Start uwsgi and configure it to start on boot
    sudo chmod +x /etc/init.d/uwsgi
    sudo /etc/init.d/uwsgi start
    sudo update-rc.d uwsgi defaults
  10. Open up your web browser and go to http://{your pi’s ip address}/
    If you’re using the browser on your Pi then you could instead go to http://localhost/
    If you see the message “Hello World” then everything is working.

About Takaitra

Matthew is a software engineer for Amazon's Cloud Drive team working with various technologies including web services, React Native and Android. His interests include motorcycling, camping, photography, small electronics and traveling. He lives in Seattle, Washington with his beautiful wife and two children.

Leave a Reply

Your email address will not be published. Required fields are marked *