Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/iFamishedX/mapres/llms.txt

Use this file to discover all available pages before exploring further.

mapres resolves placeholders by searching through a LayerStack — an ordered collection of Layer objects. Each layer groups one or more maps (DataMap instances or plain dicts) under a name and a numeric priority. When the resolver encounters a placeholder key, it walks the layers from lowest priority number to highest: the first layer that contains the key wins, and all remaining layers serve as progressively lower-priority fallbacks. This lets you compose a rich, multi-source configuration from simple, single-concern maps without any manual merging.

The Layer class

A Layer bundles a list of maps under a name and a priority value:
class Layer:
    """Holds a map with a priority"""
    def __init__(self, name, maps=None, priority=0):
        self.name = name
        self.maps = maps or []
        self.priority = priority
ParameterTypeDefaultDescription
namestrUnique identifier for this layer within a LayerStack.
mapslist | NoneNone ([])Ordered list of DataMap instances or plain dict objects held by this layer.
priorityint0Numeric priority controlling resolution order (see Priority ordering).

add(m)

Append a map to the layer’s internal list after construction:
layer = Layer("config", priority=0)
layer.add(AppMap())
layer.add({"extra_key": "extra_value"})
Layer is also directly iterable — for m in layer yields each map in insertion order.

The LayerStack class

LayerStack manages the full collection of layers and is the object MapResolver operates on:
class LayerStack:
    """Manages ordered layers"""
    def __init__(self, layers=None):
        self.layers = {}
        if layers:
            for layer in layers:
                self.layers[layer.name] = layer
Layers are stored by name in an internal dictionary.

Methods

add_layer(layer)

Register a Layer. If a layer with the same name already exists it is replaced:
stack.add_layer(Layer("overrides", maps=[OverrideMap()], priority=0))

remove_layer(name)

Remove a layer by name (no-op if the name is not present):
stack.remove_layer("overrides")

get_layer(name)

Retrieve a Layer by name, or None if not found:
base = stack.get_layer("base")

clone()

Return a shallow copy of the stack with the same layers. Used internally by MapResolver.res() when extra_maps are provided so the original stack is never mutated:
temp_stack = stack.clone()
temp_stack.add_layer(extra_layer)

all_maps()

Yield every map across all layers, sorted by ascending priority (lowest priority number first):
def all_maps(self):
    ordered = sorted(self.layers.values(), key=lambda l: l.priority)
    for layer in ordered:
        for m in layer:
            yield m
LayerStack.__iter__ delegates to all_maps(), so you can iterate a stack directly.

Priority ordering

The priority value is a plain integer — lower numbers are resolved first. A layer with priority=0 is consulted before a layer with priority=10, which is consulted before priority=999.
priority=0   ← searched first  (highest precedence)
priority=10  ← searched second
priority=999 ← searched last   (lowest precedence / fallback)
Think of it like CSS z-index in reverse: small numbers sit on top.
from mapres import Layer, LayerStack

defaults = Layer("defaults", maps=[{"color": "grey", "font": "sans-serif"}], priority=100)
theme    = Layer("theme",    maps=[{"color": "navy"}],                        priority=10)
user     = Layer("user",     maps=[{"color": "crimson"}],                     priority=0)

stack = LayerStack([defaults, theme, user])

for m in stack:
    print(m)
# Output order: user → theme → defaults
When the resolver looks up color it finds "crimson" (from user, priority 0) and stops. font is not in user or theme, so it falls back to defaults and returns "sans-serif".
Reserve priority=0 for the most specific, highest-precedence data (user preferences, runtime overrides). Use high numbers like priority=100 or priority=999 for broad defaults and fallback libraries.

extra_maps and override_maps

MapResolver.res() exposes two per-call parameters that interact with the LayerStack without mutating it permanently:

extra_maps

When provided, extra_maps are wrapped in a new Layer("extra", ..., priority=999) and appended to a clone of the existing stack. Because priority=999 is very high numerically, these maps act as low-priority fallbacks — consulted only when no existing layer has the key:
resolver.res("{greeting}", extra_maps={"greeting": "Hi", "farewell": "Bye"})

override_maps

When provided, override_maps construct a brand-new LayerStack containing only a single Layer("override", ..., priority=0). The resolver’s own self.layers are completely ignored for that call:
resolver.res("{greeting}", override_maps={"greeting": "Howdy"})
ArgumentExisting layersPriorityCache used?
extra_mapsKept (clone)999 (fallback)No
override_mapsIgnored0 (only source)No

Practical example

from mapres import MapResolver, Layer, LayerStack, datamap

@datamap
class BaseConfig:
    log_level: str = "INFO"
    timeout: int = 30
    region: str = "us-east-1"

@datamap
class ProdOverride:
    log_level: str = "WARNING"
    timeout: int = 60

# Base config as a fallback (priority=10)
base_layer = Layer("base", maps=[BaseConfig()], priority=10)

# Production overrides take precedence (priority=0)
prod_layer = Layer("prod", maps=[ProdOverride()], priority=0)

stack = LayerStack([base_layer, prod_layer])
resolver = MapResolver(layers=stack)

# log_level → ProdOverride wins  → "WARNING"
# timeout   → ProdOverride wins  → "60"
# region    → BaseConfig fallback → "us-east-1"
print(resolver.res("level={log_level} timeout={timeout} region={region}"))
# → "level=WARNING timeout=60 region=us-east-1"

# One-off extra fallback — won't override anything already in the stack
print(resolver.res("{datacenter}", extra_maps={"datacenter": "dc-west"}))
# → "dc-west"

Build docs developers (and LLMs) love