⏱️ Slide Timing: 1 min - Welcome and frame the session: how to keep secrets and config out of your source code - Promise: by the end, everyone will have loaded a real API key from a `.env` file into a script - Bridge: start with what goes wrong when config is hardcoded
⏱️ Slide Timing: 3 min - Ask: has anyone ever committed a password or API key by accident? - It happens to experienced engineers too — it's a process problem, not a carelessness problem - Emphasize the scanning-bots point — leaked keys get found and abused within minutes on public repos - Bridge: show exactly how this plays out vs. the fix ❓ Ask: "If you accidentally committed a real API key, would deleting the file fix it?"
⏱️ Slide Timing: 5 min - Left panel: the key lives inside `config.py`, so every `git commit` carries it into permanent history - Deleting the line in a later commit does NOT remove it — it's still readable in old commits - Right panel: the key lives in a `.env` file that's excluded from git entirely by `.gitignore` - `load_dotenv()` reads it into the process at runtime; the code never contains the actual value - This is the one-slide summary of "why dotenv exists" — refer back to it if questions come up later
⏱️ Slide Timing: 3 min - Key mental model: dotenv doesn't invent a new config system — it simulates environment variables locally - This is why the same `os.getenv()` call works unchanged when you deploy to a server that sets real env vars - Bridge: show the flow visually before the demo
⏱️ Slide Timing: 3 min - Walk left to right: the `.env` file is just plain text sitting in your project folder - `load_dotenv()` parses it once and copies every key into `os.environ` - From that point on, `os.getenv("API_KEY")` behaves exactly like reading a real environment variable
⏱️ Slide Timing: 1 min - Keep this short — it's a single command either way - Use `uv add` in projects that already use `uv`; use `pip install` inside an activated `venv` otherwise - Reinforce the habit from the venv session: `pip install` only works as expected once a venv is activated
⏱️ Slide Timing: 4 min - Live-type this rather than just showing the slide - Point out `load_dotenv()` must run before the `os.getenv()` call — order matters - Have students run this on their own machine, confirm they see `demo123` printed
⏱️ Slide Timing: 3 min - Have students try both lines against a key that doesn't exist in their `.env` - Discuss when a hard failure is actually the right behavior — e.g. a required production secret
⏱️ Slide Timing: 3 min - This pairing solves the "how do I know what to put in .env" problem for a new teammate cloning the repo - Good habit: whenever you add a new variable to your own `.env`, add the placeholder to `.env.example` too
⏱️ Slide Timing: 3 min - The string-typing gotcha is the most common bug — a numeric-looking env var is still a string until you cast it - The precedence rule is deliberate: it lets a hosting platform's real env vars override local `.env` values safely - Mention `find_dotenv()` for cases where the working directory isn't predictable (e.g. running from a subfolder)
⏱️ Slide Timing: 2 min - Suggest students screenshot this slide — it's the reference they'll reach for in every future project
⏱️ Slide Timing: 1 min - Highest priority to bookmark: the Twelve-Factor App "Config" page — it's the design rationale this whole pattern implements
⏱️ Slide Timing: 2 min - Close the loop back to the opening problem: this is the fix for secrets ending up in git history - Practice prompt: have students add `.env` + `.env.example` to their current project right now, before leaving class