Writing automation scripts in Python allows you to replace repetitive manual tasks with reliable, reusable code. Probably you're organizing files, processing data, sending emails, or interacting with APIs. Python provides a simple and powerful way to automate everyday workflows.
With Python automation, you'll learn how to structure automation scripts, work with files and folders, schedule recurring tasks, choose the right libraries, and write maintainable code that scales as your projects grow.
Opening a File
The open() function is used to access a file.
Reading and Writing Files Automatically
with open("notes.txt", "r") as file:
content = file.read()
print(content)
The with statement automatically closes the file after the block finishes executing, even if an error occurs. This is the recommended approach because it helps prevent resource leaks.
Mode | Purpose |
|---|---|
| Read an existing file |
| Write to a file, replacing existing content |
| Append new content to the end of a file |
| Create a new file and fail if it already exists |
Choosing the correct mode helps to prevent you from accidentally overwriting important data.
Reading Files Line by Line
Large files should not always be loaded into memory at once; they should be processed one line at a time:
with open("users.txt", "r") as file:
for line in file:
print(line.strip())
This approach is more memory-efficient and works well for log files, reports, and exported datasets.
Writing Data to a File
Automation scripts often generate output that needs to be saved.
Example:
with open("report.txt", "w") as file:
file.write("Daily report completed.\n")
file.write("Processed 150 records.")
If report.txt already exists, its contents will be replaced, but to preserve existing data, use append mode instead.
with open("report.txt", "a") as file:
file.write("\nBackup completed successfully.")
Appending is commonly used for log files and activity histories.
Working with Structured Data
Many automation tasks involve structured files such as CSV documents. Python's built-in csv module makes reading and writing CSV files simple.
Reading a CSV file:
import csv
with open("employees.csv", newline="") as file:
reader = csv.reader(file)
for row in reader:
print(row)
Writing a CSV file:
import csv
rows = [
["Name", "Department"],
["Alice", "Engineering"],
["David", "Finance"]
]
with open("employees.csv", "w", newline="") as file:
writer = csv.writer(file)
writer.writerows(rows)
CSV automation is widely used for reporting, data migration, and importing information into other systems.
Check Whether a File Exists
Automation scripts should not assume every file is available. Before attempting to read a file, verify that it exists.
from pathlib import Path
file = Path("report.txt")
if file.exists():
print("File found.")
Checking file existence helps avoid runtime errors and allows your script to respond appropriately when files are missing.
Handle File Errors Gracefully
Unexpected problems can occur during file operations.
Examples:
Missing files
Insufficient permissions
Corrupted data
Files currently in use
Use exception handling to make scripts more reliable.
try:
with open("report.txt", "r") as file:
print(file.read())
except FileNotFoundError:
print("The file could not be found.")
Handling errors gracefully prevents the entire automation workflow from failing because of a single missing file.
Process Multiple Files Automatically
Many automation workflows need to perform the same operation on several files.
Example: processing every text file in a directory
from pathlib import Path
for file in Path("documents").glob("*.txt"):
print(file.name)
This technique is useful for:
Log analysis
Report generation
Document processing
Batch file conversion
Instead of opening each file manually, the script handles them automatically.
Use Meaningful File Names
Generated files should have descriptive names.
Example:
sales_report_2026_07.csv
backup_2026_07_01.zip
system_log.txt
Clear naming of conventions makes files easier to locate and reduces confusion whenever a different report or backup is created over time.
Keep Input and Output Separate
A good practice is to separate original files from generated files.
Example:
project/
│
├── input/
├── output/
├── archive/
└── main.py
This structure helps prevent accidental overwrites and keeps automation projects organized as they grow.
Test File Operations with Different Scenarios
Before relying on an automation script, be sure to test how it behaves under different conditions. Verify that it handles:
Empty files
Very large files
Missing files
Read-only files
Unexpected file contents
Testing these scenarios helps you to identify potential issues early and improves the reliability of your automation workflows.
Automating Folder and File Management
Automating folder and file management is one of the most practical uses of Python. Instead of manually organizing directories, renaming files, creating backups, or deleting temporary data. You can write a script that performs these tasks consistently in a short period of time.
Create Folders Automatically
Many automation workflows need to create directories before saving reports, logs, or exported data.
With pathlib you can create a folder if it doesn't already exist:
from pathlib import Path
output_dir = Path("reports")
output_dir.mkdir(exist_ok=True)
The exist_ok=True argument prevents an error if the folder already exists, making the script safe to run multiple times.
List Files in a Directory
Before processing files, you often need to discover what's available.
Example:
from pathlib import Path
folder = Path("documents")
for file in folder.iterdir():
print(file.name)
This allows your script to inspect an entire directory without requiring file names to be entered manually.
Find Files by Type
Many automation scripts only work with specific file formats.
You can filter files using patterns:
from pathlib import Path
for file in Path("reports").glob("*.csv"):
print(file.name)
This approach is useful when processing:
CSV reports
PDF documents
Log files
Images
Configuration files
Rename Files Automatically
Renaming files manually becomes stressful when dealing with large collections. Python can help rename files programmatically.
Example:
from pathlib import Path
old_file = Path("report.txt")
new_file = Path("daily_report.txt")
old_file.rename(new_file)
This is commonly used to apply consistent naming conventions or include dates in filenames.
Move Files Between Folders
Automation often involves organizing files after they have been processed.
The shutil module makes moving files simple.
import shutil
shutil.move("report.csv", "archive/report.csv")
Typical workflows include:
Moving processed files to an archive
Moving uploaded files to a processing folder
Moving completed reports to a distribution directory
This helps keep working folders clean and organized.
Copy Files for Backup
Some automation tasks require preserving the original file.
Instead of moving it, create a copy.
import shutil
shutil.copy("report.csv", "backup/report.csv")
For entire folders, use:
import shutil
shutil.copytree("reports", "reports_backup")
Creating backups before modifying files reduces the risk of accidental data loss.
Delete Unnecessary Files
Temporary files and outdated reports can accumulate over time.
Python allows you to remove files safely.
from pathlib import Path
file = Path("temp.txt")
if file.exists():
file.unlink()
Before deleting files automatically, consider adding checks to ensure they are no longer needed.
Handle File System Errors
File operations can fail for several reasons, including:
Missing files
Missing folders
Insufficient permissions
Files currently in use
Use exception handling to keep the automation workflow running.
try:
Path("report.txt").unlink()
except FileNotFoundError:
print("File not found.")
Handling expected errors makes automation scripts more reliable and easier to troubleshoot.
Organize Projects with a Consistent Folder Structure
A predictable directory layout simplifies maintenance.
Example:
automation-project/
│
├── input/
├── processing/
├── output/
├── archive/
├── logs/
└── main.py
Keeping incoming files, processed data, archived documents, and logs in separate folders makes automation workflows easier to understand and reduces the chance of overwriting important files.
Scheduling Repetitive Tasks with Python
Many automation scripts are designed to run more than once. Instead of executing them manually every day, you can schedule them to run automatically at specific times or regular intervals. This makes Python useful for recurring tasks such as generating reports, backing up files, cleaning directories, checking APIs, or sending notifications.
Scheduling allows your automation workflow to run consistently without requiring manual intervention.
Tasks That Should Be Scheduled
Not every script needs a schedule. The greatest benefits come from tasks that you repeat on a daily basis.
Common examples include:
Creating daily backup files
Generating weekly reports
Downloading data from an API every hour
Cleaning temporary folders each night
Monitoring server health
Processing newly uploaded files
Sending scheduled email reminders
If you find yourself running the same script repeatedly, it is a good candidate for scheduling.
Keep the Script Self-Contained
A scheduled script should perform its work without requiring user input.
Instead of:
name = input("Enter your name: ")
Design the script to read configuration values from files or environment variables and complete its task automatically.
Schedule Tasks Within Python
Example:
import schedule
import time
def generate_report():
print("Generating report...")
schedule.every().day.at("09:00").do(generate_report)
while True:
schedule.run_pending()
time.sleep(1)
This approach works well for simple automation projects that run in the background.
Use Operating System Schedulers
Operating system schedulers are a better choice for keeping a Python program running continuously.
Common scheduling tools include:
Operating System | Scheduler |
|---|---|
Windows | Task Scheduler |
Linux | cron |
macOS | cron or launchd |
These tools launch your Python script at the scheduled time, reducing resource usage and improving reliability.
Pass Arguments to Scheduled Scripts
Some automation workflows need different behavior depending on when they run.
Example:
python report.py daily
or
python report.py weekly
The script can then determine which report to generate based on the command-line argument.
Record Each Scheduled Run
A scheduled task should leave a record of its execution and logging information, such as:
Execution time
Completion status
Errors encountered
Files processed
Makes it much easier to troubleshoot failed jobs.
Example:
import logging
logging.basicConfig(filename="automation.log", level=logging.INFO)
logging.info("Daily report completed.")
Logs become especially valuable when scripts execute overnight or on remote servers.
Handle Unexpected Failures
A scheduled script should anticipate potential failures.
Examples:
Unavailable network connections
Missing files
Expired credentials
API timeouts
Insufficient disk space
Use exception handling to prevent unexpected crashes.
try:
process_data()
except Exception as error:
print(error)
In production systems, you may also log the exception or send an alert when a scheduled task fails.
Keep Scheduling Configuration Flexible
Avoid hardcoding schedules directly into your source code whenever possible.
Instead of embedding values like:
schedule.every().day.at("09:00")
Store scheduling information in a configuration file or environment variable.
This allows schedules to change without modifying the application code.
Build Automation That Can Run Reliably
Well-designed scheduled scripts share different characteristics:
They perform one clearly defined task
They finish without requiring user interaction
They generate logs for later review
They recover gracefully from common errors
They can be executed repeatedly with consistent results
Following these practices helps ensure your Python automation continues running reliably, whether it executes every few minutes or only once a month.
Logging Script Output for Easier Troubleshooting
Logging is one of the most valuable features you can add to a Python automation script. While print() statements are useful during development; they provide little help once a script runs unattended.
Logs create a permanent record of what happened during execution, making it much easier to spot failures and verify that tasks were completed successfully.
Whether your script runs every few minutes or once a month, detailed logs can significantly reduce troubleshooting time.
Why Logging Is Better Than print()
Many beginners use:
print("Processing completed.")
This displays information on the console but disappears when the terminal is closed.
A logging system writes messages to a file or another destination, allowing you to review previous executions even days or weeks later.
Example:
import logging
logging.basicConfig(
filename="automation.log",
level=logging.INFO,
format="%(asctime)s %(levelname)s %(message)s"
)
logging.info("Processing completed.")
Each log entry includes useful information, such as execution time and message importance.
Understand Log Levels
Python's built-in logging module supports several log levels that indicate the importance of a message.
Log Level | Purpose |
|---|---|
| Helps with detailed information for development |
| It helps to confirm that normal operations were completed successfully |
| It indicates a potential issue that does not stop execution |
| It records failures that prevent part of the script from completing |
| It reports serious errors that may stop the entire application |



