0
# Interpolation & Resolvers
1
2
Variable interpolation system with custom resolvers for dynamic value computation, including built-in resolvers and registration of custom resolver functions.
3
4
## Capabilities
5
6
### Interpolation Functions
7
8
Helper functions for creating interpolation expressions in configurations.
9
10
```python { .api }
11
def II(interpolation: str) -> Any:
12
"""
13
Create node interpolation equivalent to ${interpolation}.
14
15
Parameters:
16
- interpolation: Interpolation string (e.g., "server.host")
17
18
Returns:
19
Interpolation expression as "${interpolation}"
20
21
Usage:
22
- II("server.host") creates "${server.host}"
23
- Used for referencing other config values
24
"""
25
26
def SI(interpolation: str) -> Any:
27
"""
28
Create string interpolation for embedding in strings.
29
30
Parameters:
31
- interpolation: String with embedded interpolations
32
33
Returns:
34
String with interpolation patterns
35
36
Usage:
37
- SI("http://${server.host}:${server.port}")
38
- Used for string templates with variable substitution
39
"""
40
```
41
42
### Resolver Management
43
44
Functions for registering and managing custom resolver functions that compute dynamic values.
45
46
```python { .api }
47
def register_new_resolver(name, resolver, replace=False, use_cache=False):
48
"""
49
Register a custom resolver function.
50
51
Parameters:
52
- name: Resolver name for use in interpolations
53
- resolver: Function that computes resolved values
54
- replace: Whether to replace existing resolver with same name
55
- use_cache: Whether to cache resolver results
56
57
Examples:
58
- register_new_resolver("env", os.getenv)
59
- register_new_resolver("now", lambda: datetime.now().isoformat())
60
"""
61
62
def has_resolver(name):
63
"""
64
Check if resolver is registered.
65
66
Parameters:
67
- name: Resolver name to check
68
69
Returns:
70
True if resolver exists, False otherwise
71
"""
72
73
def clear_resolvers():
74
"""
75
Clear all registered resolvers and re-register built-in defaults.
76
77
Removes all custom resolvers but preserves OmegaConf's built-in
78
resolvers like "oc.env", "oc.decode", etc.
79
"""
80
81
def clear_resolver(name):
82
"""
83
Clear specific resolver by name.
84
85
Parameters:
86
- name: Name of resolver to remove
87
"""
88
```
89
90
### Legacy Resolver Support
91
92
```python { .api }
93
def register_resolver(name, resolver):
94
"""
95
DEPRECATED: Register resolver (legacy interface).
96
97
Parameters:
98
- name: Resolver name
99
- resolver: Resolver function
100
101
Note: Use register_new_resolver() instead
102
"""
103
104
def legacy_register_resolver(name, resolver):
105
"""
106
Register resolver using legacy interface.
107
108
Parameters:
109
- name: Resolver name
110
- resolver: Resolver function
111
"""
112
```
113
114
### Interpolation Inspection
115
116
Methods for detecting and working with interpolation expressions.
117
118
```python { .api }
119
def is_interpolation(node, key=None):
120
"""
121
Check if node or key contains interpolation.
122
123
Parameters:
124
- node: Configuration node to check
125
- key: Optional specific key to check
126
127
Returns:
128
True if value contains interpolation expressions
129
"""
130
```
131
132
## Built-in Resolvers
133
134
OmegaConf provides several built-in resolvers for common use cases:
135
136
### Environment Variable Resolver
137
138
```python
139
# Access environment variables
140
config = OmegaConf.create({
141
"database_url": "${oc.env:DATABASE_URL}",
142
"debug": "${oc.env:DEBUG,false}" # With default value
143
})
144
```
145
146
### Decode Resolver
147
148
```python
149
# Decode base64 strings
150
config = OmegaConf.create({
151
"secret": "${oc.decode:base64,SGVsbG8gV29ybGQ=}" # "Hello World"
152
})
153
```
154
155
## Usage Examples
156
157
### Basic Interpolation
158
159
```python
160
from omegaconf import OmegaConf
161
162
config = OmegaConf.create({
163
"server": {
164
"host": "localhost",
165
"port": 8080
166
},
167
"database": {
168
"host": "${server.host}", # References server.host
169
"url": "postgresql://${database.host}:5432/mydb"
170
},
171
"api": {
172
"base_url": "http://${server.host}:${server.port}",
173
"endpoints": {
174
"users": "${api.base_url}/users",
175
"posts": "${api.base_url}/posts"
176
}
177
}
178
})
179
180
# Interpolations are resolved when accessed
181
print(config.database.host) # "localhost"
182
print(config.api.endpoints.users) # "http://localhost:8080/users"
183
```
184
185
### Helper Functions
186
187
```python
188
from omegaconf import OmegaConf, II, SI
189
190
# Using II() for node interpolation
191
config = OmegaConf.create({
192
"server": {"host": "localhost", "port": 8080},
193
"client": {
194
"server_host": II("server.host"), # Same as "${server.host}"
195
"url": SI("http://${server.host}:${server.port}/api")
196
}
197
})
198
```
199
200
### Custom Resolvers
201
202
```python
203
import os
204
from datetime import datetime
205
from omegaconf import OmegaConf
206
207
# Register environment variable resolver
208
OmegaConf.register_new_resolver("env", lambda key, default=None: os.getenv(key, default))
209
210
# Register timestamp resolver
211
OmegaConf.register_new_resolver("now", lambda: datetime.now().isoformat())
212
213
# Register computation resolver
214
OmegaConf.register_new_resolver("add", lambda x, y: int(x) + int(y))
215
216
config = OmegaConf.create({
217
"database": {
218
"host": "${env:DB_HOST,localhost}", # Environment variable with default
219
"password": "${env:DB_PASSWORD}" # Environment variable
220
},
221
"deployment": {
222
"timestamp": "${now:}", # Current timestamp
223
"total_workers": "${add:4,8}" # Computed value: 12
224
}
225
})
226
227
print(config.database.host) # Value from DB_HOST env var or "localhost"
228
print(config.deployment.timestamp) # Current ISO timestamp
229
print(config.deployment.total_workers) # 12
230
```
231
232
### Resolver with Caching
233
234
```python
235
from omegaconf import OmegaConf
236
import random
237
238
# Expensive computation that should be cached
239
def expensive_computation():
240
print("Computing expensive value...")
241
return random.randint(1000, 9999)
242
243
# Register with caching enabled
244
OmegaConf.register_new_resolver("expensive", expensive_computation, use_cache=True)
245
246
config = OmegaConf.create({
247
"value1": "${expensive:}",
248
"value2": "${expensive:}", # Same resolver call
249
"value3": "${expensive:}" # Same resolver call
250
})
251
252
# Resolver function called only once due to caching
253
print(config.value1) # Prints "Computing expensive value..." and returns value
254
print(config.value2) # Returns cached value (no print)
255
print(config.value3) # Returns cached value (no print)
256
```
257
258
### Complex Resolver Patterns
259
260
```python
261
from omegaconf import OmegaConf
262
import json
263
264
# Register JSON parsing resolver
265
OmegaConf.register_new_resolver("json", lambda s: json.loads(s))
266
267
# Register file reading resolver
268
OmegaConf.register_new_resolver("file", lambda path: open(path).read().strip())
269
270
# Register conditional resolver
271
OmegaConf.register_new_resolver("if", lambda condition, true_val, false_val: true_val if condition == "true" else false_val)
272
273
config = OmegaConf.create({
274
"features": "${json:[\"auth\", \"logging\", \"metrics\"]}", # Parse JSON array
275
"version": "${file:VERSION}", # Read from file
276
"debug_mode": "${if:${env:DEBUG,false},debug,production}" # Conditional logic
277
})
278
279
print(config.features) # ["auth", "logging", "metrics"]
280
print(config.version) # Contents of VERSION file
281
print(config.debug_mode) # "debug" or "production" based on DEBUG env var
282
```
283
284
### Resolver Management
285
286
```python
287
from omegaconf import OmegaConf
288
289
# Check if resolver exists
290
if OmegaConf.has_resolver("env"):
291
print("Environment resolver available")
292
293
# Clear specific resolver
294
OmegaConf.clear_resolver("env")
295
296
# Clear all resolvers (keeps built-ins)
297
OmegaConf.clear_resolvers()
298
299
# Re-register custom resolvers after clearing
300
OmegaConf.register_new_resolver("env", os.getenv)
301
```