AI Engineer Portal
Your personal operating system for career transition.
Exercise
Build a type-safe config loader from environment variables
Build a Type-Safe Config Loader from Environment Variables
AI services are configured through environment variables: API keys, model names, timeout values, rate limits, feature flags. The naive approach — calling os.environ.get("MODEL") scattered throughout the codebase — creates invisible coupling between config layout and application code, and lets the service start with missing or invalid config that will fail on the first request.
What to build
Implement a ServiceConfig Pydantic model and a load_config() factory function that:
- Reads all config from environment variables — use
pydantic-settingsBaseSettingsor standardBaseModelwithmodel_validator. - Validates types and constraints —
max_tokensmust be between 1 and 8192,temperaturebetween 0.0 and 2.0,api_keymust be non-empty. - Provides defaults for non-critical settings —
timeout_sdefaults to30.0,max_concurrentdefaults to5. - Raises a descriptive error on startup if required values are missing — do not let the service boot with
api_key = None. - Supports a
from_dictclass method for testing — so tests can pass config without touchingos.environ.
Config fields to implement
| Field | Type | Required | Default | Constraint |
|---|---|---|---|---|
api_key | str | Yes | — | min length 8 |
model | str | Yes | — | non-empty |
max_tokens | int | No | 1024 | 1–8192 |
temperature | float | No | 0.7 | 0.0–2.0 |
timeout_s | float | No | 30.0 | > 0 |
max_concurrent | int | No | 5 | 1–50 |
Why this matters
Missing or malformed config is one of the most common production failure modes. A service that validates its entire config at boot time fails fast with a clear error — not 10 minutes into the first request with a cryptic AttributeError. The from_dict method makes tests config-hermetic: no monkeypatching environment variables.
Constraints
- Use Pydantic v2. Do not use
os.environinside the model — inject values viafrom_dictfor tests. - Raise a
ValueErrorwith a clear message ifapi_keyis missing or too short.
Python Refresh / medium / Step 13 of 16
Core runtime habits
Normalize the boundary first, keep return shapes stable, and make the middle of the function boring on purpose.
- - Returns one stable shape across branches
- - Makes failure handling obvious
- - Keeps the core logic readable in under a minute
- - Did I make the input and output shapes explicit?
- - Would a teammate know where validation happens?
- - Did I avoid silent mutation or vague branching?
Practice
Generate a variation
Generate a new exercise variation to deepen understanding or practice a related concept.
Attempt history
Recent submissions
Before you submit, decide what a strong answer should make obvious to the reviewer.
No attempts yet.