方寸 Portal

AI Engineer Portal

Your personal operating system for career transition.

Private mode

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:

  1. Reads all config from environment variables — use pydantic-settings BaseSettings or standard BaseModel with model_validator.
  2. Validates types and constraintsmax_tokens must be between 1 and 8192, temperature between 0.0 and 2.0, api_key must be non-empty.
  3. Provides defaults for non-critical settingstimeout_s defaults to 30.0, max_concurrent defaults to 5.
  4. Raises a descriptive error on startup if required values are missing — do not let the service boot with api_key = None.
  5. Supports a from_dict class method for testing — so tests can pass config without touching os.environ.

Config fields to implement

FieldTypeRequiredDefaultConstraint
api_keystrYesmin length 8
modelstrYesnon-empty
max_tokensintNo10241–8192
temperaturefloatNo0.70.0–2.0
timeout_sfloatNo30.0> 0
max_concurrentintNo51–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.environ inside the model — inject values via from_dict for tests.
  • Raise a ValueError with a clear message if api_key is missing or too short.

Python Refresh / medium / Step 13 of 16

Practice stage

Core runtime habits

Hint

Normalize the boundary first, keep return shapes stable, and make the middle of the function boring on purpose.

Success criteria
  • - Returns one stable shape across branches
  • - Makes failure handling obvious
  • - Keeps the core logic readable in under a minute
Review checklist
  • - 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.