Skip to content

electionscience/vote.electionscience.org

Repository files navigation

Approval Voting Platform

A Django-based web application for creating and managing approval voting polls. This platform provides an alternative to traditional plurality voting polls, allowing voters to approve of multiple options rather than being limited to a single choice.

The application can be used as a standalone service at vote.electionscience.org or the approval_polls package can be integrated into other Django projects.

Features

  • Approval Voting: Voters can approve of multiple options in a single poll
  • Embeddable Polls: Polls can be embedded in other websites via iframe
  • Multiple Voting Types: Public, authenticated, and invitation-only polls
  • Real-time Results: View approval counts and proportional vote calculations
  • User Management: User accounts with poll creation and management
  • Tagging System: Organize polls with tags
  • Email Integration: Optional email opt-in and invitation system

Prerequisites

  • Python 3.14.0 or higher
  • UV package manager
  • Git

Local Development Setup

1. Clone the Repository

git clone [email protected]:electionscience/vote.electionscience.org.git
cd vote.electionscience.org

2. Configure Environment

Copy the example environment file and fill in the required values:

cp .env.dist .env

Edit .env with your configuration. At minimum, you'll need to set:

  • DEBUG=True for local development
  • SECRET_KEY (generate a random string)
  • SENDGRID_API_KEY (optional, for email functionality)
  • GOOGLE_SECRET (optional, for Google OAuth)

3. Install Dependencies

UV manages both Python versions and dependencies. It will automatically detect the required Python version from pyproject.toml (requires >=3.14.0) and .python-version (specifies 3.14).

Install UV:

# macOS/Linux
brew install uv

# Or use the official installer
curl -LsSf https://astral.sh/uv/install.sh | sh

Install project dependencies:

uv sync

The uv sync command will:

  • Automatically install Python 3.14 if needed
  • Create a virtual environment (.venv)
  • Install all dependencies from pyproject.toml
  • Generate or update uv.lock for reproducible builds

Note: uv commands (like uv sync, uv run, uv pip install) automatically detect and use the .venv directory, so manual activation isn't required for uv commands. However, if you want to run python directly or use other tools like pytest or mypy, you'll need to activate the virtualenv:

source .venv/bin/activate

Optional: Auto-activate virtualenv with direnv

For convenience, you can use direnv to automatically activate the virtualenv when entering this directory:

# Install direnv
brew install direnv

# Add to your shell (add this to ~/.zshrc)
eval "$(direnv hook zsh)"

# Create .envrc file in the project directory
echo 'export VIRTUAL_ENV="$PWD/.venv"' > .envrc
echo 'export PATH="$VIRTUAL_ENV/bin:$PATH"' >> .envrc

# Allow direnv in this directory (only needed once)
direnv allow

This will automatically activate .venv when you cd into the project directory and deactivate it when you leave.

Adding dependencies:

To add a new dependency, use:

uv add package-name

This will update pyproject.toml and uv.lock automatically.

4. Initialize the Database

Run migrations to create the database tables:

python manage.py migrate

During the first migration, you'll be prompted to create a superuser account. This is recommended for accessing the Django admin interface and creating polls.

5. Collect Static Files

Collect static files for the admin interface and other static assets:

python manage.py collectstatic --noinput

6. Configure Site Domain (Optional)

If you need email functionality to work correctly, update the site domain in the Django admin:

  1. Start the server: python manage.py runserver
  2. Visit http://localhost:8000/admin
  3. Go to Sites → Sites
  4. Change the domain from example.com to localhost:8000 (or your actual domain)

7. Start the Development Server

python manage.py runserver

Visit http://localhost:8000/ in your browser.

You can now:

  • Log in with your superuser account
  • Create new polls
  • Vote in polls
  • View results

Testing

Run the test suite:

python manage.py test

Or using pytest:

pytest

The project uses pytest with Django integration. Test files should be named test_*.py or *_tests.py.

Code Quality

Linting and Formatting

We use Trunk to enforce consistent coding style:

npm install -g @trunk/cli
trunk check

Type Checking

The project uses type hints. Run type checking with:

mypy approval_polls

Project Structure

approval_polls/
├── models.py          # Poll, Choice, Ballot, Vote models
├── views.py            # View handlers for polls, voting, results
├── urls.py             # URL routing
├── settings.py         # Django configuration
├── templates/          # HTML templates
├── staticfiles/        # Static assets (CSS, JS, images)
└── tests.py            # Test suite

Deployment

Production Deployment on Fly.io

This project is deployed to production on fly.io from an account managed by Felix Sargent.

Deployment process:

  1. Ensure you have the flyctl CLI installed
  2. Configure your fly.io app (see fly.toml)
  3. Deploy:
fly deploy

Note: Docker is only used for fly.io deployment via the Dockerfile. For local development, you run Django directly without Docker.

The Dockerfile uses UV to install dependencies and runs the application with gunicorn.

Automatic deployments: The project is configured to automatically deploy to production on push to the main branch.

Contributing

We welcome contributions! Here are some resources to get started:

Learning Resources

Contribution Process

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests: python manage.py test
  5. Check code style: trunk check
  6. Submit a pull request

Coding Standards

  • Follow PEP 8 style guidelines
  • Use type hints where appropriate
  • Write tests for new features
  • Update documentation as needed
  • Run trunk check before submitting

License

See LICENSE file for details.

Support

For issues, questions, or contributions, please open an issue on GitHub.

Related Resources

About

Down with Plurality-Based Web Polling!

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 16