Syllabus Lesson 46 of 244 · Files, Errors & Modules
Files, Errors & Modules

Configuration and secrets

Real programs need settings that should not live in the code: API keys, database URLs, a debug flag. Two reasons to keep them out. First, secrets in source code leak: the moment you commit an API key to git, it is in the history forever, and pushing to a public repo hands it to the world. Second, the same code should run in different places (your laptop, a server) with different settings.

The standard answer is environment variables: named values the operating system hands to your process. Python reads them from os.environ, which behaves like a dict:

import os
key = os.environ["API_KEY"]              # raises KeyError if missing
debug = os.environ.get("DEBUG", "off")   # a safe default instead

In development you keep these in a .env file that you never commit (you add .env to .gitignore). It is just KEY=value lines:

API_KEY=sk-abc123
# a comment
MODEL=claude-sonnet-4-6
DEBUG=on

Libraries like python-dotenv load that file into os.environ for you. Under the hood they parse exactly these lines. In this exercise you will write that parser yourself, plus a helper that redacts a secret so it is safe to print in a log.

The golden rule: read secrets from the environment, log them redacted, and never hardcode them.

Your turn

Build three helpers. (1) load_env(text) parses the contents of a .env file into a dict. Skip blank lines and comment lines (starting with #). Split each remaining line on the first =. Strip whitespace, and strip one pair of surrounding quotes from the value if present. Keep a line only if the key is a valid environment name: all uppercase, and a valid Python identifier (letters, digits and underscores, not starting with a digit). (2) get_setting(env, key, default=None) returns env[key] if present, else default. (3) redact(value) returns a safe-to-log string showing only the last 4 characters, e.g. redact("sk-abc123") is "****c123"; values of 4 characters or fewer become "****".

Spotted a problem in this lesson? Report it

Code · runs in your browser
Output