Freezing Saddles competition main web application
Python JavaScript HTML CSS
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

Freezing Saddles Web

This is the web component for the Freezing Saddles (aka BikeArlington Freezing Saddles, "BAFS") Strava-based winter cycling competition software.

NOTE: This application conists of multiple components that work together (designed to run as Docker containers).

  1. freezing-web - The website for viewing leaderboards
  2. freezing-model - A library of shared database and messaging classes.
  3. freezing-sync - The component that syncs ride data from Strava.
  4. freezing-nq - The component that receives webhooks and queues them up for syncing.

Development Setup


  • Python 3.6+ (will not work with python 2.x)
  • Pip
  • Virtualenv (venv)
  • MySQL. (Sadly.)


Here are some instructions for setting up a development environment:

# Clone repo
shell$ git clone

# Create and activate a virtual environment for freezing-web
shell$ cd freezing-web
shell$ python3.6 -m venv env
shell$ source env/bin/activate
(env) shell$ pip install -r requirements.txt
(env) shell$ python develop

We will assume for all subsequent shell examples that you are running in the freezing-web activated virtualenv. (This is denoted by using the "(env) shell$" prefix before shell commands.)

Database Setup

This application requires MySQL. I know, MySQL is a horrid database, but since I have to host this myself (and my shared hosting provider only supports MySQL), it's what we're doing.

DB Setup using Docker

We have some development support Docker Compose files that can help make database setup simpler, head over to the freezing-compose repo for those instructions.

Manual DB Setup

Install MySQL, version 5.6 ideally. (A newer 5.x may work fine too, but current production db server is 5.6 so there might be differences in supported db features.)

You should create a database and create a user that can access the database. Something like this might work in the default case:

shell$ mysql -uroot
mysql> create database freezing;
mysql> grant all on freezing.* to freezing@localhost;

Configure and Run Server

Configuration files are shell environment files (or you can use environment variables dirctly).

There is a sample file (example.cfg) that you can reference. You need to set an environment variable called APP_SETTINGS to the path to the file you wish to use.

Here is an example of starting the webserver using settings from a new development.cfg config file:

(env) shell$ cp example.cfg development.cfg
# Edit the file
(env) shell$ APP_SETTINGS=development.cfg freezing-server

Critical things to set include:

  • Database URI
  • Strava Client info (ID and secret), if you want to test registration/authorization/login.
# The SQLALchemy connection URL for your MySQL database.
# NOTE: If you are using docker use as the host, NOT localhost

# These are issued when you create a Strava application.
# These are really only needed if you want to test app authorization or login features.

Docker Deployment

See freezing-compose for guide to deploying this in production along with the related containers.

This component is designed to run as a container and should be configured with environment variables for:

  • DEBUG: Whether to display exception stack traces, etc.
  • SECRET_KEY: Used to cryptographically sign the Flask session cookies.
  • BEANSTALKD_HOST: The hostname (probably a container link) to a beanstalkd server.
  • BEANSTALKD_PORT: The port for beanstalkd server (default 11300)
  • SQLALCHEMY_URL: The URL to the database.
  • STRAVA_CLIENT_ID: The ID of the Strava application.
  • STRAVA_CLIENT_SECRET: Secret key for the app (available from App settings page in Strava)
  • TEAMS: A comma-separated list of team (Strava club) IDs for the competition. = env('TEAMS', cast=list, subcast=int, default=[])
  • OBSERVER_TEAMS: Comma-separated list of any teams that are just observing, not playing (they can get their overall stats included, but won't be part of leaderboards)
  • START_DATE: The beginning of the competition.
  • END_DATE: The end of the competition.