Chapter 5: Important Libraries - Interview Preparation Notes
Focus on libraries commonly used in DevOps/Cloud/Product roles and interviews.
Table of Contents
- os and pathlib (filesystem, environment)
- sys and argparse (CLI handling)
- datetime (dates, times, timezones)
- json (configs, serialization)
- re (regular expressions)
- logging (structured logs)
- requests (HTTP basics)
- Common Interview Questions
- Practice Snippets
1. os and pathlib
import os
from pathlib import Path
# Environment variables
api_key = os.getenv("API_KEY", "default-key")
os.environ["MODE"] = "dev"
# Current working directory
print(os.getcwd())
# Join and normalize paths (prefer pathlib)
base = Path.home() / "projects" / "myapp"
logs_dir = base / "logs"
logs_dir.mkdir(parents=True, exist_ok=True)
# Iterate files
for p in logs_dir.glob("*.log"):
print(p.name, p.stat().st_size)
# Read/write text files with pathlib
config_file = base / "config.json"
config_file.write_text("{}", encoding="utf-8")
print(config_file.read_text(encoding="utf-8"))
# Cross-platform temp directory
import tempfile
with tempfile.TemporaryDirectory() as tmp:
tmp_path = Path(tmp)
(tmp_path / "file.txt").write_text("hello")Notes:
- Prefer
pathlib.Pathover string paths; cleaner and cross-platform. - Use
exist_ok=Trueandparents=Truesafely.
2. sys and argparse
import sys
import argparse
# Access CLI args directly
print(sys.argv) # ['script.py', 'arg1', 'arg2']
# argparse for robust CLIs
parser = argparse.ArgumentParser(description="Process numbers")
parser.add_argument("numbers", nargs="+", type=int, help="Numbers to sum")
parser.add_argument("--verbose", "-v", action="store_true", help="Verbose output")
args = parser.parse_args(["1", "2", "3", "-v"]) # example usage
if args.verbose:
print(f"Adding {args.numbers}")
print(sum(args.numbers))Notes:
- Use
argparsefor validation, help text, and defaults.
3. datetime
from datetime import date, datetime, timedelta, timezone
# Current time (naive vs aware)
now_naive = datetime.now()
now_utc = datetime.now(timezone.utc)
# Parsing and formatting
s = "2025-09-19 14:30:00"
ts = datetime.strptime(s, "%Y-%m-%d %H:%M:%S")
print(ts.strftime("%b %d, %Y %I:%M %p"))
# Arithmetic
week_later = now_utc + timedelta(days=7)
# Convert timezone
ist = timezone(timedelta(hours=5, minutes=30))
now_ist = now_utc.astimezone(ist)Notes:
- Prefer timezone-aware datetimes in apps.
- For complex tz handling, consider
pytzorzoneinfo(Py3.9+).
4. json
import json
from pathlib import Path
settings = {"debug": True, "retries": 3}
# Serialize to string
s = json.dumps(settings, indent=2)
# Write to file
Path("settings.json").write_text(s, encoding="utf-8")
# Read from file
loaded = json.loads(Path("settings.json").read_text(encoding="utf-8"))
# Custom objects: use default hook
from dataclasses import dataclass, asdict
@dataclass
class User:
name: str
age: int
u = User("Alice", 30)
json_str = json.dumps(asdict(u))Notes:
- Use
asdictwith dataclasses for clean JSON. - For YAML in infra contexts,
PyYAMLis common but ensure safe loading (safe_load).
5. re (Regular Expressions)
import re
text = "Order #12345 shipped to email user@example.com on 2025-09-19"
# Search for first match
m = re.search(r"#(\d+)", text)
order_id = m.group(1) if m else None
# Find all emails
emails = re.findall(r"[\w.-]+@[\w.-]+", text)
# Replace dates to another format
new_text = re.sub(r"(\d{4})-(\d{2})-(\d{2})", r"\3/\2/\1", text)
# Named groups
pattern = re.compile(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})")
match = pattern.search("2025-12-01")
if match:
print(match.group("year"), match.groupdict())Notes:
- Use raw strings
r"..."for regex patterns. - Precompile with
re.compilewhen reusing patterns.
6. logging
import logging
# Basic config
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(name)s %(message)s",
)
logger = logging.getLogger("app")
logger.info("App started")
# File handler
file_handler = logging.FileHandler("app.log")
file_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.debug("Debug details")
logger.error("Something went wrong", exc_info=True)Notes:
- Avoid print for production logs; use
loggingwith handlers/formatters. - Use
exc_info=Trueto capture stack traces.
7. requests (HTTP basics)
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
# Simple GET with timeout
resp = requests.get("https://httpbin.org/get", timeout=5)
print(resp.status_code, resp.json())
# POST JSON
payload = {"name": "alice"}
resp = requests.post("https://httpbin.org/post", json=payload, timeout=5)
# Session with retries
session = requests.Session()
retry = Retry(total=3, backoff_factor=0.5, status_forcelist=[500, 502, 503, 504])
session.mount("https://", HTTPAdapter(max_retries=retry))
resp = session.get("https://httpbin.org/status/503", timeout=5)Notes:
- Always set timeouts; consider retries for transient errors.
- Prefer sessions to reuse connections.
8. Common Interview Questions
- How to read/write files portably across OSes?
- Difference between
os.pathandpathlib? - How do you parse CLI args and provide help?
- Timezone-aware vs naive datetimes? How to convert?
- JSON serialization of custom objects?
- Practical uses of regex groups and
re.sub? - How to configure logging for file and console?
- How to implement request retries and timeouts?
9. Practice Snippets
- Safe config loader (JSON)
import json
from pathlib import Path
from typing import Any
def load_config(path: str) -> dict[str, Any]:
p = Path(path)
if not p.exists():
return {}
try:
return json.loads(p.read_text(encoding="utf-8"))
except json.JSONDecodeError:
return {}- Grep-like search with regex
import re
from pathlib import Path
def grep(pattern: str, path: str) -> list[str]:
rx = re.compile(pattern)
return [line for line in Path(path).read_text(encoding="utf-8").splitlines() if rx.search(line)]- CLI sum with argparse
import argparse
def cli_sum(args: list[str]) -> int:
parser = argparse.ArgumentParser()
parser.add_argument("nums", type=int, nargs="+")
ns = parser.parse_args(args)
return sum(ns.nums)