10 Python Automation Scripts I Use Every Week (with full code)
Every developer eventually builds up a folder of "that script I wrote once and keep reusing." Here are the 10 I reach for most, cleaned up and ready to drop into any project.
All standalone, under 100 lines each, minimal dependencies.
1. Bulk File Renamer
Rename hundreds of files using regex patterns in one pass. Photos, log files, build artifacts — all handled.
import re, pathlib
def bulk_rename(directory, pattern, replacement, dry_run=True):
path = pathlib.Path(directory)
renamed = []
for f in path.iterdir():
if f.is_file():
new_name = re.sub(pattern, replacement, f.name)
if new_name != f.name:
if not dry_run:
f.rename(f.parent / new_name)
renamed.append((f.name, new_name))
return renamed
Always run with dry_run=True first.
2. CSV / Excel Merger
Combines many spreadsheets with smart column matching — handles mismatched column orders and gaps.
import pandas as pd, glob
def merge_spreadsheets(directory, output_file):
files = glob.glob(f"{directory}/*.csv") + glob.glob(f"{directory}/*.xlsx")
dfs = []
for f in files:
df = pd.read_csv(f) if f.endswith('.csv') else pd.read_excel(f)
dfs.append(df)
merged = pd.concat(dfs, ignore_index=True, sort=False)
merged.to_csv(output_file, index=False)
return len(merged)
3. Email Sender with Attachments
Programmatic email via Gmail SMTP. HTML body, multiple attachments, all handled.
import smtplib, os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
def send_email(sender, password, recipient, subject, body, attachments=[]):
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = recipient
msg['Subject'] = subject
msg.attach(MIMEText(body, 'html'))
for fp in attachments:
with open(fp, 'rb') as f:
part = MIMEBase('application', 'octet-stream')
part.set_payload(f.read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', f'attachment; filename={os.path.basename(fp)}')
msg.attach(part)
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as s:
s.login(sender, password)
s.send_message(msg)
Use an App Password if you have 2FA on Gmail.
4. Web Scraper Template
BeautifulSoup + requests starter with rate limiting and retry logic.
import requests, time, random
from bs4 import BeautifulSoup
def scrape_page(url, delay_range=(1, 3)):
time.sleep(random.uniform(*delay_range))
headers = {'User-Agent': 'Mozilla/5.0'}
for attempt in range(3):
try:
r = requests.get(url, headers=headers, timeout=10)
r.raise_for_status()
return BeautifulSoup(r.text, 'html.parser')
except requests.RequestException:
if attempt == 2: raise
time.sleep(2 ** attempt)
5. PDF Text Extractor
Pull text from PDFs for search or data pipelines.
import PyPDF2
def extract_pdf_text(filepath, pages=None):
with open(filepath, 'rb') as f:
reader = PyPDF2.PdfReader(f)
if pages is None:
pages = range(len(reader.pages))
return '\n\n'.join(reader.pages[p].extract_text() for p in pages)
6. Directory Watcher
Trigger actions whenever a file is added, modified, or deleted. Uses watchdog.
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import time
class FileHandler(FileSystemEventHandler):
def on_created(self, event):
if not event.is_directory:
print(f"New file: {event.src_path}")
def watch_directory(path):
observer = Observer()
observer.schedule(FileHandler(), path, recursive=False)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
7. JSON ↔ CSV Converter
Bidirectional conversion with nested-JSON flattening.
import json, csv
def flatten(d, parent='', sep='.'):
items = []
for k, v in d.items():
new_key = f"{parent}{sep}{k}" if parent else k
if isinstance(v, dict):
items.extend(flatten(v, new_key, sep).items())
else:
items.append((new_key, v))
return dict(items)
def json_to_csv(json_file, csv_file):
with open(json_file) as f:
data = json.load(f)
if isinstance(data, dict): data = [data]
flat = [flatten(item) for item in data]
keys = sorted({k for d in flat for k in d})
with open(csv_file, 'w', newline='') as f:
w = csv.DictWriter(f, fieldnames=keys)
w.writeheader()
w.writerows(flat)
8. Duplicate File Finder
Find (and optionally remove) duplicate files using MD5 hashing.
import hashlib, pathlib
from collections import defaultdict
def find_duplicates(directory, remove=False):
hashes = defaultdict(list)
for fp in pathlib.Path(directory).rglob('*'):
if fp.is_file():
md5 = hashlib.md5(fp.read_bytes()).hexdigest()
hashes[md5].append(fp)
dupes = {h: paths for h, paths in hashes.items() if len(paths) > 1}
if remove:
for paths in dupes.values():
for p in paths[1:]:
p.unlink()
return dupes
9. Scheduled Task Runner
Pure-Python cron, no separate scheduler service needed.
import schedule, time, threading
def run_scheduler(jobs):
for j in jobs:
schedule.every(j['interval']).hours.do(j['fn'])
while True:
schedule.run_pending()
time.sleep(60)
threading.Thread(
target=run_scheduler,
args=([{'interval': 1, 'fn': lambda: print('tick')}],),
daemon=True
).start()
10. API Response Cacher
Decorator that caches JSON results to disk with a TTL. Saves your rate limits and makes dev loops fast.
import json, hashlib, os, time
from functools import wraps
def cache_api(cache_dir='.cache', ttl=3600):
os.makedirs(cache_dir, exist_ok=True)
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
key = hashlib.md5(str(args + tuple(kwargs.items())).encode()).hexdigest()
path = os.path.join(cache_dir, f'{key}.json')
if os.path.exists(path) and time.time() - os.path.getmtime(path) < ttl:
with open(path) as f: return json.load(f)
result = func(*args, **kwargs)
try:
with open(path, 'w') as f: json.dump(result, f)
except (TypeError, ValueError):
pass
return result
return wrapper
return decorator
Wrapping up
These are the 10 I reach for constantly. Each is small and easy to modify for your use case.
If you want the ready-to-use pack with docs + example usage for all 10: payhip.com/b/Zm4lG ($12).
A few of them are also up as open source on GitHub as a preview: github.com/Devtoolkit26/python-automation-toolkit-lite.
What automation scripts have saved you the most time?
