No description
  • Python 50.1%
  • JavaScript 23.1%
  • CSS 14.4%
  • HTML 10.4%
  • Shell 1.9%
  • Other 0.1%
Find a file
2026-05-10 13:59:33 +02:00
backend fix : settings and stats 2026-05-10 13:59:33 +02:00
cli fix : cli commands 2026-05-03 11:17:13 +02:00
completions Initial commit 2026-03-24 19:26:29 +00:00
frontend - fix : updater 2026-05-03 10:32:16 +02:00
.gitignore -remove .qwen/ 2026-04-03 11:59:37 +02:00
ChangeLog - add : Update button on setting pop-up 2026-04-13 13:07:19 +02:00
cli.py -updater updated 2026-04-03 11:58:28 +02:00
CLI_README.md - line added 2026-03-29 10:32:09 +02:00
install.sh - 2026-05-03 10:03:21 +02:00
README.md - add : Update button on setting pop-up 2026-04-13 13:07:19 +02:00
requirements.txt -light 2026-04-02 21:23:44 +02:00
V2.4.4 Update V2.4.4 2026-05-03 11:43:52 +02:00
wis.aleksi.systems.har - lighter everything 2026-04-02 21:08:42 +02:00

What I Spend

A modern, self-hosted personal expense tracking application with a beautiful interface, powerful analytics, and multi-user data sharing capabilities.

Version Python FastAPI License


Table of Contents


Features

💰 Expense Management

  • Add, edit, and delete expenses with descriptions
  • Categorize expenses with nested subcategories
  • Track payment methods (Cash, Card, Transfer, etc.)
  • Filter by month and export to CSV or Excel (XLSX)
  • Category is required for expenses; subcategory remains optional

📊 Analytics Dashboard

  • Total spent for the month
  • Transaction count and average per transaction
  • Highest expense tracking
  • Daily evolution chart (line graph)
  • Category distribution (pie chart)
  • Weekly comparison (bar chart)
  • Payment method breakdown (horizontal bar chart)
  • Top 5 expenses list

🔗 Multi-User Data Sharing

  • Link user accounts without merging them
  • Share expenses, categories, and payment methods between linked accounts
  • Each account remains independent with its own credentials
  • Link and unlink accounts at any time
  • Perfect for couples or roommates tracking shared expenses

🌍 Geolocation

  • Automatic GPS capture for expense locations
  • Suggestions based on frequently visited places
  • Smart location-based expense tracking

🌙 Dark Mode

  • Full dark mode support with toggle in settings
  • Persistent theme preference across sessions

🔒 Security

  • Argon2id password hashing
  • Session-based authentication
  • Rate limiting (configurable, default 50 req/s)
  • Optional French IP filtering (GeoIP)
  • API key protection for all endpoints

🔄 Automatic Updates

In-App Update System

  • One-click update from Settings menu
  • No CLI required - updates directly from the web interface
  • Automatic backup before any changes
  • Real-time progress visualization
  • Automatic rollback on failure
  • Server restart after successful update

🎨 Modern UI

  • Clean, professional design with Indigo/Violet theme
  • Fully responsive (mobile, tablet, desktop)
  • Interactive charts powered by Chart.js
  • Toast notifications and modal dialogs
  • Smooth animations and transitions
  • Interactive setup wizard for first-time users

Quick Start

# Clone or navigate to the project
cd WhatISpend

# Run the automated installation
sudo ./install.sh

The installation script will:

  • Create a Python virtual environment
  • Install all dependencies
  • Generate an API key
  • Initialize the database
  • Start the server with a setup wizard

Access the application: http://localhost:3000


Installation

Prerequisites

  • Python 3.10+
  • pip (Python package manager)
  • Linux/macOS (Ubuntu/Debian recommended)

Manual Installation

  1. Create virtual environment

    python3 -m venv venv
    source venv/bin/activate
    
  2. Install dependencies

    pip install -r requirements.txt
    
  3. Generate API key

    python3 -c "import secrets; print(secrets.token_hex(16))"
    
  4. Configure the application

    Create a config.env file at the project root:

    # Expense Tracker Configuration
    
    # API Keys (generate with the command above)
    API_KEY=your_api_key_here
    API_KEY_SALT=your_salt_secret_here
    
    # Server Configuration
    HOST=0.0.0.0
    PORT=3000
    
    # Session Configuration (in hours)
    SESSION_DURATION=24
    
    # Rate Limiting (requests per second)
    RATE_LIMIT=50
    
    # GeoIP (optional)
    GEOIP_ENABLED=false
    GEOIP_LICENSE_KEY=
    
  5. Initialize data directory

    mkdir -p data
    echo '{}' > data/users.json
    echo '{}' > data/expenses.json
    echo '{}' > data/categories.json
    echo '{}' > data/payment_methods.json
    
  6. Create an admin user

    python cli.py user create --username admin --password your_secure_password
    
  7. Start the server

    uvicorn backend.main:app --host 0.0.0.0 --port 3000
    
  8. Access the application

    • Open your browser to: http://localhost:3000
    • Login with your credentials

Configuration

Edit config.env to customize your installation:

Variable Description Default Required
API_KEY API authentication key (generated)
API_KEY_SALT Salt for user API keys (generated)
HOST Server bind address 0.0.0.0
PORT Server port 3000
SESSION_DURATION Session lifetime (hours) 24
RATE_LIMIT Requests per second 50
GEOIP_ENABLED Enable French IP filtering false
GEOIP_LICENSE_KEY MaxMind GeoIP license -

Usage

First Login

  1. Navigate to http://localhost:3000
  2. Enter your username and password
  3. You'll be redirected to the Dashboard

Dashboard

The main dashboard displays:

  • Key Metrics: Total spent, transaction count, average, highest expense
  • Charts: Daily evolution, category distribution, weekly comparison, payment methods
  • Top Expenses: Your 5 largest expenses for the month

Managing Expenses

  1. Go to the Expenses page
  2. Click Add Expense to create a new entry
  3. Fill in amount, date, category, payment method, and optional description
  4. Optionally add GPS coordinates for location tracking
  5. Edit or delete existing expenses as needed
  6. Use the month filter to view different periods
  7. Export to CSV or Excel for external analysis

Managing Categories

  1. Go to the Categories page
  2. Create parent categories and subcategories
  3. Edit or delete categories (deletion requires no associated expenses)

Managing Payment Methods

  1. Go to the Payment Methods page
  2. Create custom payment methods (Cash, Card, etc.)
  3. Edit or delete as needed

Multi-User Data Sharing

What I Spend supports linking user accounts to share data while keeping accounts independent.

Linking Users

# Link two user accounts
python cli.py user link --user1 username1 --user2 username2

# Unlink accounts
python cli.py user unlink --user1 username1 --user2 username2

How It Works

  • Shared Data: Expenses, categories, and payment methods are shared between linked accounts
  • Independent Accounts: Each user maintains their own login credentials and preferences
  • Flexible: Link and unlink accounts at any time without data loss
  • Storage: Links are stored in data/user_links.json

Use Cases

  • Couples: Track shared household expenses while maintaining individual accounts
  • Roommates: Share rent and utility expenses without merging accounts
  • Family: Parents and children can share certain expense categories

API Reference

All API endpoints require the API key as a query parameter: ?key=YOUR_API_KEY

Authentication

Endpoint Method Description
/sysapi/login POST Login (form: username, password)
/sysapi/logout POST Logout
/sysapi/session GET Check session validity

Expenses

Endpoint Method Description
/sysapi/expenses GET List expenses (?month=YYYY-MM)
/sysapi/expense_create POST Create expense
/sysapi/expense_update POST Update expense
/sysapi/expense_delete POST Delete expense

Categories

Endpoint Method Description
/sysapi/categories GET List categories (nested)
/sysapi/categories_flat GET List all categories (flat)
/sysapi/category_create POST Create category
/sysapi/category_update POST Update category
/sysapi/category_delete POST Delete category

Payment Methods

Endpoint Method Description
/sysapi/payment_methods GET List payment methods
/sysapi/payment_method_create POST Create payment method
/sysapi/payment_method_update POST Update payment method
/sysapi/payment_method_delete POST Delete payment method

Statistics

Endpoint Method Description
/sysapi/dashboard-data GET All dashboard statistics in one call
/sysapi/stats GET Monthly statistics
/sysapi/daily_evolution GET Daily evolution data
/sysapi/category_distribution GET Category distribution
/sysapi/weekly_comparison GET Weekly comparison
/sysapi/payment_method_stats GET Payment method statistics
/sysapi/top_expenses GET Top expenses (?limit=5)
/sysapi/export_csv GET Export expenses as CSV

Update

Endpoint Method Description
/sysapi/update/check GET Check for available updates
/sysapi/update/execute POST Execute update process
/sysapi/update/status GET Get current update status

User Management

Endpoint Method Description
/sysapi/users GET List all users
/sysapi/users/link POST Link two user accounts
/sysapi/users/unlink POST Unlink two user accounts
/sysapi/users/linked GET Get linked users for current user

Example API Calls

# Get expenses for January 2026
curl "http://localhost:3000/sysapi/expenses?month=2026-01&key=YOUR_API_KEY"

# Create an expense
curl -X POST "http://localhost:3000/sysapi/expense_create?key=YOUR_API_KEY" \
  -d "amount=50.00&date=2026-01-15&category_id=1&payment_method_id=1&description=Groceries"

# Get all dashboard data in a single call
curl "http://localhost:3000/sysapi/dashboard-data?month=2026-01&key=YOUR_API_KEY"

# Link two user accounts
curl -X POST "http://localhost:3000/sysapi/users/link?key=YOUR_API_KEY" \
  -d "user1=john&user2=jane"

Project Structure

WhatISpend/
├── backend/
│   ├── main.py                 # FastAPI application entry point
│   ├── config.py               # Configuration management
│   ├── security.py             # Rate limiting, auth middleware
│   ├── storage.py              # JSON file storage management
│   ├── models.py               # Pydantic data models
│   ├── geolocation.py          # GeoIP filtering (optional)
│   ├── excel_generator.py      # Excel export functionality
│   ├── update_manager.py       # Update process management
│   └── routes/
│       ├── auth.py             # Authentication routes
│       ├── expenses.py         # Expense CRUD operations
│       ├── categories.py       # Category management
│       ├── payment_methods.py  # Payment method management
│       ├── stats.py            # Statistics and analytics
│       └── update.py           # Update API endpoints
├── frontend/
│   ├── index.html              # Main application HTML
│   ├── setup.html              # Setup wizard page
│   ├── app.js                  # Frontend application logic
│   ├── setup.js                # Setup wizard JavaScript
│   ├── styles.css              # Application styles
│   ├── setup.css               # Setup wizard styles
│   └── favicon.*               # Application icons
├── cli/
│   ├── __init__.py
│   ├── commands/
│   │   ├── user.py             # User management commands
│   │   ├── server.py           # Server control commands
│   │   ├── backup.py           # Backup commands
│   │   ├── logs.py             # Log viewing commands
│   │   ├── update.py           # Update command
│   │   └── interactive.py      # Interactive mode
│   └── utils/
│       └── display.py          # CLI display utilities
├── scripts/
│   ├── create_user.py          # User creation utility
│   ├── delete_user.py          # User deletion utility
│   ├── link_users.py           # User linking utility
│   └── watchdog.py             # Monitoring utility
├── data/                       # JSON data storage
│   ├── users.json              # User accounts
│   ├── expenses.json           # Expense records
│   ├── categories.json         # Category definitions
│   ├── payment_methods.json    # Payment method definitions
│   ├── user_links.json         # User link relationships
│   └── update_status.json      # Current update status
├── backups/                    # Automatic backup storage
├── cli.py                      # Main CLI entry point
├── install.sh                  # Automated installation script
├── requirements.txt            # Python dependencies
├── config.env                  # Application configuration (auto-generated)
├── .gitignore                  # Git ignore rules
├── ChangeLog                   # Version history
├── V2.4.1                      # Current version file
└── README.md                   # This file

Security

API Key Authentication

  • 32-character hexadecimal key generated on installation
  • Required on all /sysapi/* endpoints
  • Stored securely in config.env

Password Security

  • Argon2id hashing (winner of the Password Hashing Competition)
  • Automatic salt generation per user
  • Parameters: m=65536, t=3, p=4 (recommended secure defaults)

Rate Limiting

  • Default: 50 requests per second per IP
  • Configurable via RATE_LIMIT in config.env
  • Returns HTTP 429 when exceeded

GeoIP Filtering (Optional)

  • Restrict access to French IP addresses only
  • Requires MaxMind GeoIP license key
  • Enable via GEOIP_ENABLED=true

Session Management

  • 24-hour session duration (configurable)
  • Secure cookie-based sessions
  • Automatic expiration and cleanup

Production Recommendations

  1. Use HTTPS: Deploy behind Nginx/Apache with SSL
  2. Firewall: Restrict access to trusted IPs
  3. Regular Backups: Use python cli.py backup create regularly
  4. Strong Passwords: Use complex passwords for admin accounts
  5. Update Dependencies: Keep requirements.txt up to date
  6. Enable GeoIP: If you want to restrict access to specific regions

Data Management

Storage Format

Data is stored in JSON files in the data/ directory:

users.json:

{
  "admin": {
    "username": "admin",
    "password_hash": "$argon2id$v=19$m=65536,t=3,p=4$...",
    "created_at": "2026-03-21T10:00:00Z"
  }
}

expenses.json:

{
  "1": {
    "id": 1,
    "user": "admin",
    "amount": 45.50,
    "date": "2026-03-21",
    "category_id": 1,
    "payment_method_id": 1,
    "description": "Groceries",
    "created_at": "2026-03-21T10:30:00Z"
  }
}

Backup

# Create a backup
python cli.py backup create -o my-backup

# List backups
python cli.py backup list

# Restore from backup
python cli.py backup restore --file backup-20260403.tar.gz

User Management

Create a user:

python cli.py user create --username <username> --password <password>

List users:

python cli.py user list

Link users:

python cli.py user link --user1 <username1> --user2 <username2>

Unlink users:

python cli.py user unlink --user1 <username1> --user2 <username2>

Delete a user:

python cli.py user delete --username <username> [--delete-data]

CLI (Command Line Interface)

A beautiful and intuitive CLI for managing your Expense Tracker application.

Quick Start

cd WhatISpend
source venv/bin/activate
python cli.py --help

Usage Modes

Interactive Mode (Recommended):

python cli.py interactive
# or
python cli.py -i

# Then type commands:
expense-tracker> user create
expense-tracker> server start --background
expense-tracker> status
expense-tracker> exit

Direct Command Mode:

python cli.py status
python cli.py user create --username john
python cli.py server start --background
python cli.py backup create -o monthly-backup
python cli.py update

Main Commands

Command Description
status Show application status
user create Create a new user
user list List all users
user link Link two user accounts
user unlink Unlink two user accounts
server start Start the server
server stop Stop the server
server restart Restart the server
backup create Create a backup
backup list List available backups
backup restore Restore from backup
logs show View logs
update Update application to latest version

Interactive Mode Shortcuts

  • u = user
  • srv = server
  • bkp = backup
  • h = help
  • q = quit

For complete CLI documentation, see CLI_README.md.


Troubleshooting

Server won't start

  1. Check if port is in use:

    sudo lsof -i :3000
    
  2. Check logs:

    python cli.py logs show
    
  3. Verify configuration:

    cat config.env
    

Can't login

  1. Verify user exists:

    python cli.py user list
    
  2. Reset password:

    python cli.py user delete --username <username>
    python cli.py user create --username <username> --password <new_password>
    

API key errors

  1. Check API key in config.env:

    grep API_KEY config.env
    
  2. Regenerate if needed:

    python3 -c "import secrets; print(secrets.token_hex(16))"
    # Update config.env with new key
    

GeoIP issues

  1. Disable GeoIP if causing problems:
    # In config.env
    GEOIP_ENABLED=false
    
    Then restart the server.

CSS/JavaScript issues

  • The application uses non-minified source files for easier debugging
  • Browser cache is disabled for assets to ensure fresh content
  • If styles appear broken, try a hard refresh (Ctrl+Shift+R / Cmd+Shift+R)

Development

Dependencies

fastapi>=0.104.0          # Web framework
uvicorn[standard]>=0.24.0 # ASGI server
pydantic>=2.0.0           # Data validation
argon2-cffi>=23.1.0       # Password hashing
python-multipart>=0.0.6   # Form data parsing
slowapi>=0.1.9            # Rate limiting
geoip2>=4.7.0             # GeoIP filtering
python-jose[cryptography]>=3.3.0  # JWT/Cryptography
passlib>=1.7.4            # Password utilities
rich>=13.0.0              # CLI formatting
click>=8.0.0              # CLI framework
openpyxl>=3.1.0           # Excel export
psutil>=5.9.0             # Process management

Performance Optimizations

  • Dashboard API: Consolidated from 9 calls to 1 (/dashboard-data)
  • GZip Compression: Enabled for responses > 1KB (20-30% size reduction)
  • Non-minified Assets: Source CSS/JS used directly for easier debugging
Metric Before After Gain
Dashboard API calls 9 1 -89%
Initial load time ~2-3s ~1-1.5s -50%
HTML size (compressed) 52 KB 40 KB -23%

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests
  5. Submit a pull request

License

MIT License - See LICENSE file for details.


Support

For issues, questions, or contributions:

  • Check existing documentation
  • Review the code in backend/ and frontend/ directories
  • Open an issue on the repository

Version History

See ChangeLog for detailed release notes.

Version Date Highlights
2.4.1 April 2026 Web update system, Leaflet map fix
2.4 April 2026 User linking, CLI update restart, category validation
2.3.4 April 2026 Dashboard API optimization, GZip compression, shared categories
2.3 March 2026 CLI update command with automatic backup
2.2.1 March 2026 Project cleanup and documentation
2.2 March 2026 GPS coordinate fixes, setup page CSS
2.1 March 2026 Geolocation, dark mode, payment filters
2.0 Feb. 2026 FastAPI migration, subcategories, new charts
1.1 Jan. 2026 Custom payment methods, CSV export
1.0 Dec. 2025 Initial stable release