0
# Configuration Store
1
2
Centralized registry for storing and managing structured configuration schemas. The ConfigStore enables registration of Python dataclasses, dictionaries, and other objects as configuration templates that can be used by name in Hydra applications.
3
4
## Capabilities
5
6
### ConfigStore Class
7
8
Singleton registry that stores configuration nodes organized hierarchically by groups and names.
9
10
```python { .api }
11
class ConfigStore:
12
@staticmethod
13
def instance() -> "ConfigStore":
14
"""Get the singleton ConfigStore instance."""
15
16
def store(
17
self,
18
name: str,
19
node: Any,
20
group: Optional[str] = None,
21
package: Optional[str] = None,
22
provider: Optional[str] = None
23
) -> None:
24
"""
25
Store a configuration node in the repository.
26
27
Parameters:
28
- name: Config name (automatically gets .yaml suffix if missing)
29
- node: Config node (DictConfig, dataclass, dict, list, or any structured config)
30
- group: Config group for hierarchical organization (use "/" for subgroups)
31
- package: Config node parent hierarchy (use "." for nested packages)
32
- provider: Name of module/app providing this config (for debugging)
33
"""
34
35
def load(self, config_path: str) -> ConfigNode:
36
"""
37
Load a configuration node by path.
38
39
Parameters:
40
- config_path: Path to config (e.g., "group/name" or just "name")
41
42
Returns:
43
ConfigNode: Loaded configuration node with metadata
44
45
Raises:
46
ConfigLoadError: If config not found
47
"""
48
49
def list(self, path: str) -> List[str]:
50
"""
51
List available configurations at path.
52
53
Parameters:
54
- path: Group path to list
55
56
Returns:
57
List[str]: Sorted list of available config names
58
59
Raises:
60
IOError: If path not found or points to a file
61
"""
62
63
def get_type(self, path: str) -> ObjectType:
64
"""
65
Get the type of object at path.
66
67
Parameters:
68
- path: Path to check
69
70
Returns:
71
ObjectType: CONFIG, GROUP, or NOT_FOUND
72
"""
73
```
74
75
### ConfigNode Class
76
77
Dataclass representing a stored configuration with metadata.
78
79
```python { .api }
80
@dataclass
81
class ConfigNode:
82
name: str # Config name
83
node: DictConfig # The configuration data
84
group: Optional[str] # Config group
85
package: Optional[str] # Package hierarchy
86
provider: Optional[str] # Provider name
87
```
88
89
### ConfigStoreWithProvider Context Manager
90
91
Context manager for storing multiple configs with the same provider.
92
93
```python { .api }
94
class ConfigStoreWithProvider:
95
def __init__(self, provider: str) -> None:
96
"""
97
Create context manager with provider name.
98
99
Parameters:
100
- provider: Provider name for all configs stored in this context
101
"""
102
103
def store(
104
self,
105
name: str,
106
node: Any,
107
group: Optional[str] = None,
108
package: Optional[str] = None
109
) -> None:
110
"""Store config with the context provider."""
111
```
112
113
## Usage Examples
114
115
### Basic Configuration Storage
116
117
```python
118
from dataclasses import dataclass
119
from hydra.core.config_store import ConfigStore
120
121
@dataclass
122
class DatabaseConfig:
123
driver: str = "mysql"
124
host: str = "localhost"
125
port: int = 3306
126
user: str = "root"
127
password: str = "password"
128
129
# Get ConfigStore instance
130
cs = ConfigStore.instance()
131
132
# Store structured config
133
cs.store(name="db_config", node=DatabaseConfig)
134
135
# Store with group
136
cs.store(name="mysql", node=DatabaseConfig, group="db")
137
138
# Store with package hierarchy
139
cs.store(name="prod", node=DatabaseConfig, group="db", package="database.primary")
140
```
141
142
### Using Config Groups
143
144
```python
145
from dataclasses import dataclass
146
from hydra.core.config_store import ConfigStore
147
148
@dataclass
149
class MySQLConfig:
150
driver: str = "mysql"
151
port: int = 3306
152
153
@dataclass
154
class PostgreSQLConfig:
155
driver: str = "postgresql"
156
port: int = 5432
157
158
cs = ConfigStore.instance()
159
160
# Store in db config group
161
cs.store(name="mysql", node=MySQLConfig, group="db")
162
cs.store(name="postgres", node=PostgreSQLConfig, group="db")
163
164
# Use in application
165
@hydra.main(version_base=None, config_path=None, config_name="config")
166
def my_app(cfg: DictConfig) -> None:
167
print(cfg.db.driver)
168
169
# Override from command line: python app.py db=postgres
170
```
171
172
### Package Hierarchies
173
174
```python
175
from dataclasses import dataclass
176
from hydra.core.config_store import ConfigStore
177
178
@dataclass
179
class ServerConfig:
180
host: str = "localhost"
181
port: int = 8080
182
183
cs = ConfigStore.instance()
184
185
# Store with package hierarchy - config will be nested under server.web
186
cs.store(
187
name="web_server",
188
node=ServerConfig,
189
package="server.web"
190
)
191
192
# Results in configuration structure:
193
# server:
194
# web:
195
# host: localhost
196
# port: 8080
197
```
198
199
### Provider Context Manager
200
201
```python
202
from hydra.core.config_store import ConfigStore
203
204
cs = ConfigStore.instance()
205
206
# Store multiple configs with same provider
207
with cs.provider("my_app"):
208
cs.store(name="config1", node={"key1": "value1"})
209
cs.store(name="config2", node={"key2": "value2"})
210
211
# Alternative using ConfigStoreWithProvider directly
212
from hydra.core.config_store import ConfigStoreWithProvider
213
214
with ConfigStoreWithProvider("my_app") as store:
215
store.store(name="config1", node={"key1": "value1"})
216
store.store(name="config2", node={"key2": "value2"})
217
```
218
219
### Loading and Querying Configurations
220
221
```python
222
from hydra.core.config_store import ConfigStore
223
224
cs = ConfigStore.instance()
225
226
# Load a specific configuration
227
config_node = cs.load("db/mysql")
228
print(config_node.name)
229
print(config_node.node)
230
print(config_node.provider)
231
232
# List available configurations
233
db_configs = cs.list("db")
234
print(db_configs) # ['mysql.yaml', 'postgres.yaml']
235
236
# Check if path exists and get type
237
from hydra.core.object_type import ObjectType
238
239
obj_type = cs.get_type("db")
240
if obj_type == ObjectType.GROUP:
241
print("db is a group")
242
elif obj_type == ObjectType.CONFIG:
243
print("db is a config")
244
elif obj_type == ObjectType.NOT_FOUND:
245
print("db not found")
246
```
247
248
### Integration with Main Application
249
250
```python
251
from dataclasses import dataclass
252
from hydra import main
253
from hydra.core.config_store import ConfigStore
254
from omegaconf import DictConfig
255
256
@dataclass
257
class AppConfig:
258
name: str = "MyApp"
259
debug: bool = False
260
database: dict = None
261
262
# Register configuration
263
cs = ConfigStore.instance()
264
cs.store(name="config", node=AppConfig)
265
266
@main(version_base=None, config_path=None, config_name="config")
267
def my_app(cfg: AppConfig) -> None: # Type hint matches stored config
268
print(f"Running {cfg.name}")
269
if cfg.debug:
270
print("Debug mode enabled")
271
```
272
273
### Complex Hierarchical Configurations
274
275
```python
276
from dataclasses import dataclass, field
277
from typing import Dict, Any
278
from hydra.core.config_store import ConfigStore
279
280
@dataclass
281
class DatabaseConfig:
282
host: str = "localhost"
283
port: int = 3306
284
285
@dataclass
286
class CacheConfig:
287
ttl: int = 3600
288
size: int = 1000
289
290
@dataclass
291
class AppConfig:
292
name: str = "MyApp"
293
database: Dict[str, Any] = field(default_factory=dict)
294
cache: Dict[str, Any] = field(default_factory=dict)
295
296
cs = ConfigStore.instance()
297
298
# Store main config
299
cs.store(name="config", node=AppConfig)
300
301
# Store component configs in groups
302
cs.store(name="mysql", node=DatabaseConfig, group="database")
303
cs.store(name="redis", node=CacheConfig, group="cache")
304
305
# Use with defaults in config file or via defaults list
306
# config.yaml:
307
# defaults:
308
# - database: mysql
309
# - cache: redis
310
```
311
312
### Error Handling
313
314
```python
315
from hydra.core.config_store import ConfigStore
316
from hydra.plugins.config_source import ConfigLoadError
317
318
cs = ConfigStore.instance()
319
320
# Handle missing config
321
try:
322
config = cs.load("nonexistent/config")
323
except ConfigLoadError as e:
324
print(f"Config not found: {e}")
325
326
# Handle invalid paths
327
try:
328
configs = cs.list("nonexistent/path")
329
except IOError as e:
330
print(f"Path error: {e}")
331
```
332
333
### Runtime Configuration Discovery
334
335
```python
336
from hydra.core.config_store import ConfigStore
337
338
def discover_configs():
339
"""Discover all available configurations."""
340
cs = ConfigStore.instance()
341
342
def explore_path(path: str = "", indent: int = 0):
343
try:
344
items = cs.list(path)
345
for item in items:
346
full_path = f"{path}/{item}" if path else item
347
print(" " * indent + item)
348
349
obj_type = cs.get_type(full_path)
350
if obj_type == ObjectType.GROUP:
351
explore_path(full_path, indent + 1)
352
except IOError:
353
pass
354
355
print("Available configurations:")
356
explore_path()
357
358
discover_configs()
359
```