Layer request defaults with ChainMap
Also published in our Blogger archive.
Layer request defaults with ChainMap
Author: Batu. AI assistance was used to draft this article.
collections.ChainMap supplies a single mapping-style view over configuration layers without first merging them. Put the most specific request mapping first, followed by service-level settings and baseline defaults. A lookup searches in that order, so the request’s timeout of 5 wins over the default 30; the service layer provides both retries and region. The three printed values make each source of resolution concrete.
The later assignment, settings["retries"] = 1, is an important detail: ChainMap writes only to its first mapping. The assertion verifies that request gains the override while service["retries"] stays 4. This makes the front map a useful per-request overlay: it records decisions local to the request without mutating reusable layers. Underlying mappings are held by reference, so a later mutation to one of them is visible through the chain.
This is not a deep-merge structure. If a key maps to a nested dictionary, ChainMap chooses one entire nested dictionary rather than combining its fields. Missing lookups still raise KeyError, just as for a normal mapping. Also avoid assuming iteration has lookup precedence: iteration is defined by scanning the underlying mappings in a different direction. Convert to dict(settings) only when a flattened snapshot is actually needed. ChainMap was added in Python 3.3.
Source: Python ChainMap documentation.
from collections import ChainMap
defaults = {"timeout": 30, "retries": 2, "region": "baseline"}
service = {"retries": 4, "region": "zone-a"}
request = {"timeout": 5}
settings = ChainMap(request, service, defaults)
assert settings["timeout"] == 5
assert settings["retries"] == 4
assert settings["region"] == "zone-a"
print("timeout:", settings["timeout"])
print("retries:", settings["retries"])
print("region:", settings["region"])
settings["retries"] = 1
assert request == {"timeout": 5, "retries": 1}
assert service["retries"] == 4
print("request:", request)
Expected stdout
timeout: 5
retries: 4
region: zone-a
request: {'timeout': 5, 'retries': 1}