Python Basics for DevOps
Python has become the de facto scripting language for DevOps, automation, and platform engineering. Its simplicity, readability, and extensive library ecosystem make it ideal for infrastructure automation, deployment scripts, and tooling. This post covers Python fundamentals essential for DevOps practitioners.
Why Python for DevOps
Python provides several advantages for DevOps work:
- Readable syntax: Easy to learn and maintain
- Rich standard library: Built-in modules for file I/O, networking, JSON, and more
- Extensive ecosystem: Libraries for AWS (boto3), Azure (azure-sdk), Kubernetes (kubernetes-python), and more
- Cross-platform: Runs on Linux, Windows, and macOS
- Interpreted: Quick development and testing cycles
graph LR
A[Python Script] --> B[File Operations]
A --> C[API Calls]
A --> D[Database Access]
A --> E[Cloud SDKs]
Basic Syntax
Variables and Data Types
# Variables (no declaration needed)
name = "Alice"
age = 30
height = 5.6
is_active = True
# Multiple assignment
x, y, z = 1, 2, 3
# Type hints (Python 3.5+)
name: str = "Alice"
age: int = 30
Numbers
# Integer
count = 42
big_number = 1_000_000
# Float
price = 19.99
scientific = 1.5e-3
# Operations
result = 10 + 5 - 3 * 2 / 4
power = 2 ** 3 # 8
modulo = 10 % 3 # 1
floor_div = 10 // 3 # 3
Strings
# String literals
single = 'Hello'
double = "World"
multiline = """This is
a multiline
string"""
# String formatting
name = "Alice"
age = 30
# f-strings (Python 3.6+, preferred)
message = f"My name is {name} and I'm {age} years old"
# format() method
message = "My name is {} and I'm {} years old".format(name, age)
# % formatting (older style)
message = "My name is %s and I'm %d years old" % (name, age)
# String methods
text = " Hello World "
upper = text.upper() # " HELLO WORLD "
lower = text.lower() # " hello world "
stripped = text.strip() # "Hello World"
replaced = text.replace("World", "Python")
split_words = text.split() # ["Hello", "World"]
Data Structures
Lists
Lists are ordered, mutable collections.
# Create list
numbers = [1, 2, 3, 4, 5]
mixed = [1, "two", 3.0, True]
# Access elements
first = numbers[0] # 1
last = numbers[-1] # 5
slice = numbers[1:3] # [2, 3]
# Modify list
numbers.append(6)
numbers.insert(0, 0)
numbers.remove(3)
popped = numbers.pop()
numbers.extend([7, 8, 9])
# List operations
length = len(numbers)
contains = 5 in numbers
index = numbers.index(5)
count = numbers.count(2)
# List comprehension
squares = [x**2 for x in range(10)]
evens = [x for x in numbers if x % 2 == 0]
Dictionaries
Dictionaries are key-value stores.
# Create dictionary
person = {
"name": "Alice",
"age": 30,
"city": "New York"
}
# Access values
name = person["name"]
age = person.get("age")
city = person.get("country", "USA") # Default value
# Modify dictionary
person["age"] = 31
person["email"] = "alice@example.com"
del person["city"]
# Dictionary operations
keys = person.keys()
values = person.values()
items = person.items()
# Dictionary comprehension
squared = {x: x**2 for x in range(5)}
# Iterate over dictionary
for key, value in person.items():
print(f"{key}: {value}")
Tuples
Tuples are immutable ordered collections.
# Create tuple
coordinates = (10, 20)
rgb = (255, 128, 0)
# Unpack tuple
x, y = coordinates
r, g, b = rgb
# Named tuples
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y)
Sets
Sets are unordered collections of unique elements.
# Create set
numbers = {1, 2, 3, 4, 5}
unique = set([1, 2, 2, 3, 3, 4]) # {1, 2, 3, 4}
# Set operations
numbers.add(6)
numbers.remove(3)
numbers.discard(10) # No error if not exists
# Set math
a = {1, 2, 3}
b = {3, 4, 5}
union = a | b # {1, 2, 3, 4, 5}
intersection = a & b # {3}
difference = a - b # {1, 2}
Control Flow
Conditionals
# If-elif-else
score = 85
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
else:
grade = "F"
# Ternary operator
grade = "Pass" if score >= 60 else "Fail"
# Multiple conditions
if score >= 60 and score < 90:
print("Good job")
if score < 60 or score > 100:
print("Invalid score")
Loops
# For loop
for i in range(5):
print(i) # 0, 1, 2, 3, 4
# For with list
fruits = ["apple", "banana", "orange"]
for fruit in fruits:
print(fruit)
# For with enumerate
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
# For with dictionary
person = {"name": "Alice", "age": 30}
for key, value in person.items():
print(f"{key}: {value}")
# While loop
count = 0
while count < 5:
print(count)
count += 1
# Break and continue
for i in range(10):
if i == 3:
continue # Skip 3
if i == 7:
break # Stop at 7
print(i)
graph TD
A[Start Loop] --> B{Condition?}
B -->|True| C[Execute Block]
C --> D{Continue?}
D -->|Yes| B
D -->|Break| E[Exit Loop]
B -->|False| E
Functions
# Basic function
def greet(name):
return f"Hello, {name}!"
# Default parameters
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
# Multiple return values
def get_coordinates():
return 10, 20
x, y = get_coordinates()
# Variable arguments
def sum_all(*args):
return sum(args)
result = sum_all(1, 2, 3, 4, 5)
# Keyword arguments
def create_user(**kwargs):
print(kwargs)
create_user(name="Alice", age=30, city="NYC")
# Lambda functions
square = lambda x: x ** 2
add = lambda x, y: x + y
File Operations
# Read file
with open("file.txt", "r") as f:
content = f.read()
# Read lines
with open("file.txt", "r") as f:
lines = f.readlines()
# Read line by line
with open("file.txt", "r") as f:
for line in f:
print(line.strip())
# Write file
with open("output.txt", "w") as f:
f.write("Hello, World!\n")
# Append to file
with open("output.txt", "a") as f:
f.write("Additional line\n")
# Write multiple lines
lines = ["Line 1\n", "Line 2\n", "Line 3\n"]
with open("output.txt", "w") as f:
f.writelines(lines)
# Check if file exists
import os
if os.path.exists("file.txt"):
print("File exists")
Working with JSON
import json
# Read JSON file
with open("config.json", "r") as f:
config = json.load(f)
# Write JSON file
data = {"name": "Alice", "age": 30}
with open("output.json", "w") as f:
json.dump(data, f, indent=2)
# Parse JSON string
json_string = '{"name": "Bob", "age": 25}'
person = json.loads(json_string)
# Convert to JSON string
json_string = json.dumps(data, indent=2)
Exception Handling
# Basic try-except
try:
result = 10 / 0
except ZeroDivisionError as e:
print(f"Error: {e}")
# Multiple exceptions
try:
value = int("abc")
except (ValueError, TypeError) as e:
print(f"Error: {e}")
# Catch all exceptions
try:
risky_operation()
except Exception as e:
print(f"Unexpected error: {e}")
# Finally block
try:
f = open("file.txt", "r")
content = f.read()
except FileNotFoundError:
print("File not found")
finally:
f.close() # Always executes
# Raise exceptions
def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
Modules and Imports
# Import entire module
import os
import sys
# Import specific items
from pathlib import Path
from datetime import datetime, timedelta
# Import with alias
import numpy as np
import pandas as pd
# Import all (not recommended)
from math import *
Common DevOps Modules
# Operating system operations
import os
# Get environment variable
api_key = os.getenv("API_KEY", "default_value")
# Execute command
exit_code = os.system("ls -la")
# List directory
files = os.listdir("/path/to/dir")
# Path operations
from pathlib import Path
path = Path("/path/to/file.txt")
exists = path.exists()
is_file = path.is_file()
parent = path.parent
name = path.name
# Subprocess for running commands
import subprocess
result = subprocess.run(
["ls", "-la"],
capture_output=True,
text=True
)
print(result.stdout)
print(result.returncode)
# HTTP requests
import requests
response = requests.get("https://api.example.com/data")
if response.status_code == 200:
data = response.json()
# YAML parsing
import yaml
with open("config.yaml", "r") as f:
config = yaml.safe_load(f)
Practical Example: Server Health Check Script
#!/usr/bin/env python3
import requests
import time
import sys
from datetime import datetime
def check_server(url, timeout=5):
"""Check if server is responding."""
try:
response = requests.get(url, timeout=timeout)
return response.status_code == 200
except requests.RequestException as e:
print(f"Error checking {url}: {e}")
return False
def log_status(url, is_healthy):
"""Log server status with timestamp."""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
status = "UP" if is_healthy else "DOWN"
message = f"[{timestamp}] {url} is {status}"
print(message)
# Write to log file
with open("health_check.log", "a") as f:
f.write(message + "\n")
def monitor_servers(urls, interval=60):
"""Monitor multiple servers continuously."""
print(f"Monitoring {len(urls)} servers every {interval} seconds")
print("Press Ctrl+C to stop\n")
try:
while True:
for url in urls:
is_healthy = check_server(url)
log_status(url, is_healthy)
time.sleep(interval)
except KeyboardInterrupt:
print("\nMonitoring stopped")
sys.exit(0)
if __name__ == "__main__":
servers = [
"https://api.example.com/health",
"https://app.example.com",
"https://db.example.com/ping"
]
monitor_servers(servers, interval=30)
Key Takeaways
- Python provides clean, readable syntax ideal for DevOps automation scripts
- Lists, dictionaries, tuples, and sets are core data structures for different use cases
- File operations with context managers (
withstatement) ensure proper resource cleanup - JSON and YAML parsing enable working with configuration files
- Exception handling prevents scripts from crashing unexpectedly
- Standard library modules like os, pathlib, and subprocess enable system operations
- Third-party libraries like requests, boto3, and kubernetes simplify API interactions
- Type hints improve code documentation and enable static analysis
- List and dictionary comprehensions provide concise syntax for data transformations
- Functions with default parameters and keyword arguments increase flexibility
- Virtual environments isolate project dependencies
- Python's cross-platform nature ensures scripts run consistently across environments