A full-stack web application for tracking personal income and expenses, built with Python and Flask. Features secure user authentication, budget monitoring, financial analytics, recurring transactions, and CSV/PDF reporting.
- Authentication — Register/login with bcrypt-hashed passwords, CSRF protection, and automatic account lockout after 5 failed attempts (15-minute cooldown)
- Transactions — Log income and expenses with date, category, and notes
- Categories — Create custom income/expense categories with optional monthly budget limits; archive categories without losing history
- Recurring Templates — Define monthly repeating transactions (e.g. rent, salary) and generate them in one click
- Dashboard & Insights — Live KPIs including savings rate, average daily spend, highest spending category, and month-on-month comparison with trend chart
- Overspending Alerts — Automated alerts when a category exceeds its budget, spending spikes >20% month-on-month, or monthly expenses exceed income
- Reports — Filter transactions by date range and export to CSV or PDF
- CSV Import — Two-phase import wizard: preview shows valid rows, errors, and duplicates before committing; all-or-nothing database transaction prevents partial imports
- Security — Session hardening (HttpOnly, SameSite, 30-min idle expiry), DECIMAL storage for exact financial arithmetic, and a full security test suite
| Layer | Technology |
|---|---|
| Backend | Python 3, Flask, Flask-SQLAlchemy |
| Database | SQLite (via SQLAlchemy ORM) |
| Auth | Flask-Login, Flask-Bcrypt |
| Forms / CSRF | Flask-WTF, WTForms |
| PDF Export | ReportLab |
| Frontend | Jinja2 templates, Vanilla JS, CSS |
| Testing | pytest, pytest-flask, coverage |
budget_tracker/
├── app/
│ ├── auth/ # Registration, login, logout
│ ├── transactions/ # CRUD for income/expense records
│ ├── categories/ # User-defined category management
│ ├── recurring/ # Monthly recurring transaction templates
│ ├── reports/ # Report generation + CSV/PDF export
│ ├── imports/ # Two-phase CSV import wizard
│ ├── account/ # Profile settings
│ ├── templates/ # Jinja2 HTML templates
│ ├── static/ # CSS, JS, images
│ ├── models.py # SQLAlchemy models (User, Transaction, Category, RecurringTemplate)
│ └── __init__.py # Application factory
├── tests/ # pytest test suite (auth, transactions, reports, imports, security)
├── config.py # App config + TestingConfig
├── run.py # Entry point
├── seed_data.py # Sample data for development
└── requirements.txt
- Python 3.10+
- pip
# 1. Clone the repository
git clone https://github.com/YOUR_USERNAME/budget-tracker.git
cd budget-tracker
# 2. Create and activate a virtual environment
python -m venv venv
# Windows
venv\Scripts\activate
# macOS / Linux
source venv/bin/activate
# 3. Install dependencies
pip install -r requirements.txt
# 4. (Optional) Load sample data
python seed_data.py
# 5. Run the app
python run.pyOpen http://127.0.0.1:5000 in your browser.
pytest tests/ -vTo view coverage:
coverage run -m pytest tests/
coverage report- Application Factory Pattern —
create_app()in__init__.pymakes the app testable: each pytest run gets a fresh in-memory SQLite database with no side effects. - DECIMAL over FLOAT — All monetary amounts use
Numeric(10, 2)in SQLAlchemy to avoid IEEE-754 floating-point rounding errors. - Brute-Force Protection — Login failures are counted per user and stored in the database; after the threshold the account is locked for a configurable window.
- Two-Phase CSV Import — The import wizard separates parsing/validation from committing, so users can review row-level errors and duplicates before any data is written.
- No Background Scheduler — Recurring transactions are generated on demand rather than via a cron job, keeping the architecture simple and eliminating scheduler drift.
Run the app with
python seed_data.py && python run.pyto see a pre-populated demo.
MIT