📁 Files and Exceptions
Reading and Writing Files
Working with text files for configuration management.
# Writing configuration to a file
def write_config(filename, config_data):
with open(filename, 'w') as file:
for device, config in config_data.items():
file.write(f"{device}: {config}\\n")
print(f"Configuration written to {filename}")
# Reading configuration from a file
def read_config(filename):
config = {}
try:
with open(filename, 'r') as file:
for line in file:
device, config_line = line.strip().split(': ', 1)
config[device] = config_line
return config
except FileNotFoundError:
print(f"File {filename} not found")
return {}
# Usage
config_data = {
"SW101": "vlan 10,20,30",
"SW102": "vlan 40,50,60",
"SW110": "vlan 70,80,90"
}
write_config("network_config.txt", config_data)
config = read_config("network_config.txt")
Handling Exceptions
Proper error handling for robust network automation.
def safe_device_config(device_name, config):
"""Safely configure a device with error handling"""
try:
# Simulate device configuration
if device_name not in ["SW101", "SW102", "SW110"]:
raise ValueError(f"Unknown device: {device_name}")
if not config:
raise ValueError("Configuration cannot be empty")
print(f"Configuring {device_name} with: {config}")
return True
except ValueError as e:
print(f"Configuration error: {e}")
return False
except Exception as e:
print(f"Unexpected error: {e}")
return False
finally:
print(f"Configuration attempt completed for {device_name}")
# Test exception handling
safe_device_config("SW101", "vlan 10")
safe_device_config("SW999", "vlan 20") # Unknown device
safe_device_config("SW102", "") # Empty config
Command Line Arguments
Using command line arguments for flexible scripts.
import sys
def process_command_line_args():
"""Process command line arguments"""
if len(sys.argv) < 2:
print("Usage: python script.py [device_name]")
return None, None
config_file = sys.argv[1]
device_name = sys.argv[2] if len(sys.argv) > 2 else None
return config_file, device_name
# Usage
config_file, device = process_command_line_args()
if config_file:
print(f"Processing config file: {config_file}")
if device:
print(f"Target device: {device}")
📦 Modules
Datetime and Time Modules
Working with dates and times for network monitoring.
import datetime
import time
def log_network_event(event, device):
"""Log network events with timestamp"""
timestamp = datetime.datetime.now()
log_entry = f"[{timestamp}] {event} on {device}"
print(log_entry)
# Save to log file
with open("network.log", "a") as log_file:
log_file.write(log_entry + "\\n")
def monitor_network_duration():
"""Monitor network for a specific duration"""
start_time = time.time()
duration = 10 # seconds
print(f"Starting network monitoring for {duration} seconds...")
while time.time() - start_time < duration:
log_network_event("Status check", "SW101")
time.sleep(2) # Check every 2 seconds
print("Network monitoring completed")
# Usage
log_network_event("Device online", "SW101")
monitor_network_duration()
OS and Calendar Modules
System operations and calendar functions.
import os
import calendar
def system_info():
"""Get system information"""
print(f"Current directory: {os.getcwd()}")
print(f"Environment: {os.environ.get('PYTHONPATH', 'Not set')}")
# List files in current directory
files = os.listdir('.')
print(f"Files in directory: {files}")
def network_calendar():
"""Display network maintenance calendar"""
year = 2024
month = 3
print(f"Network Maintenance Calendar for {calendar.month_name[month]} {year}")
print(calendar.month(year, month))
# Check if it's a weekend (maintenance day)
today = datetime.date.today()
if today.weekday() >= 5: # Saturday = 5, Sunday = 6
print("Weekend - Maintenance window available")
else:
print("Weekday - Limited maintenance window")
# Usage
system_info()
network_calendar()
Math Module
Mathematical operations for network calculations.
import math
def calculate_network_metrics():
"""Calculate various network metrics"""
# Bandwidth calculations
ports = 48
port_speed = 1000 # Mbps
total_bandwidth = ports * port_speed
# Convert to different units
bandwidth_gbps = total_bandwidth / 1000
bandwidth_tbps = total_bandwidth / 1000000
print(f"Total bandwidth: {total_bandwidth} Mbps")
print(f"Total bandwidth: {bandwidth_gbps} Gbps")
print(f"Total bandwidth: {bandwidth_tbps:.3f} Tbps")
# Calculate network efficiency
utilization = 0.75 # 75% utilization
effective_bandwidth = total_bandwidth * utilization
print(f"Effective bandwidth at {utilization*100}% utilization: {effective_bandwidth} Mbps")
# Calculate packet loss
packets_sent = 1000000
packets_lost = 100
packet_loss_rate = (packets_lost / packets_sent) * 100
print(f"Packet loss rate: {packet_loss_rate:.4f}%")
# Calculate round-trip time
distance_km = 100 # Distance in kilometers
speed_of_light = 299792458 # m/s
rtt = (2 * distance_km * 1000) / speed_of_light * 1000 # Convert to ms
print(f"RTT for {distance_km}km: {rtt:.2f} ms")
# Usage
calculate_network_metrics()
📚 Packages
Creating a Network Package
Organizing code into packages for better structure.
network_utils/
├── __init__.py
├── config.py
└── status.py
# network_utils/__init__.py
from .config import NetworkConfig
from .status import DeviceStatus
__version__ = "1.0.0"
__all__ = ["NetworkConfig", "DeviceStatus"]
# network_utils/config.py
class NetworkConfig:
def __init__(self, device_name):
self.device_name = device_name
self.config = {}
def add_vlan(self, vlan_id, vlan_name):
self.config[f"vlan_{vlan_id}"] = vlan_name
print(f"Added VLAN {vlan_id}: {vlan_name}")
def get_config(self):
return self.config
# network_utils/status.py
class DeviceStatus:
def __init__(self, device_name):
self.device_name = device_name
self.status = "unknown"
def set_status(self, status):
self.status = status
print(f"{self.device_name} status: {status}")
def get_status(self):
return self.status
Using the Package
# main.py
from network_utils import NetworkConfig, DeviceStatus
def main():
# Create network configuration
config = NetworkConfig("SW101")
config.add_vlan(10, "Management")
config.add_vlan(20, "Data")
config.add_vlan(30, "Voice")
# Check device status
status = DeviceStatus("SW101")
status.set_status("up")
print(f"Configuration: {config.get_config()}")
print(f"Device status: {status.get_status()}")
if __name__ == "__main__":
main()
🎮 Interactive Demo: File Operations
Try different file operations:
File Writer
Enter filename and content to write a file!
Exception Handler
Enter device name and config to test exception handling!
🔧 Advanced Network Automation
Complete Network Management System
import json
import logging
from datetime import datetime
class NetworkManager:
def __init__(self, config_file="network_config.json"):
self.config_file = config_file
self.devices = {}
self.setup_logging()
def setup_logging(self):
"""Setup logging for network operations"""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('network.log'),
logging.StreamHandler()
]
)
self.logger = logging.getLogger(__name__)
def load_config(self):
"""Load network configuration from file"""
try:
with open(self.config_file, 'r') as file:
self.devices = json.load(file)
self.logger.info(f"Loaded configuration for {len(self.devices)} devices")
except FileNotFoundError:
self.logger.warning(f"Config file {self.config_file} not found")
self.devices = {}
except json.JSONDecodeError as e:
self.logger.error(f"Invalid JSON in config file: {e}")
self.devices = {}
def save_config(self):
"""Save network configuration to file"""
try:
with open(self.config_file, 'w') as file:
json.dump(self.devices, file, indent=2)
self.logger.info("Configuration saved successfully")
except Exception as e:
self.logger.error(f"Failed to save configuration: {e}")
def add_device(self, device_name, device_type, ip_address):
"""Add a new device to the network"""
self.devices[device_name] = {
"type": device_type,
"ip": ip_address,
"status": "unknown",
"last_updated": datetime.now().isoformat()
}
self.logger.info(f"Added device: {device_name}")
def update_device_status(self, device_name, status):
"""Update device status"""
if device_name in self.devices:
self.devices[device_name]["status"] = status
self.devices[device_name]["last_updated"] = datetime.now().isoformat()
self.logger.info(f"Updated {device_name} status to {status}")
else:
self.logger.warning(f"Device {device_name} not found")
def get_device_info(self, device_name):
"""Get information about a specific device"""
return self.devices.get(device_name, None)
def list_devices(self):
"""List all devices in the network"""
for device, info in self.devices.items():
print(f"{device}: {info['type']} - {info['ip']} - {info['status']}")
# Usage example
if __name__ == "__main__":
manager = NetworkManager()
manager.load_config()
# Add some devices
manager.add_device("SW101", "Switch", "192.168.1.1")
manager.add_device("SW102", "Switch", "192.168.1.2")
manager.add_device("R101", "Router", "192.168.1.254")
# Update status
manager.update_device_status("SW101", "up")
manager.update_device_status("SW102", "up")
manager.update_device_status("R101", "up")
# List devices
manager.list_devices()
# Save configuration
manager.save_config()
🎯 Best Practices
Error Handling Best Practices
- Use specific exceptions: Catch specific exceptions rather than generic ones
- Log errors: Always log errors for debugging
- Graceful degradation: Handle errors gracefully without crashing
- Resource cleanup: Use try-finally or context managers
File Handling Best Practices
- Use context managers: Always use 'with' statements for file operations
- Handle encoding: Specify encoding when reading/writing files
- Validate paths: Check if files exist before operations
- Backup important files: Create backups before modifications
Module Organization Best Practices
- Single responsibility: Each module should have one clear purpose
- Clear naming: Use descriptive names for modules and functions
- Documentation: Include docstrings and comments
- Version control: Use version numbers for packages
🎮 Interactive Demo: Complete System
Run the complete network management system:
Click a button to see the complete system in action!
📊 Quick Comparison
| Topic | Key Point | Example |
|---|---|---|
| File I/O | Use context manager | with open(...) as f: |
| Exceptions | Catch specific types | except FileNotFoundError: |
| Modules | Group related code | import os |
| Packages | Directory with __init__.py | network_utils/ |
📝 Quick Quiz (5 Questions)
- Best practice to ensure file closes:
- Handle missing file with:
- Which logs time-stamped messages?
- A package must contain:
- Which module is for OS ops?
Answer all questions and click Submit.
🎉 Course Completion
🎓 Python Training Complete!
📚 5 Days of Learning
🔧 Network Automation Ready
🚀 Advanced Python Skills
What You've Learned:
- Day 1: Data types, variables, expressions, statements, and functions
- Day 2: Control flow, loops, conditionals, and iteration
- Day 3: Advanced functions, arrays, string manipulation, and recursion
- Day 4: Lists, tuples, dictionaries, and data structures
- Day 5: Files, exceptions, modules, packages, and advanced topics
Next Steps:
- Practice with real network automation projects
- Explore Python libraries like Netmiko, NAPALM, and Ansible
- Learn about REST APIs and network programmability
- Consider advanced topics like async programming and testing