Skip to content

AlborzNazari/Secure-Apportionment-System

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

202 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Secure Apportionment System

Windows Python Flask Docker Encryption Algorithm License: MIT Tests

A secure parliamentary seat apportionment tool that implements the Huntington-Hill algorithm with AES-256-CBC encryption. Supports both a command-line interface and a web-based interface via Flask.


🔗 Visual Lab Secure Apportionment System

Secure-Apportionment-System

What It Does

This system takes a CSV file of political parties and their vote counts, then fairly distributes a given number of parliamentary seats using the Huntington-Hill method — the same method used in the U.S. House of Representatives. Results are encrypted with AES-256 before being saved to disk, ensuring data integrity and confidentiality.


Project Structure

Secure-Apportionment-System/
├── Dockerfile               # Multi-stage Docker build
├── docker-compose.yml       # Local dev orchestration
├── .dockerignore            # Excludes secrets and artifacts from image
├── .env.example             # Environment variable template (commit this)
├── .env                     # Your local secrets (never commit)
├── src/
│   ├── main.py              # CLI entry point with AES-256 encryption
│   ├── app.py               # Flask web application
│   ├── apportionment.py     # Huntington-Hill algorithm
│   ├── validators.py        # Input validation
│   ├── logging_setup.py     # Secure logging
│   ├── AES-256.py           # Standalone AES-256-CBC encryption module
│   └── __init__.py
├── backend/
│   ├── config.py            # Environment-based configuration
│   ├── requirements.txt     # Backend dependencies
│   └── pytest.ini
├── templates/
│   ├── base.html
│   └── index.html
├── static/
│   ├── css/style.css
│   └── js/main.js
├── tests/
│   ├── test.py
│   └── test_validators.py
├── docs/
│   ├── ARCHITECTURE.md
│   ├── ENCRYPTION.md
│   ├── THREAT_MODEL.md
│   └── CHANGELOG.md
├── requirements.txt         # Root dependencies
└── index.html               # Static frontend

Requirements

  • Python 3.10 or higher
  • pip

Windows users: Do NOT use the Microsoft Store version of Python. Download the official installer from python.org and check "Add Python to PATH" during installation.


Installation

1. Clone the repository

git clone https://github.com/AlborzNazari/Secure-Apportionment-System.git
cd Secure-Apportionment-System

2. Create and activate a virtual environment

Windows (PowerShell):

python -m venv venv
venv\Scripts\activate

macOS / Linux:

python3 -m venv venv
source venv/bin/activate

3. Install dependencies

Install the root dependencies:

pip install -r requirements.txt

Install the backend dependencies:

pip install -r backend/requirements.txt

Note: The backend requirements.txt includes both Flask and FastAPI. The current application uses Flask. FastAPI and uvicorn are listed for future API development but are not required to run the app today.


Preparing Your Input CSV

The system requires a CSV file with exactly two columns: Group and Votes.

11 ready-made research scenarios are already included in the project root and embedded in the web interface dataset library — no file creation needed:

File Scenario Seats
sample_basic.csv 4-party proportional baseline 100
sample_proportional.csv EU Parliament 22-state model 705
sample_condorcet.csv Condorcet winner scenario 50
sample_arrow.csv Arrow's impossibility stress test 25
sample_runoff_round1.csv Two-round system Round 1 200
sample_runoff_round2.csv Two-round system Round 2 200
sample_strategic_voting.csv IIA violation — Green present 60
sample_strategic_voting_no_green.csv IIA baseline — Green withdrawn 60
sample_large_election.csv UK-scale 8.24M ballot test 650
sample_alabama_paradox.csv Alabama paradox — try 25 then 26 25/26
sample_coalition.csv Bundestag coalition model 598

To create your own CSV, save it with exactly this format:

Group,Votes
Party_A,50000
Party_B,30000
Party_C,15000
Party_D,5000

Windows PowerShell users: Do NOT use echo to create CSV files — it adds invisible Unicode characters that break the parser and return empty results {}. Use Notepad or run:

Set-Content -Path "sample_data.csv" -Value "Group,Votes`nParty_A,50000`nParty_B,30000`nParty_C,15000`nParty_D,5000" -Encoding UTF8

CSV rules:

  • First row must be the header: Group,Votes
  • Group names must not contain commas
  • Vote values must be whole positive numbers (no decimals)
  • Rows with invalid values are silently skipped

Running the Application

Recommended: Use Docker (Option 1) — it eliminates all environment setup, works identically on Windows, macOS, and Linux, and keeps your encryption key out of the project directory.

Option 1 — Docker (Recommended)

Prerequisites: Docker Desktop installed and running.

Step 1 — Clone and enter the project:

git clone https://github.com/AlborzNazari/Secure-Apportionment-System.git
cd Secure-Apportionment-System

Step 2 — Create your environment file:

cp .env.example .env

Then open .env and set a real encryption key. Generate one with:

python -c "import os, base64; print(base64.b64encode(os.urandom(32)).decode())"

Step 3 — Build and start:

docker-compose up --build

Step 4 — Open the web interface:

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

Upload your CSV and enter the number of seats. That's it.

Windows Desktop App (No Setup Required)

For users who want to run the system without Python, Docker, or any installation:

  1. Go to Releases
  2. Download ApportionmentSys-Windows.zip
  3. Unzip it anywhere on your machine
  4. Double-click ApportionmentSys-App.exe
  5. Select a dataset from the dropdown
  6. Enter the number of seats
  7. Click Calculate Allocation →

Results appear instantly in the output panel. Encrypted output saved to results.json.enc in the same folder. No Python, no Docker, no browser, no internet connection required.

Note: Windows Defender or antivirus software may flag the exe on first run — this is a known false positive with PyInstaller bundles. Click "More info" → "Run anyway" to proceed. The source code is fully open at the link above.

Useful Docker commands:

Command What it does
docker-compose up --build Build image and start the app
docker-compose up -d Start in background (detached)
docker-compose down Stop and remove the container
docker-compose logs -f apportionment Stream live logs
docker-compose exec apportionment bash Open a shell inside the container

Running the CLI inside Docker:

docker-compose exec apportionment python -m src.main --seats 10 sample_data.csv

Note: Log files are written to a logs/ directory mounted as a Docker volume. They persist across container restarts, which matters for audit trails on a security-critical application.


Option 2 — Command Line (CLI)

Run from the project root directory (not from inside src/ or backend/):

python -m src.main --seats 10 sample_data.csv

Arguments:

Argument Required Description
csv_file Yes Path to your CSV file
--seats Yes Total seats to allocate
--output No Output filename base (default: results.json)

Example with custom output name:

python -m src.main --seats 100 sample_data.csv --output election_results

Expected output:

Apportionment Results:
{'Party_A': 50, 'Party_B': 30, 'Party_C': 15, 'Party_D': 5}
Encrypted results saved to results.json.enc
Key saved to key.bin (keep secure!)

Output files generated:

  • results.json.enc — AES-256 encrypted results
  • key.bin — Encryption key (keep this secure; do not commit to Git)

Option 3 — Web Interface (Flask, manual)

Run from the project root:

python -m src.app

Then open your browser and go to: http://127.0.0.1:5000

Upload your CSV file through the web form and enter the total number of seats to allocate.


Running Tests

pytest tests/

Known Issues & Bugs

1. Empty results {} from CLI

If you see Apportionment Results: {}, your CSV was not parsed correctly. This is almost always caused by PowerShell adding a UTF-16 BOM or extra formatting when creating the file with echo. Use Set-Content with -Encoding UTF8 instead (see CSV section above).

2. ModuleNotFoundError: No module named 'src'

You are running the script from inside src/ or backend/. Always run from the project root:

cd Secure-Apportionment-System
python -m src.main ...

3. app.py imports allocate_seats which does not exist

src/app.py imports from src.apportionment import allocate_seats, but the actual function in apportionment.py is named huntington_hill. Running app.py will raise an ImportError. Fix by updating the import in app.py:

from src.apportionment import huntington_hill as allocate_seats

4. key.bin and results.json.enc committed to Git

These files are generated at runtime and should not be in version control. Add them to .gitignore:

key.bin
*.enc
logs/

5. Default encryption key warning

If ENCRYPTION_KEY is not set in your environment, the system uses a hardcoded default and prints a warning. For any real use, set the key in a .env file:

ENCRYPTION_KEY=your-random-secret-key-here

Docker Troubleshooting

failed to connect to the docker API at npipe

Docker Desktop is not running. Open it from the Start menu, wait for the green Running status in the bottom-left corner, then retry in a fresh PowerShell window. If it won't start, right-click → Run as administrator. If the engine still fails after 60 seconds: Docker Desktop → Settings → TroubleshootReset to factory defaults.

Changes to files not appearing in the browser

Docker caches image layers. Always use the full rebuild sequence:

docker-compose down
docker rmi secure-apportionment-v010 -f
docker-compose up --build

Then hard-refresh: Ctrl + Shift + R Verify in browser console (F12): should say ✓ Secure Apportionment System v3 loaded

ImportError: cannot import name 'allocate_seats'

In src/app.py line 4, change:

from src.apportionment import allocate_seats

to:

from src.apportionment import huntington_hill as allocate_seats

TemplateNotFound: index.html

In src/app.py, change:

app = Flask(__name__)

to:

app = Flask(__name__, template_folder='../templates', static_folder='../static')

cp not recognized on Windows

Use copy instead:

copy .env.example .env

Annotations not showing in results panel

Open F12 → Console. If it says v2 loaded the image is stale — run the full rebuild sequence above. Annotations only appear for the 11 named scenario files or when selecting a card from the dataset library. Custom CSV uploads show results without annotations by design.

Deployment Targets

Method Platform Requirements Use Case
ApportionmentSys-App.exe Windows Nothing End users, offline use
python -m src.main Any Python 3.10+ Developers, scripting
docker-compose up --build Any Docker Desktop Full web UI, localhost
Fly.io / Render Cloud Docker Public deployment (v0.2.0)
./ApportionmentSys-linux Linux Nothing Linux end users

Each deployment method is independent. The exe, Docker, and direct Python all use the same core algorithm and encryption layer.

Dependencies

Root requirements.txt

Package Version Purpose
cryptography 41.0.7 AES-256-CBC encryption
Flask 3.0.0 Web interface
pytest 7.4.3 Testing
pandas >=2.2.3 Data handling (available but not currently used in core logic)

backend/requirements.txt

Package Version Purpose
Flask 3.0.0 Web interface (active)
cryptography 41.0.7 Encryption (active)
pytest 7.4.3 Testing (active)
fastapi 0.109.0 Future REST API (not yet used)
uvicorn 0.27.0 Future ASGI server for FastAPI (not yet used)
pydantic 2.11.7 Future data validation for FastAPI (not yet used)

python-dotenv is used in backend/config.py but is not listed in either requirements.txt. Install it manually until this is fixed:

pip install python-dotenv

Security Notes

  • The key.bin file contains your AES-256 encryption key. Never commit it to a repository.
  • In production, store the encryption key as an environment variable (ENCRYPTION_KEY), not in a file.
  • Logging is configured to never record sensitive data.
  • The system is intended for development and research use. A production deployment would require additional hardening (HTTPS, key management infrastructure, authentication).

Community

Visualization & Charts

📄 Download PDF (v0.2.0)
SHA‑256: 7953a990fcb601e05ecc56832918d34e688c52271add2a525d8d7508e6878934

License

See LICENSE for details.

About

A secure apportionment system demonstrating Huntington-Hill method with AES-256 encryption.

Resources

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors