Guide Python Intermediate

From Python Basics to Production Scripts

Prepare scripts for repeatable use with environments, CLI arguments, logging, configuration, tests, and bounded API calls.

3 min read

Prerequisites

Complete functions, exceptions, files, and modules in fundamentals, then the file-processing lab. This bridge runs locally without AWS credentials.

Set up a project environment

Create a project directory and run python -m venv .venv. Activate it with .venv\Scripts\Activate.ps1 in PowerShell or source .venv/bin/activate in bash. Alternatively, call .venv\Scripts\python.exe on Windows or .venv/bin/python on Unix directly. Confirm python -c "import sys; print(sys.executable)" points inside the environment.

For the later AWS labs, install boto3 with python -m pip install boto3. Record tested dependencies with python -m pip freeze > requirements.txt, and recreate them with python -m pip install -r requirements.txt. Keep .venv/ out of version control. See the Python virtual environment tutorial.

Sample input and task

Turn a list of server states into a command-line report. Save the solution as report.py. Accept a status filter, log a count to stderr, print matching names to stdout, and return zero on success.

Run python report.py --status critical. Expected stdout: web-02. Stderr includes INFO matched=1. An unsupported status must produce an argument error and a nonzero exit code.

HintKeep filtering separate from argument parsing and logging so tests can pass records directly.
Show solution: report.py
import argparse
import logging
import os


def select_names(records, status):
    return [row["name"] for row in records if row["status"] == status]


def main():
    parser = argparse.ArgumentParser(description="Filter server states")
    parser.add_argument("--status", choices=["healthy", "critical"],
                        default="critical")
    args = parser.parse_args()
    level = os.environ.get("REPORT_LOG_LEVEL", "INFO").upper()
    if level not in {"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"}:
        parser.error("REPORT_LOG_LEVEL must be a logging level")
    logging.basicConfig(level=level, format="%(levelname)s %(message)s")
    records = [{"name": "web-01", "status": "healthy"},
               {"name": "web-02", "status": "critical"}]
    names = select_names(records, args.status)
    logging.info("matched=%d", len(names))
    for name in names:
        print(name)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

Test the behavior

Save this beside the script as test_report.py and run python -m unittest -v.

import unittest
from report import select_names


class ReportTests(unittest.TestCase):
    def test_filters_without_changing_input(self):
        rows = [{"name": "web-01", "status": "healthy"},
                {"name": "web-02", "status": "critical"}]
        self.assertEqual(select_names(rows, "critical"), ["web-02"])
        self.assertEqual(len(rows), 2)

    def test_empty_and_no_match(self):
        self.assertEqual(select_names([], "critical"), [])
        self.assertEqual(select_names(
            [{"name": "web-01", "status": "healthy"}], "critical"), [])

Before adding an API

ConcernApply it to your script
ConfigurationUse CLI flags for the current run and environment variables for deployment defaults; validate both.
CredentialsUse the SDK credential chain and a role or configured profile.
LoggingSend diagnostics to stderr and report data to stdout or a file; exclude secrets.
TimeoutsBound connection and read waits; a read timeout is not a deadline for a whole paginated job.
RetriesUse the SDK’s bounded retry policy for supported transient failures.
Exit codesReturn zero only on success so CI and schedulers can detect failures.

For boto3, use Config(connect_timeout=5, read_timeout=20, retries={"mode": "standard", "total_max_attempts": 4}). The attempt limit includes the original request. See the SDK retry documentation.

Completion checklist and challenge

  • Run both status filters and the invalid-status case.
  • Pass the unit tests without calling a network service.
  • Explain the difference between logs and report output.
  • Add a CSV input argument and a test for a missing required column.

Continue to the EC2 report lab and then the inventory capstone.

Add More Questions to This Guide

Know a question that should be here? Share it and help the community!

Open Google Form