or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-parsing.mdcollections.mdconfiguration.mdindex.mdsubprocess-runners.mdtask-execution.mdwatchers.md

configuration.mddocs/

0

# Configuration Management

1

2

Invoke provides a sophisticated multi-source configuration system that supports files, environment variables, command-line arguments, and Python dictionaries with hierarchical merging and attribute-style access.

3

4

## Capabilities

5

6

### Config Class

7

8

Main configuration management system with multi-source loading and hierarchical merging.

9

10

```python { .api }

11

class Config:

12

"""

13

Configuration management with multi-source loading and merging.

14

15

Supports loading from:

16

- Default values

17

- System configuration files

18

- User configuration files

19

- Project configuration files

20

- Environment variables

21

- Runtime overrides

22

- Collection-specific configuration

23

24

Attributes:

25

- _defaults (dict): Default configuration values

26

- _overrides (dict): Runtime override values

27

- _system (dict): System-level configuration

28

- _user (dict): User-level configuration

29

- _project (dict): Project-level configuration

30

- _runtime (dict): Runtime configuration

31

- _collection (dict): Collection-specific configuration

32

- _env (dict): Environment variable configuration

33

"""

34

35

def __init__(self, defaults=None, overrides=None, lazy=False, runtime_path=None, system_prefix=None, user_prefix=None, project_location=None, env_prefix=None, file_prefix=None):

36

"""

37

Initialize Config object.

38

39

Parameters:

40

- defaults (dict, optional): Default configuration values

41

- overrides (dict, optional): Runtime override values

42

- lazy (bool): Whether to defer configuration loading

43

- runtime_path (str, optional): Runtime configuration file path

44

- system_prefix (str, optional): System config file prefix

45

- user_prefix (str, optional): User config file prefix

46

- project_location (str, optional): Project root directory

47

- env_prefix (str, optional): Environment variable prefix

48

- file_prefix (str, optional): Configuration file prefix

49

"""

50

51

@classmethod

52

def global_defaults(cls):

53

"""

54

Get global default configuration values.

55

56

Returns:

57

dict: Global default configuration

58

"""

59

60

def load_defaults(self, merge=True):

61

"""

62

Load default configuration values.

63

64

Parameters:

65

- merge (bool): Whether to merge with existing configuration

66

67

Returns:

68

Config: Self for method chaining

69

"""

70

71

def load_overrides(self, merge=True):

72

"""

73

Load runtime override configuration.

74

75

Parameters:

76

- merge (bool): Whether to merge with existing configuration

77

78

Returns:

79

Config: Self for method chaining

80

"""

81

82

def load_system(self, merge=True):

83

"""

84

Load system-level configuration files.

85

86

Parameters:

87

- merge (bool): Whether to merge with existing configuration

88

89

Returns:

90

Config: Self for method chaining

91

"""

92

93

def load_user(self, merge=True):

94

"""

95

Load user-level configuration files.

96

97

Parameters:

98

- merge (bool): Whether to merge with existing configuration

99

100

Returns:

101

Config: Self for method chaining

102

"""

103

104

def load_project(self, merge=True):

105

"""

106

Load project-level configuration files.

107

108

Parameters:

109

- merge (bool): Whether to merge with existing configuration

110

111

Returns:

112

Config: Self for method chaining

113

"""

114

115

def load_runtime(self, merge=True):

116

"""

117

Load runtime configuration file.

118

119

Parameters:

120

- merge (bool): Whether to merge with existing configuration

121

122

Returns:

123

Config: Self for method chaining

124

"""

125

126

def load_shell_env(self, merge=True):

127

"""

128

Load configuration from environment variables.

129

130

Parameters:

131

- merge (bool): Whether to merge with existing configuration

132

133

Returns:

134

Config: Self for method chaining

135

"""

136

137

def load_collection(self, collection, merge=True):

138

"""

139

Load collection-specific configuration.

140

141

Parameters:

142

- collection (Collection): Task collection

143

- merge (bool): Whether to merge with existing configuration

144

145

Returns:

146

Config: Self for method chaining

147

"""

148

149

def set_project_location(self, path):

150

"""

151

Set project root directory for configuration files.

152

153

Parameters:

154

- path (str): Project root directory path

155

"""

156

157

def set_runtime_path(self, path):

158

"""

159

Set runtime configuration file path.

160

161

Parameters:

162

- path (str): Runtime configuration file path

163

"""

164

165

def merge(self, *dicts):

166

"""

167

Merge configuration dictionaries hierarchically.

168

169

Parameters:

170

- *dicts: Configuration dictionaries to merge

171

172

Returns:

173

Config: New merged configuration

174

"""

175

176

def clone(self, into=None):

177

"""

178

Create a copy of this configuration.

179

180

Parameters:

181

- into (type, optional): Class to clone into

182

183

Returns:

184

Config: Cloned configuration object

185

"""

186

```

187

188

### DataProxy Class

189

190

Base class providing nested dictionary access with attribute-style syntax.

191

192

```python { .api }

193

class DataProxy:

194

"""

195

Nested dictionary with attribute-style access.

196

197

Provides both dict-style (obj['key']) and attribute-style (obj.key)

198

access to nested configuration data.

199

"""

200

201

@classmethod

202

def from_data(cls, data):

203

"""

204

Create DataProxy from dictionary data.

205

206

Parameters:

207

- data (dict): Dictionary data to wrap

208

209

Returns:

210

DataProxy: Proxy object for the data

211

"""

212

213

def __getitem__(self, key):

214

"""Get item using dict-style access."""

215

216

def __setitem__(self, key, value):

217

"""Set item using dict-style access."""

218

219

def __delitem__(self, key):

220

"""Delete item using dict-style access."""

221

222

def __contains__(self, key):

223

"""Test membership using 'in' operator."""

224

225

def __iter__(self):

226

"""Iterate over keys."""

227

228

def __len__(self):

229

"""Get number of top-level keys."""

230

231

def __getattr__(self, key):

232

"""Get item using attribute-style access."""

233

234

def __setattr__(self, key, value):

235

"""Set item using attribute-style access."""

236

237

def get(self, key, default=None):

238

"""Get item with default value."""

239

240

def pop(self, key, *args):

241

"""Remove and return item."""

242

243

def popitem(self):

244

"""Remove and return arbitrary item."""

245

246

def clear(self):

247

"""Remove all items."""

248

249

def update(self, other):

250

"""Update with items from another mapping."""

251

252

def keys(self):

253

"""Get view of keys."""

254

255

def values(self):

256

"""Get view of values."""

257

258

def items(self):

259

"""Get view of key-value pairs."""

260

```

261

262

### Configuration Utility Functions

263

264

Helper functions for configuration manipulation.

265

266

```python { .api }

267

def merge_dicts(base, updates):

268

"""

269

Recursively merge configuration dictionaries.

270

271

Parameters:

272

- base (dict): Base configuration dictionary

273

- updates (dict): Updates to apply

274

275

Returns:

276

dict: Merged configuration dictionary

277

"""

278

279

def copy_dict(source):

280

"""

281

Deep copy a configuration dictionary.

282

283

Parameters:

284

- source (dict): Dictionary to copy

285

286

Returns:

287

dict: Deep copy of source dictionary

288

"""

289

290

def excise(dict_, keypath):

291

"""

292

Remove nested key from dictionary.

293

294

Parameters:

295

- dict_ (dict): Dictionary to modify

296

- keypath (str): Dot-separated key path (e.g., 'section.subsection.key')

297

298

Returns:

299

any: Removed value

300

"""

301

302

def obliterate(base, deletions):

303

"""

304

Remove multiple nested keys from dictionary.

305

306

Parameters:

307

- base (dict): Dictionary to modify

308

- deletions (list): List of dot-separated key paths to remove

309

310

Returns:

311

dict: Modified dictionary

312

"""

313

```

314

315

## Usage Examples

316

317

### Basic Configuration Usage

318

319

```python

320

from invoke import Config

321

322

# Create configuration with defaults

323

config = Config({

324

'run': {

325

'echo': True,

326

'pty': False

327

},

328

'sudo': {

329

'password': None

330

}

331

})

332

333

# Access configuration values

334

print(config.run.echo) # True

335

print(config['run']['pty']) # False

336

337

# Modify configuration

338

config.run.timeout = 30

339

config['sudo']['password'] = 'secret'

340

```

341

342

### Multi-source Configuration Loading

343

344

```python

345

from invoke import Config

346

347

# Load from all default sources

348

config = Config()

349

config.load_defaults()

350

config.load_system() # /etc/invoke.yaml

351

config.load_user() # ~/.invoke.yaml

352

config.load_project() # ./invoke.yaml

353

config.load_shell_env() # Environment variables

354

355

# Check final configuration

356

print(f"Echo enabled: {config.run.echo}")

357

```

358

359

### Configuration Files

360

361

Create configuration files in YAML or JSON format:

362

363

**invoke.yaml**:

364

```yaml

365

run:

366

echo: true

367

pty: false

368

warn: false

369

370

sudo:

371

password: null

372

prompt_for_password: true

373

374

tasks:

375

auto_dash_names: true

376

collection_name: 'tasks'

377

```

378

379

**invoke.json**:

380

```json

381

{

382

"run": {

383

"echo": true,

384

"pty": false,

385

"shell": "/bin/bash"

386

},

387

"sudo": {

388

"password": null

389

}

390

}

391

```

392

393

### Environment Variable Configuration

394

395

```python

396

import os

397

from invoke import Config

398

399

# Set environment variables (prefix with INVOKE_)

400

os.environ['INVOKE_RUN_ECHO'] = 'false'

401

os.environ['INVOKE_RUN_PTY'] = 'true'

402

os.environ['INVOKE_SUDO_PASSWORD'] = 'mypassword'

403

404

# Load configuration including environment

405

config = Config()

406

config.load_defaults()

407

config.load_shell_env()

408

409

print(config.run.echo) # False (from env var)

410

print(config.run.pty) # True (from env var)

411

```

412

413

### Configuration Merging and Cloning

414

415

```python

416

from invoke import Config, merge_dicts

417

418

# Base configuration

419

base_config = Config({

420

'run': {'echo': True, 'pty': False},

421

'sudo': {'password': None}

422

})

423

424

# Override configuration

425

overrides = {

426

'run': {'pty': True, 'timeout': 30},

427

'new_section': {'enabled': True}

428

}

429

430

# Merge configurations

431

merged = base_config.merge(overrides)

432

print(merged.run.echo) # True (from base)

433

print(merged.run.pty) # True (from override)

434

print(merged.run.timeout) # 30 (from override)

435

436

# Clone configuration

437

cloned = base_config.clone()

438

cloned.run.echo = False

439

print(base_config.run.echo) # True (original unchanged)

440

print(cloned.run.echo) # False (clone modified)

441

```

442

443

### Context Integration

444

445

```python

446

from invoke import Context, Config

447

448

# Create custom configuration

449

config = Config({

450

'run': {

451

'echo': True,

452

'pty': True,

453

'shell': '/bin/zsh'

454

}

455

})

456

457

# Use with context

458

ctx = Context(config=config)

459

result = ctx.run("echo 'Hello World'") # Uses custom config

460

```

461

462

### Task-specific Configuration

463

464

```python

465

from invoke import task, Context

466

467

@task

468

def deploy(ctx, env='staging'):

469

"""Deploy with environment-specific configuration."""

470

471

# Access configuration for current environment

472

db_host = ctx.config.environments[env].database.host

473

api_key = ctx.config.environments[env].api_key

474

475

ctx.run(f"deploy.sh --host {db_host} --key {api_key}")

476

477

# Configuration file (invoke.yaml):

478

# environments:

479

# staging:

480

# database:

481

# host: staging-db.example.com

482

# api_key: staging-key

483

# production:

484

# database:

485

# host: prod-db.example.com

486

# api_key: prod-key

487

```

488

489

### Configuration Validation

490

491

```python

492

from invoke import Config

493

from invoke.exceptions import UncastableEnvVar, AmbiguousEnvVar

494

495

try:

496

config = Config()

497

config.load_shell_env()

498

except UncastableEnvVar as e:

499

print(f"Invalid environment variable: {e}")

500

except AmbiguousEnvVar as e:

501

print(f"Ambiguous environment variable: {e}")

502

```