Python Automation Scripts 2026 — Automate Everything With Python
⚡ Quick Answer
Learn to automate repetitive tasks with Python. File management, email sending, web scraping, scheduled jobs, Excel automation — real scripts you can use today.
Get more content like this on Telegram!
Daily AI tips, notes & resources — free
Advertisement
Python Automation Scripts 2026 — Stop Doing Things Manually
You know that feeling when you spend three hours doing something mind-numbing — renaming 200 files, moving data between spreadsheets, sending the same type of email to a list of people — and you think: there has to be a better way.
There is. Python automation scripts.
Once you learn to automate repetitive tasks, your productivity multiplies. You stop being the bottleneck and your computer starts working for you. This guide is packed with real, immediately usable scripts for common automation tasks.
The Python Automation Mindset
Before touching any code, internalize this: if you do a task more than twice, automate it. The initial investment of writing a 30-line Python script saves hours over the year.
Good candidates for automation:
- Any task you do on a regular schedule (daily, weekly)
- Any task involving repetitive file operations
- Any task that processes data from one format to another
- Any task that involves fetching information from the web
Part 1: File and Folder Automation
Organize a Messy Downloads Folder
import os
import shutil
from pathlib import Path
def organize_downloads(downloads_path: str) -> dict:
"""Sort files in downloads folder into subfolders by type."""
CATEGORIES = {
"Images": [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg", ".bmp"],
"Videos": [".mp4", ".mkv", ".avi", ".mov", ".wmv"],
"Documents": [".pdf", ".doc", ".docx", ".txt", ".odt"],
"Spreadsheets": [".xls", ".xlsx", ".csv"],
"Code": [".py", ".js", ".ts", ".html", ".css", ".json"],
"Archives": [".zip", ".rar", ".7z", ".tar", ".gz"],
"Audio": [".mp3", ".wav", ".flac", ".aac"],
}
downloads = Path(downloads_path)
moved = {}
for file in downloads.iterdir():
if not file.is_file():
continue
suffix = file.suffix.lower()
destination_folder = None
for category, extensions in CATEGORIES.items():
if suffix in extensions:
destination_folder = category
break
if destination_folder is None:
destination_folder = "Other"
dest_dir = downloads / destination_folder
dest_dir.mkdir(exist_ok=True)
dest_path = dest_dir / file.name
if not dest_path.exists():
shutil.move(str(file), str(dest_path))
moved[category] = moved.get(category, 0) + 1
return moved
result = organize_downloads(r"C:\Users\User\Downloads")
for category, count in result.items():
print(f"Moved {count} files to {category}/")
Batch Rename Files
from pathlib import Path
import re
def batch_rename(folder: str, pattern: str, replacement: str) -> int:
"""Rename files matching a pattern in a folder."""
path = Path(folder)
count = 0
for file in path.iterdir():
if file.is_file():
new_name = re.sub(pattern, replacement, file.name)
if new_name != file.name:
file.rename(file.parent / new_name)
print(f" {file.name} → {new_name}")
count += 1
return count
# Example: rename "IMG_20260501_143022.jpg" → "2026-05-01_photo.jpg"
count = batch_rename(
r"C:\Users\User\Photos",
r"IMG_(\d{4})(\d{2})(\d{2})_\d+",
r"\1-\2-\3_photo"
)
print(f"Renamed {count} files")
Auto-Backup Important Folders
import shutil
import os
from datetime import datetime
from pathlib import Path
def backup_folder(source: str, backup_root: str, keep_last: int = 7) -> str:
"""Create a timestamped backup of a folder, keeping only the last N."""
source_path = Path(source)
backup_dir = Path(backup_root)
backup_dir.mkdir(parents=True, exist_ok=True)
timestamp = datetime.now().strftime("%Y-%m-%d_%H%M%S")
folder_name = source_path.name
backup_path = backup_dir / f"{folder_name}_{timestamp}"
shutil.copytree(source, backup_path)
print(f"Backup created: {backup_path}")
# Remove old backups
backups = sorted(backup_dir.glob(f"{folder_name}_*"), reverse=True)
for old_backup in backups[keep_last:]:
shutil.rmtree(old_backup)
print(f"Removed old backup: {old_backup.name}")
return str(backup_path)
backup_folder(
r"C:\Users\User\Documents\Projects",
r"D:\Backups",
keep_last=7
)
Part 2: Excel and CSV Automation
Process Multiple CSV Files
import pandas as pd
from pathlib import Path
def merge_monthly_reports(reports_folder: str, output_file: str) -> int:
"""Merge all CSV reports in a folder into one master file."""
folder = Path(reports_folder)
all_dfs = []
for csv_file in sorted(folder.glob("*.csv")):
df = pd.read_csv(csv_file)
df["source_file"] = csv_file.name # Track which file each row came from
all_dfs.append(df)
print(f"Loaded: {csv_file.name} ({len(df)} rows)")
if not all_dfs:
print("No CSV files found")
return 0
merged = pd.concat(all_dfs, ignore_index=True)
merged.to_csv(output_file, index=False)
print(f"\nMerged {len(all_dfs)} files → {len(merged)} total rows → {output_file}")
return len(merged)
merge_monthly_reports("monthly_reports/", "full_year_report.csv")
Generate Excel Reports with Formatting
import pandas as pd
from openpyxl.styles import PatternFill, Font, Alignment
from openpyxl.utils import get_column_letter
def create_sales_report(data: pd.DataFrame, output_file: str) -> None:
"""Create a formatted Excel report from a DataFrame."""
with pd.ExcelWriter(output_file, engine="openpyxl") as writer:
data.to_excel(writer, index=False, sheet_name="Sales Data")
workbook = writer.book
worksheet = writer.sheets["Sales Data"]
# Style header row
header_fill = PatternFill("solid", fgColor="4F46E5")
header_font = Font(color="FFFFFF", bold=True)
for cell in worksheet[1]:
cell.fill = header_fill
cell.font = header_font
cell.alignment = Alignment(horizontal="center")
# Auto-fit column widths
for i, column in enumerate(data.columns, 1):
max_length = max(len(str(column)), data[column].astype(str).str.len().max())
worksheet.column_dimensions[get_column_letter(i)].width = min(max_length + 4, 40)
print(f"Report saved: {output_file}")
Part 3: Email Automation
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
from pathlib import Path
import os
def send_email(
to: str | list[str],
subject: str,
body_html: str,
attachments: list[str] | None = None,
smtp_server: str = "smtp.gmail.com",
smtp_port: int = 587,
) -> bool:
"""Send an email with optional attachments."""
sender = os.environ["EMAIL_ADDRESS"]
password = os.environ["EMAIL_APP_PASSWORD"] # Use App Password, not real password
msg = MIMEMultipart("alternative")
msg["From"] = sender
msg["To"] = ", ".join(to) if isinstance(to, list) else to
msg["Subject"] = subject
msg.attach(MIMEText(body_html, "html"))
# Attach files
for filepath in (attachments or []):
path = Path(filepath)
with open(path, "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={path.name}")
msg.attach(part)
try:
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls()
server.login(sender, password)
server.send_message(msg)
print(f"Email sent to {msg['To']}")
return True
except Exception as e:
print(f"Failed to send email: {e}")
return False
# Send weekly report
send_email(
to="team@company.com",
subject="Weekly Sales Report — May 2026",
body_html="<h2>Weekly Report</h2><p>See attached for this week's sales data.</p>",
attachments=["weekly_report.xlsx"]
)
Part 4: Scheduled Automation
Using the schedule Library
import schedule
import time
import logging
from datetime import datetime
logging.basicConfig(level=logging.INFO, format="%(asctime)s — %(message)s")
logger = logging.getLogger(__name__)
def morning_report():
logger.info("Generating morning report...")
# Your report generation code here
logger.info("Morning report sent!")
def backup_job():
logger.info("Running daily backup...")
# Your backup code here
logger.info("Backup complete!")
def weekly_cleanup():
logger.info("Running weekly cleanup...")
# Your cleanup code here
# Schedule jobs
schedule.every().day.at("08:00").do(morning_report)
schedule.every().day.at("23:00").do(backup_job)
schedule.every().monday.at("09:00").do(weekly_cleanup)
schedule.every(30).minutes.do(lambda: logger.info("Heartbeat OK"))
logger.info("Scheduler started. Press Ctrl+C to stop.")
while True:
schedule.run_pending()
time.sleep(60)
Running Scripts Automatically on Windows (Task Scheduler)
To run your Python script automatically on Windows without keeping a terminal open:
:: Create a .bat file: run_script.bat
@echo off
cd /d "C:\path\to\your\script"
"C:\path\to\python.exe" your_script.py >> logs\output.log 2>&1
Then use Windows Task Scheduler to run run_script.bat on your desired schedule.
Part 5: Web Automation with Playwright
For automating browsers — filling forms, logging into sites, clicking buttons:
from playwright.sync_api import sync_playwright
def automate_login_and_download(url: str, username: str, password: str) -> None:
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto(url)
# Fill login form
page.fill("#username", username)
page.fill("#password", password)
page.click("button[type='submit']")
# Wait for redirect after login
page.wait_for_url("**/dashboard**")
print("Logged in successfully")
# Navigate to reports
page.click("text=Reports")
page.wait_for_selector(".report-table")
# Trigger download
with page.expect_download() as download_info:
page.click("button.download-csv")
download = download_info.value
download.save_as("report_downloaded.csv")
print(f"Downloaded: report_downloaded.csv")
browser.close()
Part 6: System Monitoring Automation
import psutil
import smtplib
import time
def monitor_system(
cpu_threshold: float = 90.0,
memory_threshold: float = 85.0,
disk_threshold: float = 90.0,
check_interval: int = 60
) -> None:
"""Monitor system resources and alert when thresholds are exceeded."""
print(f"Monitoring system... Checking every {check_interval}s")
while True:
cpu = psutil.cpu_percent(interval=1)
memory = psutil.virtual_memory().percent
disk = psutil.disk_usage("/").percent
alerts = []
if cpu > cpu_threshold:
alerts.append(f"CPU: {cpu:.1f}% (threshold: {cpu_threshold}%)")
if memory > memory_threshold:
alerts.append(f"Memory: {memory:.1f}% (threshold: {memory_threshold}%)")
if disk > disk_threshold:
alerts.append(f"Disk: {disk:.1f}% (threshold: {disk_threshold}%)")
if alerts:
message = "ALERT: System thresholds exceeded\n" + "\n".join(alerts)
print(f"\n{message}")
# send_email(to="admin@company.com", subject="System Alert", body_html=message)
else:
print(f"\rCPU: {cpu:.1f}% | RAM: {memory:.1f}% | Disk: {disk:.1f}%", end="")
time.sleep(check_interval)
Building Your Automation Library
The best approach is to build a personal library of reusable scripts. As your collection grows, new automations take minutes instead of hours because you are combining things you have already built.
To get even more power from your automation scripts, combine them with AI — our guide on best free AI tools 2026 covers tools like GitHub Copilot that help you write automation code faster.
For scheduling your web-scraping automations, check out the Python web scraping guide which pairs perfectly with the scheduling techniques in this post.
Quick Reference: Python Automation Libraries
| Library | Use Case | Install |
|---|---|---|
pathlib | File and folder operations | Built-in |
shutil | Copy, move, delete files | Built-in |
schedule | Run code on a schedule | pip install schedule |
pandas | CSV/Excel processing | pip install pandas openpyxl |
playwright | Browser automation | pip install playwright |
smtplib | Send emails | Built-in |
psutil | System monitoring | pip install psutil |
watchdog | Watch for file changes | pip install watchdog |
Start with one automation that saves you real time this week. That first win is addictive — once you see an hour of manual work handled in 10 seconds, you will automate everything.
Python automation templates for common workflows available free in the AiTechWorlds Telegram channel!
Further Reading
- Python vs JavaScript in 2025: Which Should a Beginner Learn First?
- Python for Beginners: Complete 2026 Roadmap – Step-by-Step Guide
- FastAPI Tutorial 2026 — Build Production-Ready REST APIs with Python
- How I Learned Python in 3 Months and Got a Job: My Honest Story
- Python Async Programming Guide 2026 — asyncio, aiohttp & Concurrency
- JavaScript Promises and Async/Await: Finally Understand Them
Advertisement
💬 DiscussionPowered by GitHub Discussions
Frequently Asked Questions

AiTechWorlds Team
✓ Verified WriterThe AiTechWorlds team is passionate about AI, technology, and education. We create high-quality, research-backed content to help you learn, grow, and succeed in the modern digital world.
Advertisement
Related Articles
The Python Libraries Every Developer Must Know in 2025
The essential Python libraries for 2025: from requests and pandas to FastAPI and LangChain — what each does, when to use it, and how to get started quickly.
Django vs Flask in 2025: Which Framework Should You Learn?
An honest Django vs Flask comparison for 2025 — which Python framework to learn first, when each excels, and why FastAPI has changed the equation.
FastAPI Tutorial: Building Your First REST API in 30 Minutes
A hands-on FastAPI tutorial for beginners: build a fully functional REST API in 30 minutes with CRUD endpoints, request validation, and automatic docs.
Jupyter Notebook Guide: The Data Scientist's Favorite Tool
A complete Jupyter Notebook guide for 2025: installation, essential shortcuts, best practices, and how data scientists use Jupyter for exploration, analysis, and sharing.