DEV Community

Otto
Otto

Posted on

5 Automation Scripts That Run My Freelance Business on Autopilot (Python, Open Source)

I run my freelance business with 5 Python scripts that handle the boring stuff automatically.

Here's exactly what they do and how to build them.

Why Automation Matters for Freelancers

As a freelancer, your time is your product. Every hour spent on admin, follow-ups, or manual tracking is an hour not spent on billable work.

These 5 scripts collectively save ~8 hours/week.

Script 1: Invoice Generator

Generates professional PDF invoices from a simple JSON config.

import json
from datetime import datetime

def generate_invoice(client_data, items):
    invoice = {
        'invoice_number': f"INV-{datetime.now().strftime('%Y%m%d-%H%M')}",
        'date': datetime.now().strftime('%d/%m/%Y'),
        'client': client_data,
        'items': items,
        'total': sum(item['quantity'] * item['unit_price'] for item in items),
        'vat': sum(item['quantity'] * item['unit_price'] for item in items) * 0.20
    }
    return invoice

# Usage
client = {'name': 'Acme Corp', 'email': 'billing@acme.com', 'address': 'Paris, France'}
items = [
    {'description': 'Web development - Phase 1', 'quantity': 20, 'unit_price': 75},
    {'description': 'Code review', 'quantity': 3, 'unit_price': 50}
]

invoice = generate_invoice(client, items)
print(f"Invoice {invoice['invoice_number']}: €{invoice['total']} + TVA €{invoice['vat']:.2f}")
Enter fullscreen mode Exit fullscreen mode

Time saved: 20-30 minutes per invoice

Script 2: Client Follow-Up Tracker

Tracks when to follow up with prospects and alerts when action is needed.

import json
from datetime import datetime, timedelta

def check_followups(clients_file='clients.json'):
    with open(clients_file) as f:
        clients = json.load(f)

    today = datetime.now().date()
    due_followups = []

    for client in clients:
        last_contact = datetime.strptime(client['last_contact'], '%Y-%m-%d').date()
        followup_days = client.get('followup_days', 7)
        due_date = last_contact + timedelta(days=followup_days)

        if due_date <= today:
            days_overdue = (today - due_date).days
            due_followups.append({
                'name': client['name'],
                'days_overdue': days_overdue,
                'context': client.get('last_note', '')
            })

    return sorted(due_followups, key=lambda x: x['days_overdue'], reverse=True)

# Run daily via cron
followups = check_followups()
for f in followups:
    print(f"⚠️  {f['name']}{f['days_overdue']} days overdue — {f['context']}")
Enter fullscreen mode Exit fullscreen mode

Time saved: 1-2 hours/week (no more lost leads)

Script 3: Time Tracker & Revenue Calculator

Logs hours and calculates actual hourly rate vs target.

import json
from datetime import datetime

class TimeTracker:
    def __init__(self, log_file='time_log.json'):
        self.log_file = log_file
        self.entries = self._load()

    def _load(self):
        try:
            with open(self.log_file) as f:
                return json.load(f)
        except:
            return []

    def log_session(self, project, hours, amount_eur):
        entry = {
            'date': datetime.now().strftime('%Y-%m-%d'),
            'project': project,
            'hours': hours,
            'amount': amount_eur,
            'effective_rate': amount_eur / hours if hours > 0 else 0
        }
        self.entries.append(entry)
        with open(self.log_file, 'w') as f:
            json.dump(self.entries, f, indent=2)
        return entry

    def monthly_summary(self, month=None):
        month = month or datetime.now().strftime('%Y-%m')
        month_entries = [e for e in self.entries if e['date'].startswith(month)]

        total_hours = sum(e['hours'] for e in month_entries)
        total_revenue = sum(e['amount'] for e in month_entries)
        avg_rate = total_revenue / total_hours if total_hours > 0 else 0

        return {
            'month': month,
            'hours': total_hours,
            'revenue': total_revenue,
            'avg_rate': round(avg_rate, 2)
        }

# Usage
tracker = TimeTracker()
tracker.log_session('Client A - Feature Build', 8, 600)
summary = tracker.monthly_summary()
print(f"March: {summary['hours']}h | €{summary['revenue']} | €{summary['avg_rate']}/hr avg")
Enter fullscreen mode Exit fullscreen mode

Time saved: 30 min/week + better rate negotiation

Script 4: Proposal Generator

Generates customized proposals from templates.

def generate_proposal(template_file, client_vars):
    with open(template_file) as f:
        template = f.read()

    for key, value in client_vars.items():
        template = template.replace(f'{{{{{key}}}}}', str(value))

    output_file = f"proposal_{client_vars['client_name'].replace(' ', '_')}.md"
    with open(output_file, 'w') as f:
        f.write(template)

    return output_file

# Usage
client_vars = {
    'client_name': 'StartupXYZ',
    'project_type': 'MVP Development',
    'budget': '€5,000',
    'timeline': '6 weeks',
    'deliverables': 'Working web application + documentation'
}

output = generate_proposal('proposal_template.md', client_vars)
print(f"Proposal generated: {output}")
Enter fullscreen mode Exit fullscreen mode

Time saved: 45 min per proposal

Script 5: Weekly Revenue Report

Automatically pulls data from multiple sources and generates a weekly summary.

import json
from datetime import datetime, timedelta

def weekly_report(gumroad_sales, time_log_file):
    # Calculate week boundaries
    today = datetime.now()
    week_start = today - timedelta(days=today.weekday())

    # Digital product revenue
    digital_revenue = sum(
        sale['price'] for sale in gumroad_sales
        if datetime.strptime(sale['created_at'][:10], '%Y-%m-%d') >= week_start
    )

    # Service revenue from time log
    with open(time_log_file) as f:
        time_entries = json.load(f)

    service_revenue = sum(
        entry['amount'] for entry in time_entries
        if datetime.strptime(entry['date'], '%Y-%m-%d') >= week_start
    )

    print(f"\n📊 Weekly Report — Week of {week_start.strftime('%d %b %Y')}")
    print(f"   Digital products: €{digital_revenue:.2f}")
    print(f"   Services: €{service_revenue:.2f}")
    print(f"   Total: €{digital_revenue + service_revenue:.2f}")

Enter fullscreen mode Exit fullscreen mode

Time saved: 1 hour/week on reporting

The Full System

These 5 scripts, running on a simple cron schedule, handle:

  • Invoice creation (on demand)
  • Client follow-up reminders (daily at 9am)
  • Time tracking (after each session)
  • Proposal generation (on demand)
  • Weekly revenue reporting (Monday 8am)

Total setup time: ~4 hours. Ongoing maintenance: near zero.

Where to Get These Scripts

I've packaged a ready-to-use version of these scripts with documentation, examples, and Notion integration in the Invoice Generator Pro on Gumroad (€14.99).

If you want the full operational system — time tracking, client management, finance dashboard — the Freelancer OS Notion Template (€19) covers the non-code side.

Conclusion

Automation isn't about replacing your work — it's about removing the friction from your most repetitive tasks.

8 hours saved per week = 32 hours per month = almost a full extra week of billable time.

Start with the invoice generator. It pays for itself after one invoice.


Have a specific automation challenge in your freelance business? Comment below.

Top comments (0)