Setting up Flask cgi app as a tool

From Wikitech

"Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions. And before you ask: It's BSD licensed!" It can be use via CGI to write web applications like tool scripts and the like here on labs.

Setting up a Flask app as default web app for a Tool

Set up virtualenv

You would want to have a separate python environment for your tool. Checkout virtualenv on how to use it. If you don't need anything special just do a

virtualenv python

This sets up a local python environment in a directory called 'python'.

Install Flask

source python/bin/activate
pip install flask

Setup flask app

Create an app.py file in /cgi-bin

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
   return "Hello World!"

if __name__ == "__main__":
   app.run()


create a cgi.py file /cgi-bin

Use the approrpiate path to python in shebang and site packages for your tool:

which python

Refer: Taken from http://flask.pocoo.org/docs/deploying/cgi/

replace the first line here with the results of which python and ensure the path on the third line is correct:

#!/data/project/tools-dashboard/python/bin/python
import site
site.addsitedir("/data/project/tools-dashboard/python/lib/python2.7/site-packages")

from wsgiref.handlers import CGIHandler
from app import app
import os

os.environ['SCRIPT_NAME'] = '/tools-dashboard'
CGIHandler().run(app)

Ensure permissions

All python files in cgi-bin must be owned by the tool and executable permissions set.

chmod +x cgi-bin/*.py

If everything went right, you should be able to load this page http://tools.wmflabs.org/tools-dashboard/cgi-bin/cgi.py/ and its content must be "Hello world" (replace tools-dashboard with your app name)

Make it the default app

The last step is to load this app at http://tools.wmflabs.org/tools-dashboard/. You have to add a .htaccess in ~/public_html of your tools.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule ^(.*)$ /tools-dashboard/cgi-bin/cgi.py/$1 [L]

Debugging

Because there is no access to error logs, you have to manually register an error log file:

import logging
from logging import FileHandler   
(...)
app = Flask(__name__)
logger = FileHandler('/path/to/your/error.log')
logger.setLevel(logging.WARNING)
app.logger.addHandler(logger)

OAuth login / API use

See /OAuth