or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

arguments.mdcaching.mdconfiguration.mdcontrollers.mdextensions.mdfoundation.mdhooks.mdindex.mdinterface-handler.mdlogging.mdmail.mdoutput.mdplugins.mdtemplates.mdutilities.md

utilities.mddocs/

0

# Utility Functions

1

2

Cement provides a comprehensive collection of utility functions for common operations including file system operations, shell command execution, configuration helpers, and testing utilities.

3

4

## Capabilities

5

6

### Miscellaneous Utilities

7

8

Collection of general-purpose utility functions for common operations.

9

10

```python { .api }

11

def init_defaults(*sections: str) -> Dict[str, Any]:

12

"""

13

Create a standard dictionary for application configuration defaults.

14

15

Creates a nested dictionary structure with the specified sections.

16

Commonly used for setting up application configuration defaults.

17

18

Args:

19

*sections: Section names to create in the defaults dictionary

20

21

Returns:

22

Dictionary with nested sections for configuration defaults

23

24

Example:

25

config = init_defaults('myapp', 'database')

26

# Returns: {'myapp': {}, 'database': {}}

27

"""

28

29

def minimal_logger(namespace: str) -> logging.Logger:

30

"""

31

Create a basic logger instance for framework use.

32

33

Creates a minimal logger with basic configuration suitable for

34

framework internal logging and simple application logging needs.

35

36

Args:

37

namespace: Logger namespace/name

38

39

Returns:

40

Configured Logger instance

41

"""

42

43

def rando(salt: str = None) -> str:

44

"""

45

Generate a random hash string for various purposes.

46

47

Useful for testing, unique identifiers, or any time a random

48

string is required. Uses SHA256 for compatibility.

49

50

Args:

51

salt: Optional salt string. If None, uses random.random()

52

53

Returns:

54

Random hash string (32 characters)

55

56

Example:

57

random_id = rando('my_salt_string')

58

test_id = rando() # Uses random salt

59

"""

60

61

def is_true(item: Any) -> bool:

62

"""

63

Test if a value should be considered True.

64

65

Provides consistent boolean evaluation for configuration values

66

and user input, handling strings like 'true', 'yes', '1', etc.

67

68

Args:

69

item: Value to test for truthiness

70

71

Returns:

72

True if item should be considered True, False otherwise

73

74

Example:

75

is_true('true') # True

76

is_true('yes') # True

77

is_true('1') # True

78

is_true('false') # False

79

is_true(0) # False

80

"""

81

82

def wrap(text: str, width: int = 77, indent: str = '', long_words: bool = False, hyphens: bool = False) -> str:

83

"""

84

Wrap text to specified width with optional indentation.

85

86

Provides text wrapping functionality with control over line width,

87

indentation, and handling of long words and hyphenation.

88

89

Args:

90

text: Text to wrap

91

width: Maximum line width

92

indent: String to indent each line

93

long_words: Whether to break long words

94

hyphens: Whether to use hyphenation

95

96

Returns:

97

Wrapped text string

98

"""

99

100

def get_random_string(length: int = 12) -> str:

101

"""

102

Generate a random string of specified length.

103

104

Creates random strings suitable for temporary identifiers,

105

test data, or other purposes requiring random text.

106

107

Args:

108

length: Length of random string to generate

109

110

Returns:

111

Random string of specified length

112

"""

113

```

114

115

### File System Utilities

116

117

File system operations and temporary file/directory management.

118

119

```python { .api }

120

class Tmp:

121

"""

122

Context manager for temporary directory and file creation with cleanup.

123

124

Provides creation and automatic cleanup of temporary directories and files.

125

Designed to be used with the 'with' statement for automatic resource management.

126

"""

127

128

def __init__(self, cleanup: bool = True, suffix: str = '', prefix: str = '', dir: str = None) -> None:

129

"""

130

Initialize temporary file/directory manager.

131

132

Args:

133

cleanup: Whether to delete temp directory/file on exit

134

suffix: Suffix for temp directory and file names

135

prefix: Prefix for temp directory and file names

136

dir: Parent directory for temp directory/file creation

137

"""

138

139

def __enter__(self) -> 'Tmp':

140

"""

141

Enter context manager and create temporary directory/file.

142

143

Returns:

144

Self with populated dir and file attributes

145

"""

146

147

def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:

148

"""

149

Exit context manager and cleanup temporary directory/file if requested.

150

151

Args:

152

exc_type: Exception type (if any)

153

exc_val: Exception value (if any)

154

exc_tb: Exception traceback (if any)

155

"""

156

157

@property

158

def dir(self) -> str:

159

"""Path to the temporary directory."""

160

161

@property

162

def file(self) -> str:

163

"""Path to the temporary file."""

164

165

def abspath(path: str) -> str:

166

"""

167

Get absolute path with user directory expansion.

168

169

Expands user directory (~) and converts to absolute path.

170

171

Args:

172

path: File or directory path

173

174

Returns:

175

Absolute path string

176

"""

177

178

def backup(path: str, suffix: str = '.bak') -> str:

179

"""

180

Create a backup copy of a file or directory.

181

182

Creates a backup copy with the specified suffix. If backup

183

already exists, appends a number to make it unique.

184

185

Args:

186

path: Path to file or directory to backup

187

suffix: Suffix to append to backup name

188

189

Returns:

190

Path to created backup

191

"""

192

193

def cleanup(*paths: str) -> None:

194

"""

195

Remove files and directories.

196

197

Safely removes the specified files and directories,

198

handling both files and directories recursively.

199

200

Args:

201

*paths: Paths to files/directories to remove

202

"""

203

```

204

205

### Shell Utilities

206

207

Shell command execution and process management utilities.

208

209

```python { .api }

210

def cmd(command: str, capture: bool = True, *args: Any, **kwargs: Any) -> Union[Tuple[str, str, int], int]:

211

"""

212

Execute shell command with optional output capture.

213

214

Wrapper around exec_cmd and exec_cmd2 that provides a unified

215

interface for shell command execution with flexible output handling.

216

217

Args:

218

command: Command string to execute

219

capture: Whether to capture and return output

220

*args: Additional arguments passed to Popen

221

**kwargs: Additional keyword arguments passed to Popen

222

223

Returns:

224

Tuple of (stdout, stderr, return_code) if capture=True

225

Return code only if capture=False

226

227

Example:

228

# Capture output

229

out, err, code = cmd('ls -la')

230

231

# Just get return code

232

code = cmd('touch /tmp/test', capture=False)

233

"""

234

235

def exec_cmd(command: str, *args: Any, **kwargs: Any) -> Tuple[str, str, int]:

236

"""

237

Execute command and capture output.

238

239

Executes shell command and captures both stdout and stderr,

240

returning all output along with the exit code.

241

242

Args:

243

command: Command string to execute

244

*args: Additional arguments passed to Popen

245

**kwargs: Additional keyword arguments passed to Popen

246

247

Returns:

248

Tuple of (stdout, stderr, return_code)

249

"""

250

251

def exec_cmd2(command: str, *args: Any, **kwargs: Any) -> int:

252

"""

253

Execute command without capturing output.

254

255

Executes shell command allowing output to go directly to

256

console, returning only the exit code.

257

258

Args:

259

command: Command string to execute

260

*args: Additional arguments passed to Popen

261

**kwargs: Additional keyword arguments passed to Popen

262

263

Returns:

264

Command exit code

265

"""

266

267

class Prompt:

268

"""

269

Interactive prompting utilities for user input.

270

271

Provides methods for prompting users for various types of input

272

including text, boolean choices, and multiple choice selections.

273

"""

274

275

def prompt(self, text: str, default: str = None) -> str:

276

"""

277

Prompt user for text input.

278

279

Args:

280

text: Prompt text to display

281

default: Default value if user enters nothing

282

283

Returns:

284

User input string or default value

285

"""

286

287

def prompt_bool(self, text: str, default: bool = None) -> bool:

288

"""

289

Prompt user for boolean (yes/no) input.

290

291

Args:

292

text: Prompt text to display

293

default: Default boolean value

294

295

Returns:

296

Boolean value based on user input

297

"""

298

299

def prompt_options(self, text: str, options: List[str], default: str = None) -> str:

300

"""

301

Prompt user to select from multiple options.

302

303

Args:

304

text: Prompt text to display

305

options: List of available options

306

default: Default option if user enters nothing

307

308

Returns:

309

Selected option string

310

"""

311

```

312

313

### Testing Utilities

314

315

Utilities specifically designed for testing cement applications.

316

317

```python { .api }

318

class TestApp(App):

319

"""

320

Application class designed for testing cement applications.

321

322

Extends the base App class with testing-specific functionality

323

and simplified configuration for test environments.

324

"""

325

326

def with_app(app_class: Type[App] = None, **app_kwargs: Any) -> Callable:

327

"""

328

Decorator for testing functions that need an application instance.

329

330

Provides a cement application instance to test functions,

331

handling setup and cleanup automatically.

332

333

Args:

334

app_class: Application class to instantiate (defaults to TestApp)

335

**app_kwargs: Keyword arguments passed to app constructor

336

337

Returns:

338

Decorator function that injects app instance

339

340

Example:

341

@with_app()

342

def test_my_function(app):

343

app.setup()

344

# Test code here

345

app.run()

346

"""

347

```

348

349

### Version Utilities

350

351

Version information and management utilities.

352

353

```python { .api }

354

def get_version() -> str:

355

"""

356

Get the cement framework version string.

357

358

Returns the current version of the cement framework.

359

360

Returns:

361

Version string (e.g., '3.0.14')

362

"""

363

364

VERSION: Tuple[int, int, int] = (3, 0, 14)

365

"""Framework version tuple (major, minor, patch)"""

366

```

367

368

## Usage Examples

369

370

### File System Operations

371

372

```python

373

from cement.utils import fs

374

import os

375

376

# Using temporary directory context manager

377

with fs.Tmp() as tmp:

378

print(f"Temp directory: {tmp.dir}")

379

print(f"Temp file: {tmp.file}")

380

381

# Create some files in temp directory

382

test_file = os.path.join(tmp.dir, 'test.txt')

383

with open(test_file, 'w') as f:

384

f.write('Hello World!')

385

386

# Use temp file

387

with open(tmp.file, 'w') as f:

388

f.write('Temporary data')

389

390

# Directory and file are automatically cleaned up on exit

391

392

# Working with paths

393

home_config = fs.abspath('~/.myapp.conf')

394

print(f"Config path: {home_config}")

395

396

# Creating backups

397

original_file = '/path/to/important.txt'

398

if os.path.exists(original_file):

399

backup_path = fs.backup(original_file)

400

print(f"Created backup: {backup_path}")

401

402

# Cleanup multiple paths

403

fs.cleanup('/tmp/file1.txt', '/tmp/file2.txt', '/tmp/test_dir')

404

```

405

406

### Shell Command Execution

407

408

```python

409

from cement.utils import shell

410

411

# Execute command and capture output

412

stdout, stderr, exit_code = shell.cmd('ls -la /tmp')

413

print(f"Output: {stdout}")

414

print(f"Errors: {stderr}")

415

print(f"Exit code: {exit_code}")

416

417

# Execute command without capturing output (output goes to console)

418

exit_code = shell.cmd('echo "Hello World"', capture=False)

419

print(f"Command completed with exit code: {exit_code}")

420

421

# Using exec_cmd directly

422

out, err, code = shell.exec_cmd('ps aux | grep python')

423

if code == 0:

424

print("Python processes found:")

425

print(out)

426

427

# Using exec_cmd2 for commands that need user interaction

428

exit_code = shell.exec_cmd2('vim /tmp/test.txt') # Opens vim directly

429

```

430

431

### Interactive Prompting

432

433

```python

434

from cement.utils.shell import Prompt

435

436

prompt = Prompt()

437

438

# Basic text input

439

name = prompt.prompt('Enter your name: ', default='Anonymous')

440

print(f"Hello, {name}!")

441

442

# Boolean input

443

confirm = prompt.prompt_bool('Continue? [y/N]: ', default=False)

444

if confirm:

445

print("Continuing...")

446

else:

447

print("Aborted.")

448

449

# Multiple choice

450

options = ['production', 'staging', 'development']

451

env = prompt.prompt_options('Select environment: ', options, default='development')

452

print(f"Selected environment: {env}")

453

```

454

455

### Configuration Helpers

456

457

```python

458

from cement.utils.misc import init_defaults, is_true, rando

459

460

# Initialize configuration structure

461

config = init_defaults('app', 'database', 'logging')

462

config['app']['debug'] = False

463

config['app']['name'] = 'MyApp'

464

config['database']['host'] = 'localhost'

465

config['database']['port'] = 5432

466

config['logging']['level'] = 'INFO'

467

468

print(f"Config structure: {config}")

469

470

# Test boolean values from various sources

471

user_input = 'yes'

472

debug_enabled = is_true(user_input)

473

print(f"Debug enabled: {debug_enabled}")

474

475

# Generate random identifiers

476

session_id = rando('user_session')

477

test_id = rando()

478

print(f"Session ID: {session_id}")

479

print(f"Test ID: {test_id}")

480

```

481

482

### Testing Utilities

483

484

```python

485

from cement.utils.test import TestApp, with_app

486

from cement import Controller, ex

487

488

class TestController(Controller):

489

class Meta:

490

label = 'test'

491

492

@ex(help='test command')

493

def hello(self):

494

return 'Hello from test!'

495

496

# Using TestApp directly

497

def test_app_functionality():

498

with TestApp() as app:

499

app.setup()

500

assert app.config.get('myapp', 'debug') == True

501

app.run()

502

503

# Using with_app decorator

504

@with_app(TestApp, handlers=[TestController])

505

def test_controller(app):

506

app.setup()

507

508

# Test controller registration

509

assert 'test' in app.handler.list('controller')

510

511

# Get controller instance

512

controller = app.handler.get('controller', 'test')(app)

513

result = controller.hello()

514

assert result == 'Hello from test!'

515

516

# Run tests

517

test_app_functionality()

518

test_controller()

519

```

520

521

### Text Processing

522

523

```python

524

from cement.utils.misc import wrap, get_random_string

525

526

# Text wrapping

527

long_text = "This is a very long line of text that needs to be wrapped to fit within specific line length constraints for better readability and formatting."

528

529

wrapped = wrap(long_text, width=50, indent=' ')

530

print("Wrapped text:")

531

print(wrapped)

532

533

# Generate random strings for testing

534

test_data = []

535

for i in range(5):

536

random_str = get_random_string(8)

537

test_data.append(f"test_{random_str}")

538

539

print(f"Test data: {test_data}")

540

```

541

542

### Version Information

543

544

```python

545

from cement.utils.version import get_version, VERSION

546

547

# Get version information

548

version_string = get_version()

549

print(f"Cement version: {version_string}")

550

551

major, minor, patch = VERSION

552

print(f"Version components: {major}.{minor}.{patch}")

553

554

# Version comparison

555

if VERSION >= (3, 0, 0):

556

print("Using cement 3.0+")

557

```