DVPPython Studio
Module 11: Operate under pressure / Build 2 of 4

Load explicit configuration without leaking values

Validate required configuration and canonical numeric limits before effects, with controlled diagnostics.

Runs on your computer · 50–75 minutes · no paid services

Download practice filesFiles, commands & notes

Without JavaScript, use the step links and keep your files on your computer.

One useful idea

Configuration is input, not an invisible global. Pass a mapping explicitly to load_settings. Importing the package must not read os.environ, open a .env file or contact a provider. An optional command can pass os.environ deliberately. The example uses a public invented key and .invalid host, never a working provider credential or your DVP tutor login.

PROVIDER_API_KEY and ACQUISITION_HOSTS are required. The key’s classroom format is printable non-whitespace ASCII, length 12–256; that does not prove a provider accepts it. Hosts are exact lowercase ASCII DNS names, not URLs, wildcard patterns or IP literals. A host list alone is not an SSRF defense; Build 3 revalidates addresses at acquisition time.

Optional limits are canonical decimal strings. Concurrency is 1–3, timeout milliseconds 1–30000, bytes 1–8388608 and media seconds 1–600. Reject padding, signs, leading zero and non-ASCII numerals. Missing optional input uses a documented default; malformed supplied input raises ConfigError rather than silently using that default. Convert milliseconds to seconds once.

Frozen Settings refuses ordinary field assignment and validates direct construction. It is not a secret vault: raw attributes, asdict, tracebacks and arbitrary logging can expose values. ConfigError has only controlled field/code; safe_summary omits key and host values. Do not paste environment dumps into notes or the optional tutor. The reviewed Settings model helps; required-field loading, parsing and conversion remain your boundary.

Refresh first: Effect-free preflight, Validated immutable models.

Trace a finished example

from operation_tools import ConfigError, load_settings

environment = {
    "PROVIDER_API_KEY": "fixture-only-not-a-provider-key",
    "ACQUISITION_HOSTS": "media.example.invalid",
    "MAX_CONCURRENCY": "3", "CHECK_TIMEOUT_MS": "750"
}
settings = load_settings(environment)
safe = settings.safe_summary()
print(safe["concurrency"], safe["timeout_seconds"],
      safe["acquisition_host_count"])
print(environment["PROVIDER_API_KEY"] in str(safe))
try:
    load_settings({**environment, "MAX_CONCURRENCY": "03"})
except ConfigError as error:
    print(error.field, error.code)

Expected output

3 0.75 1
False
MAX_CONCURRENCY invalid

The explicit mapping becomes validated Settings; 750 milliseconds becomes 0.75 seconds. The controlled summary omits the key. A supplied noncanonical limit refuses instead of falling back to 2. Nothing here reads your environment or makes a provider request.

The finished implementation is in operation_tools/settings.py. Reading it is guided practice, not independent evidence.

Predict the refusal

Does MAX_CONCURRENCY=" 2" use the default?

Compare your answer · self-reviewed

No. A supplied malformed value produces MAX_CONCURRENCY/invalid. The default is for absent optional input, not a way to hide mistakes.

Find the leak

Settings repr hides the key. Is dataclasses.asdict(settings) safe to send to a tutor?

Compare your answer · self-reviewed

No. asdict includes raw attributes. Use controlled outputs and manually review sharing; repr policy is not a general secret detector.

Recall identity

Is the invented provider key the same as Training Hub login?

Compare your answer · self-reviewed

No. It is a classroom configuration input, never sent by the media transport. Only the site’s optional tutor uses your shared Training Hub login.

Change it, then build your own

One controlled change

Remove CHECK_TIMEOUT_MS and observe the documented default. Then try "0", "+2", "02" and a missing required host value. Predict the controlled field/code before running; do not log the entire mapping.

Your independent task

Implement load_settings in practice.py using the supplied Settings and ConfigError. Require the two named fields, parse the exact canonical integer contract for each optional limit and construct Settings with timeout converted to seconds. Do not read global os.environ inside the function, auto-load .env, echo input values or delegate to the completed loader.

What success looks like

The build2 group passes missing/invalid/default/direct-construction cases without side effects or secret-bearing diagnostics. Your own changed limits and safe summary demonstrate that values are actually loaded, not hardcoded.

Hint 1 · a question

List required and optional fields. Which branch distinguishes a missing key from a supplied bad value?

Hint 2 · a concept cue

ASCII canonical positive decimal means the first digit is 1–9 and remaining digits are 0–9. Validate the declared upper bound after parsing.

Hint 3 · a localized example

Construct Settings only after parsing every field. For CHECK_TIMEOUT_MS use parsed_ms / 1000; safe_summary is for display, not the input to reconstruct Settings.

Need the complete worked solution?

Open operation_tools/settings.py from the kit. Trace it, close it, then try fresh inputs in your own files. Treat the attempt as guided; seeing the solution does not award a practical pass.

Course help is guidance, not independent evidence. With JavaScript, opening help records guidance locally; otherwise note it in your README. Reset does not erase that history.

Repair a failed check

If signs or padding pass, validate the string grammar before int(). If malformed supplied input gets a default, distinguish absent from invalid. If timeout is 750 seconds, convert milliseconds exactly once. If an error contains the raw key or host, replace it with controlled field/code rather than sanitizing a broad traceback.

NotImplementedError means a practice stub is still unfinished. Read the failing test name and the last error line. Change one behavior, rerun that build, then rerun all implemented builds.

Show it works on new inputs

Create a fresh explicit mapping with two invented hosts and changed timeout/byte limits. Retain safe output and two refused fields without recording the key. Explain what frozen assignment and repr protection do—and what raw attribute access or a traceback can still expose.

Self-review: name the input, result, refused case and reason. Your local test output and explanation are separate from a quiz score; this page does not certify a pass.

Keep the idea

Validate configuration before effects. Controlled diagnostics help users repair a field without treating hidden repr values as a comprehensive security boundary.