DEV Community

Brad
Brad

Posted on

Python Expense Tracker: Auto-Categorize Receipts and Export to QuickBooks

Manual expense tracking wastes hours every month. Here's how to build an automated expense tracker that categorizes receipts and exports to QuickBooks-compatible CSV.

Auto-Categorize Expenses

import sqlite3
from pathlib import Path

CATEGORIES = {
    "office": ["amazon", "staples", "office depot"],
    "software": ["aws", "github", "digitalocean"],
    "travel": ["uber", "lyft", "airbnb"],
    "meals": ["grubhub", "doordash", "restaurant"],
}

def categorize(description: str) -> str:
    desc_lower = description.lower()
    for category, keywords in CATEGORIES.items():
        if any(kw in desc_lower for kw in keywords):
            return category
    return "other"

def add_expense(amount: float, description: str, date: str):
    category = categorize(description)
    conn = sqlite3.connect("expenses.db")
    conn.execute(
        "INSERT INTO expenses (amount, description, category, date) VALUES (?, ?, ?, ?)",
        (amount, description, category, date)
    )
    conn.commit()
    print(f"Added: ${amount:.2f} - {description} [{category}]")
Enter fullscreen mode Exit fullscreen mode

Export to QuickBooks CSV

import csv

def export_quickbooks_csv(output_file: str = 'quickbooks_import.csv'):
    conn = sqlite3.connect("expenses.db")
    rows = conn.execute(
        "SELECT date, description, amount, category FROM expenses ORDER BY date"
    ).fetchall()

    with open(output_file, "w", newline="") as f:
        writer = csv.writer(f)
        writer.writerow(["Date", "Description", "Amount", "Account"])
        for date, desc, amount, category in rows:
            writer.writerow([date, desc, f"-{amount:.2f}", category.title()])
    print(f"Exported {len(rows)} expenses to {output_file}")
Enter fullscreen mode Exit fullscreen mode

Monthly Summary Report

from datetime import datetime

def monthly_summary():
    conn = sqlite3.connect("expenses.db")
    month = datetime.now().strftime("%Y-%m")
    rows = conn.execute(
        "SELECT category, SUM(amount) FROM expenses WHERE date LIKE ? GROUP BY category",
        (f"{month}%",)
    ).fetchall()
    total = sum(r[1] for r in rows)
    print(f"=== {month} Expenses: ${total:.2f} ===")
    for category, amount in rows:
        print(f"  {category}: ${amount:.2f}")
Enter fullscreen mode Exit fullscreen mode

Parse Email Receipts Automatically

import imaplib
import email
import re

def parse_receipts_from_email(username: str, password: str):
    mail = imaplib.IMAP4_SSL("imap.gmail.com")
    mail.login(username, password)
    mail.select("inbox")
    _, msgs = mail.search(None, '(SUBJECT "receipt")')
    for num in msgs[0].split():
        _, data = mail.fetch(num, "(RFC822)")
        msg = email.message_from_bytes(data[0][1])
        subject = msg["Subject"] or ""
        amount_match = re.search(r"\$(\d+\.\d{2})", subject)
        if amount_match:
            amount = float(amount_match.group(1))
            from datetime import datetime
            add_expense(amount, subject, datetime.now().strftime("%Y-%m-%d"))
Enter fullscreen mode Exit fullscreen mode

Full Automation

This is just one script from the Python Business Automation Toolkit - which includes expense tracking, CRM, invoice automation, time tracking, and 50+ more scripts. $29 one-time, no subscription.

What expenses do you track manually that you wish were automated? Let me know in the comments.

Top comments (0)