Python Time Tracker + Auto-Billing Script (Bye Toggl!)
I cancelled my Toggl subscription last year and replaced it with 50 lines of Python. Here's the exact script, and how I extended it to auto-generate billing reports.
Why Toggl Isn't Worth $10/Month
Toggl is great software. But for solo freelancers, it's massive overkill. The core feature I needed:
- Start/stop timer
- Assign time to a client project
- See total hours per week/month
- Calculate billing amounts
That's 4 features. $10/month. Let's build it.
The Core Time Tracker
import sqlite3
import time
from datetime import datetime, date
from pathlib import Path
DB_PATH = Path.home() / ".time_tracker.db"
def init_db():
conn = sqlite3.connect(DB_PATH)
conn.execute("""
CREATE TABLE IF NOT EXISTS time_entries (
id INTEGER PRIMARY KEY,
project TEXT NOT NULL,
description TEXT,
start_time REAL NOT NULL,
end_time REAL,
duration_hours REAL,
rate REAL DEFAULT 75
)
""")
conn.commit()
return conn
def start_timer(project, description="", rate=75):
"""Start tracking time for a project."""
conn = init_db()
start = time.time()
conn.execute(
"INSERT INTO time_entries (project, description, start_time, rate) VALUES (?, ?, ?, ?)",
(project, description, start, rate)
)
conn.commit()
entry_id = conn.execute("SELECT last_insert_rowid()").fetchone()[0]
print(f"⏱ Timer started: {project} | ID: {entry_id}")
return entry_id
def stop_timer(entry_id):
"""Stop timer and calculate duration."""
conn = init_db()
end = time.time()
start = conn.execute("SELECT start_time, rate FROM time_entries WHERE id=?",
(entry_id,)).fetchone()
if not start:
print(f"Entry {entry_id} not found")
return
duration = (end - start[0]) / 3600 # Convert to hours
conn.execute(
"UPDATE time_entries SET end_time=?, duration_hours=? WHERE id=?",
(end, duration, entry_id)
)
conn.commit()
print(f"✅ Stopped | Duration: {duration:.2f}h | Amount: ${duration * start[1]:.2f}")
return duration
Auto-Billing Report Generator
def generate_billing_report(client=None, month=None):
"""Generate a billing summary report."""
conn = init_db()
query = "SELECT project, description, duration_hours, rate FROM time_entries WHERE end_time IS NOT NULL"
params = []
if client:
query += " AND project=?"
params.append(client)
if month:
# Filter by month
month_start = datetime(datetime.now().year, month, 1).timestamp()
query += " AND start_time >= ?"
params.append(month_start)
entries = conn.execute(query, params).fetchall()
if not entries:
print("No entries found")
return
print(f"{'Project':<20} {'Description':<30} {'Hours':>6} {'Rate':>6} {'Amount':>10}")
print("-" * 75)
total_hours = 0
total_amount = 0
for project, desc, hours, rate in entries:
amount = (hours or 0) * rate
total_hours += (hours or 0)
total_amount += amount
print(f"{project:<20} {(desc or ''):<30} {(hours or 0):>6.2f} ${rate:>5} ${amount:>9.2f}")
print("-" * 75)
print(f"{'TOTAL':<52} {total_hours:>6.2f} {'':>6} ${total_amount:>9.2f}")
return total_hours, total_amount
# Quick usage
entry_id = start_timer("Acme Corp", "API integration", rate=80)
# ... do your work ...
stop_timer(entry_id)
# Monthly report
generate_billing_report(client="Acme Corp", month=5)
Usage Pattern
My typical workflow:
# Morning: start tracking
python tracker.py start "Acme Corp" "Sprint planning" --rate 80
# End of day: stop and review
python tracker.py stop 42
python tracker.py report --month 5
# Invoice time
python tracker.py invoice --client "Acme Corp" --month 5
Extending It
I added these integrations over time:
- Auto-generate PDF invoices from tracked hours
- Export CSV for accountants
- Weekly summary email to myself
- Slack notifications for started/stopped timers
The Complete Freelancer Toolkit
This time tracker is one of 5 scripts I built to replace my SaaS stack:
- Time Tracker — this one (replaces Toggl $10/mo)
- Invoice Generator — generates PDFs + emails them (replaces Freshbooks $15/mo)
- Email Campaign Tool — client newsletters (replaces Mailchimp $20/mo)
- Proposal Generator — professional proposals (replaces Proposify $49/mo)
- Revenue Dashboard — monthly P&L overview
Total: ~$400/yr saved
All 5 scripts are available as a toolkit: Python Business Automation Toolkit — $9 one-time. Includes full source code, docs, and SQLite DB setup.
What tool would you build next? I'm thinking about a CRM replacement — track clients, notes, follow-ups — all in a local SQLite DB.
Top comments (0)