CodeFuboard ----------- This is a leaderboard built using Python (Flask, and more...) where students can submit code assignments and compare their performance metrics against other students. The leaderboard is built to be simple (and dirty), and should be fairly easy to get working in any environment that has Python 3 and some webserver with WCGI support. Setup ===== Make sure you have the packages listed in `requirements.txt`. After this you can call Flask to run the app: ```sh $ export FLASK_APP=codefuboard/__init__.py $ mkdir instance/ $ flask run ``` We use Flask-AppConfig, as such various config values can be found in `default_config.py`. **Remember to update the `SECRET_KEY`, use some random value before using this app in production!** ### ReCaptcha This application can make use of ReCaptcha for all forms (including admin login). Generate a the ReCaptacha keys and add these to the `default_config.py` file. ### Webserver Setup To run this app in a production environment one needs to proxy the Python driven process through a webserver. For this I use Nginx together with uWSGI to handle the Python process. In this example, I have cloned the app into `/srv/http/lb/codefuboard`. Additionally I created a system user `codefu` which will _run_ the app. The uWSGI configuration for this is below: ```ini [uwsgi] strict = true plugins = python chdir = /srv/http/lb/codefuboard module = wsgi callable = app master = true processes = 4 threads = 2 vacuum = true ; Delete sockets during shutdown single-interpreter = true die-on-term = true need-app = true enable-threads = true buffer-size = 65535 lazy = true chmod-socket = 775 socket = /srv/http/lb/run/%n.sock pidfile = /srv/http/lb/run/.pid disable-logging = false log-4xx = true log-5xx = true logto = /srv/http/lb/log/%n.log uid = codefu gid = codefu ``` I then setup Nginx with the following server configuration: ```nginx server { server_name ; #charset koi8-r; #access_log logs/host.access.log main; root /srv/http/lb; error_log /srv/http/lb/log/error.log; access_log /srv/http/lb/log/access.log; location / { try_files $uri @context; } location /leaderboard/ { rewrite ^/leaderboard/(.*)$ /lb/$1 permanent; } location @context { include uwsgi_params; uwsgi_pass unix:/srv/http/lb/run/lb.sock; } # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } ``` ### Database The app was initially built supporting pickledb as its db-backend. This proved not to scale well at all in production. So I moved it to use Redis together with MsgPack. The latter can encode most Python structures into strings, making it easy to store complex structures in Redis. Todo ==== - support notion of students and teams - teams need to pre-register?