0
# Configuration System
1
2
File-based configuration loading system supporting JSON, TOML, YAML formats and environment variable integration.
3
4
## Capabilities
5
6
### Base Configuration Class
7
8
Abstract base class for all configuration loaders.
9
10
```python { .api }
11
class ConfigFromFile:
12
def __init__(self, file: Path):
13
"""
14
Base configuration loader from file.
15
16
Parameters
17
----------
18
file
19
Path to configuration file
20
"""
21
22
def load(self) -> dict[str, Any]:
23
"""
24
Load configuration from file.
25
26
Returns
27
-------
28
dict[str, Any]
29
Configuration data as dictionary
30
"""
31
```
32
33
### JSON Configuration
34
35
Load configuration from JSON files.
36
37
```python { .api }
38
class Json(ConfigFromFile):
39
def __init__(self, file: Path):
40
"""
41
JSON configuration loader.
42
43
Parameters
44
----------
45
file
46
Path to JSON configuration file
47
"""
48
49
def load(self) -> dict[str, Any]:
50
"""
51
Load configuration from JSON file.
52
53
Returns
54
-------
55
dict[str, Any]
56
Parsed JSON configuration
57
58
Raises
59
------
60
FileNotFoundError
61
If configuration file doesn't exist
62
json.JSONDecodeError
63
If JSON is malformed
64
"""
65
```
66
67
### TOML Configuration
68
69
Load configuration from TOML files.
70
71
```python { .api }
72
class Toml(ConfigFromFile):
73
def __init__(self, file: Path):
74
"""
75
TOML configuration loader.
76
77
Parameters
78
----------
79
file
80
Path to TOML configuration file
81
"""
82
83
def load(self) -> dict[str, Any]:
84
"""
85
Load configuration from TOML file.
86
87
Returns
88
-------
89
dict[str, Any]
90
Parsed TOML configuration
91
92
Raises
93
------
94
FileNotFoundError
95
If configuration file doesn't exist
96
tomllib.TOMLDecodeError
97
If TOML is malformed
98
"""
99
```
100
101
### YAML Configuration
102
103
Load configuration from YAML files.
104
105
```python { .api }
106
class Yaml(ConfigFromFile):
107
def __init__(self, file: Path):
108
"""
109
YAML configuration loader.
110
111
Parameters
112
----------
113
file
114
Path to YAML configuration file
115
"""
116
117
def load(self) -> dict[str, Any]:
118
"""
119
Load configuration from YAML file.
120
121
Returns
122
-------
123
dict[str, Any]
124
Parsed YAML configuration
125
126
Raises
127
------
128
FileNotFoundError
129
If configuration file doesn't exist
130
yaml.YAMLError
131
If YAML is malformed
132
"""
133
```
134
135
### Environment Variable Configuration
136
137
Load configuration from environment variables.
138
139
```python { .api }
140
class Env:
141
def __init__(
142
self,
143
prefix: str = "",
144
case_sensitive: bool = False,
145
nested_separator: str = "__"
146
):
147
"""
148
Environment variable configuration loader.
149
150
Parameters
151
----------
152
prefix
153
Prefix for environment variable names
154
case_sensitive
155
Whether environment variable names are case sensitive
156
nested_separator
157
Separator for nested configuration keys
158
"""
159
160
def load(self) -> dict[str, Any]:
161
"""
162
Load configuration from environment variables.
163
164
Returns
165
-------
166
dict[str, Any]
167
Configuration from environment variables
168
"""
169
```
170
171
### Configuration Protocol
172
173
Protocol that configuration loaders must implement.
174
175
```python { .api }
176
class ConfigProtocol:
177
def load(self) -> dict[str, Any]:
178
"""
179
Load configuration data.
180
181
Returns
182
-------
183
dict[str, Any]
184
Configuration as dictionary
185
"""
186
```
187
188
## Usage Examples
189
190
### JSON Configuration
191
192
```python
193
from cyclopts import App
194
from cyclopts.config import Json
195
from pathlib import Path
196
197
# config.json:
198
# {
199
# "database": {
200
# "host": "localhost",
201
# "port": 5432
202
# },
203
# "verbose": true
204
# }
205
206
app = App(config=[Json(Path("config.json"))])
207
208
@app.command
209
def connect(
210
host: str = "127.0.0.1",
211
port: int = 3306,
212
verbose: bool = False
213
):
214
"""Connect to database with config file support."""
215
if verbose:
216
print(f"Connecting to {host}:{port}")
217
```
218
219
### TOML Configuration
220
221
```python
222
from cyclopts import App
223
from cyclopts.config import Toml
224
from pathlib import Path
225
226
# config.toml:
227
# [server]
228
# host = "0.0.0.0"
229
# port = 8080
230
# debug = true
231
232
app = App(config=[Toml(Path("config.toml"))])
233
234
@app.command
235
def start_server(
236
host: str = "localhost",
237
port: int = 8000,
238
debug: bool = False
239
):
240
"""Start server with TOML configuration."""
241
print(f"Starting server on {host}:{port} (debug={debug})")
242
```
243
244
### Environment Variable Configuration
245
246
```python
247
from cyclopts import App
248
from cyclopts.config import Env
249
250
# Environment variables:
251
# MYAPP_DATABASE__HOST=prod-db.example.com
252
# MYAPP_DATABASE__PORT=5432
253
# MYAPP_VERBOSE=true
254
255
app = App(config=[Env(prefix="MYAPP_", nested_separator="__")])
256
257
@app.command
258
def deploy(
259
database_host: str = "localhost",
260
database_port: int = 5432,
261
verbose: bool = False
262
):
263
"""Deploy with environment configuration."""
264
if verbose:
265
print(f"Deploying to database at {database_host}:{database_port}")
266
```
267
268
### Multiple Configuration Sources
269
270
```python
271
from cyclopts import App
272
from cyclopts.config import Json, Env
273
from pathlib import Path
274
275
# Configuration precedence: CLI args > environment > config file
276
app = App(config=[
277
Json(Path("app.json")), # Loaded first (lowest priority)
278
Env(prefix="APP_") # Loaded second (higher priority)
279
])
280
281
@app.command
282
def run_job(
283
worker_count: int = 1,
284
timeout: float = 30.0,
285
output_dir: str = "./output"
286
):
287
"""Run job with multiple configuration sources."""
288
print(f"Running job with {worker_count} workers")
289
print(f"Timeout: {timeout}s, Output: {output_dir}")
290
```
291
292
### YAML Configuration with Nested Structure
293
294
```python
295
from cyclopts import App
296
from cyclopts.config import Yaml
297
from pathlib import Path
298
299
# config.yaml:
300
# logging:
301
# level: INFO
302
# file: app.log
303
# processing:
304
# batch_size: 100
305
# parallel: true
306
307
app = App(config=[Yaml(Path("config.yaml"))])
308
309
@app.command
310
def process_data(
311
logging_level: str = "WARNING",
312
logging_file: str = "default.log",
313
processing_batch_size: int = 50,
314
processing_parallel: bool = False
315
):
316
"""Process data with YAML configuration."""
317
print(f"Logging: {logging_level} -> {logging_file}")
318
print(f"Processing: batch_size={processing_batch_size}, parallel={processing_parallel}")
319
```
320
321
### Custom Configuration Loader
322
323
```python
324
from cyclopts import App
325
from cyclopts.config import ConfigFromFile
326
from pathlib import Path
327
import configparser
328
329
class IniConfig(ConfigFromFile):
330
"""Custom INI file configuration loader."""
331
332
def load(self) -> dict[str, Any]:
333
config = configparser.ConfigParser()
334
config.read(self.file)
335
336
result = {}
337
for section_name in config.sections():
338
section = {}
339
for key, value in config[section_name].items():
340
# Try to convert to appropriate types
341
if value.lower() in ('true', 'false'):
342
section[key] = value.lower() == 'true'
343
elif value.isdigit():
344
section[key] = int(value)
345
else:
346
section[key] = value
347
result[section_name] = section
348
return result
349
350
app = App(config=[IniConfig(Path("config.ini"))])
351
352
@app.command
353
def example(setting: str = "default"):
354
"""Example command with custom INI config."""
355
print(f"Setting: {setting}")
356
```