or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-commands.mdconfiguration.mdenvironment.mdhooks-plugins.mdindex.mdtask-execution.mdutilities.md

utilities.mddocs/

0

# Utilities

1

2

Core utilities for encryption, file operations, string processing, serialization, and output formatting. These utilities provide common functionality used throughout Tutor for security, data processing, and user interaction.

3

4

## Capabilities

5

6

### Encryption and Security

7

8

Password hashing and verification using bcrypt for secure credential storage.

9

10

```python { .api }

11

def encrypt(text: str) -> str:

12

"""

13

Encrypt text using bcrypt hashing for secure password storage.

14

15

Args:

16

text (str): Plain text to encrypt

17

18

Returns:

19

str: Bcrypt hash of the input text

20

"""

21

22

def verify_encrypted(encrypted: str, text: str) -> bool:

23

"""

24

Verify that plain text matches the encrypted hash.

25

26

Args:

27

encrypted (str): Previously encrypted hash

28

text (str): Plain text to verify

29

30

Returns:

31

bool: True if text matches the encrypted hash

32

"""

33

```

34

35

### File System Operations

36

37

Utilities for managing directories and file paths.

38

39

```python { .api }

40

def ensure_file_directory_exists(path: str) -> None:

41

"""

42

Create parent directory for a file path if it doesn't exist.

43

44

Args:

45

path (str): File path whose parent directory should be created

46

"""

47

48

def ensure_directory_exists(path: str) -> None:

49

"""

50

Create directory and any necessary parent directories.

51

52

Args:

53

path (str): Directory path to create

54

"""

55

```

56

57

### String and Data Processing

58

59

Utilities for generating random data and processing service configurations.

60

61

```python { .api }

62

def random_string(length: int) -> str:

63

"""

64

Generate a random string of specified length using alphanumeric characters.

65

66

Args:

67

length (int): Length of random string to generate

68

69

Returns:

70

str: Random alphanumeric string

71

"""

72

73

def list_if(services: List[Tuple[str, bool]]) -> str:

74

"""

75

Generate JSON array string of service names where the boolean is True.

76

77

Args:

78

services (List[Tuple[str, bool]]): List of (service_name, enabled) tuples

79

80

Returns:

81

str: JSON array string of enabled service names

82

"""

83

84

def common_domain(d1: str, d2: str) -> str:

85

"""

86

Find the common domain suffix between two domain names.

87

88

Args:

89

d1 (str): First domain name

90

d2 (str): Second domain name

91

92

Returns:

93

str: Common domain suffix

94

"""

95

96

def reverse_host(domain: str) -> str:

97

"""

98

Reverse domain name in Java package style (com.example.subdomain).

99

100

Args:

101

domain (str): Domain name to reverse

102

103

Returns:

104

str: Reversed domain name

105

"""

106

```

107

108

### System Information

109

110

Utilities for checking system state and user permissions.

111

112

```python { .api }

113

def is_root() -> bool:

114

"""

115

Check if the current process is running as root user.

116

117

Returns:

118

bool: True if running as root

119

"""

120

```

121

122

### YAML Serialization

123

124

YAML loading and saving with consistent formatting and multiple document support.

125

126

```python { .api }

127

def load(stream: Union[str, IO[str]]) -> Any:

128

"""

129

Load YAML content from string or file stream.

130

131

Args:

132

stream (Union[str, IO[str]]): YAML content string or file stream

133

134

Returns:

135

Any: Parsed YAML data

136

"""

137

138

def load_all(stream: str) -> Iterator[Any]:

139

"""

140

Load multiple YAML documents from string.

141

142

Args:

143

stream (str): YAML content string with multiple documents

144

145

Returns:

146

Iterator[Any]: Iterator of parsed YAML documents

147

"""

148

149

def dump_all(documents: Sequence[Any], fileobj: TextIOWrapper) -> None:

150

"""

151

Write multiple YAML documents to a file.

152

153

Args:

154

documents (Sequence[Any]): Sequence of objects to serialize

155

fileobj (TextIOWrapper): File object to write to

156

"""

157

158

def dump(content: Any, fileobj: TextIOWrapper) -> None:

159

"""

160

Write single YAML document to a file.

161

162

Args:

163

content (Any): Object to serialize

164

fileobj (TextIOWrapper): File object to write to

165

"""

166

167

def dumps(content: Any) -> str:

168

"""

169

Serialize object to YAML string.

170

171

Args:

172

content (Any): Object to serialize

173

174

Returns:

175

str: YAML string representation

176

"""

177

```

178

179

### String Formatting

180

181

Special formatting for configuration values and output display.

182

183

```python { .api }

184

def str_format(content: Any) -> str:

185

"""

186

Format values for string output with special handling for booleans and None.

187

188

Args:

189

content (Any): Value to format

190

191

Returns:

192

str: Formatted string (booleans as lowercase, None as empty string)

193

"""

194

```

195

196

### Output Formatting and Styling

197

198

Console output styling with colors and semantic formatting for different message types.

199

200

```python { .api }

201

def title(text: str) -> str:

202

"""

203

Format text as a title with green styling.

204

205

Args:

206

text (str): Text to format

207

208

Returns:

209

str: Styled title text

210

"""

211

212

def info(text: str) -> str:

213

"""

214

Format text as informational message in blue.

215

216

Args:

217

text (str): Text to format

218

219

Returns:

220

str: Styled info text

221

"""

222

223

def error(text: str) -> str:

224

"""

225

Format text as error message in red.

226

227

Args:

228

text (str): Text to format

229

230

Returns:

231

str: Styled error text

232

"""

233

234

def command(text: str) -> str:

235

"""

236

Format text as command in magenta.

237

238

Args:

239

text (str): Text to format

240

241

Returns:

242

str: Styled command text

243

"""

244

245

def question(text: str) -> str:

246

"""

247

Format text as question in yellow.

248

249

Args:

250

text (str): Text to format

251

252

Returns:

253

str: Styled question text

254

"""

255

256

def alert(text: str) -> str:

257

"""

258

Format text as alert with warning emoji.

259

260

Args:

261

text (str): Text to format

262

263

Returns:

264

str: Styled alert text with emoji

265

"""

266

```

267

268

### Bind Mount Management

269

270

Functions for parsing and managing bind mounts between host and container directories.

271

272

```python { .api }

273

def get_mounts(config: Config) -> list[str]:

274

"""

275

Get the list of bind mounts from configuration.

276

277

Args:

278

config (Config): Configuration dictionary

279

280

Returns:

281

list[str]: List of mount specifications

282

"""

283

284

def iter_mounts(user_mounts: list[str], *names: str) -> Iterable[str]:

285

"""

286

Iterate bind-mounts available to given compose services.

287

288

Args:

289

user_mounts (list[str]): List of user mount specifications

290

*names (str): Service names to filter mounts for

291

292

Yields:

293

str: Mount strings in "host_path:container_path" format

294

"""

295

296

def parse_mount(value: str) -> list[tuple[str, str, str]]:

297

"""

298

Parse mount argument into (service, host_path, container_path) tuples.

299

300

Supports explicit format: "service1,service2:/host/path:/container/path"

301

And implicit format: "/host/path" (uses COMPOSE_MOUNTS filter)

302

303

Args:

304

value (str): Mount specification string

305

306

Returns:

307

list[tuple[str, str, str]]: List of (service, host_path, container_path)

308

"""

309

```

310

311

### YAML Serialization

312

313

YAML parsing and serialization utilities using PyYAML SafeLoader.

314

315

```python { .api }

316

def load(stream: Union[str, IO[str]]) -> Any:

317

"""

318

Load YAML from string or file stream.

319

320

Args:

321

stream (Union[str, IO[str]]): YAML content or file stream

322

323

Returns:

324

Any: Parsed YAML content

325

"""

326

327

def load_all(stream: str) -> Iterator[Any]:

328

"""

329

Load multiple YAML documents from string.

330

331

Args:

332

stream (str): YAML content with multiple documents

333

334

Yields:

335

Any: Each parsed YAML document

336

"""

337

338

def dump(content: Any, fileobj: TextIOWrapper) -> None:

339

"""

340

Write content as YAML to file stream.

341

342

Args:

343

content (Any): Content to serialize

344

fileobj (TextIOWrapper): File stream to write to

345

"""

346

347

def dumps(content: Any) -> str:

348

"""

349

Serialize content to YAML string.

350

351

Args:

352

content (Any): Content to serialize

353

354

Returns:

355

str: YAML string representation

356

"""

357

358

def parse_key_value(text: str) -> Optional[tuple[str, Any]]:

359

"""

360

Parse KEY=YAML_VALUE command line arguments.

361

362

Args:

363

text (str): Command line argument string

364

365

Returns:

366

Optional[tuple[str, Any]]: (key, parsed_value) or None if invalid

367

"""

368

```

369

370

### Output Functions

371

372

Console output functions that combine styling with printing.

373

374

```python { .api }

375

def echo_info(text: str) -> None:

376

"""

377

Print informational message to stdout.

378

379

Args:

380

text (str): Message to print

381

"""

382

383

def echo_error(text: str) -> None:

384

"""

385

Print error message to stderr.

386

387

Args:

388

text (str): Error message to print

389

"""

390

391

def echo_alert(text: str) -> None:

392

"""

393

Print alert message to stderr.

394

395

Args:

396

text (str): Alert message to print

397

"""

398

399

def echo(text: str, err: bool = False) -> None:

400

"""

401

Print text to stdout or stderr.

402

403

Args:

404

text (str): Text to print

405

err (bool): Whether to print to stderr instead of stdout

406

"""

407

```

408

409

## Type Definitions

410

411

### Configuration Types

412

413

Core type definitions for configuration management.

414

415

```python { .api }

416

# Union type for all possible configuration values

417

ConfigValue = Union[str, float, None, bool, List[str], List[Any], Dict[str, Any], Dict[Any, Any]]

418

419

# Configuration dictionary type

420

Config = Dict[str, ConfigValue]

421

422

def cast_config(config: Any) -> Config:

423

"""

424

Validate and cast input to Config type.

425

426

Args:

427

config (Any): Input to validate as configuration

428

429

Returns:

430

Config: Validated configuration dictionary

431

432

Raises:

433

TutorError: If input is not a valid configuration

434

"""

435

436

def get_typed(config: dict, key: str, expected_type: type[T], default: Optional[T] = None) -> T:

437

"""

438

Get typed value from configuration dictionary with default fallback.

439

440

Args:

441

config (dict): Configuration dictionary

442

key (str): Configuration key to retrieve

443

expected_type (type[T]): Expected type of the value

444

default (Optional[T]): Default value if key is missing

445

446

Returns:

447

T: Typed configuration value

448

449

Raises:

450

TutorError: If value exists but is not of expected type

451

"""

452

```

453

454

### Exception Types

455

456

Base exception class for Tutor-specific errors.

457

458

```python { .api }

459

class TutorError(Exception):

460

"""

461

Base exception class for all Tutor-specific errors.

462

463

Used for configuration errors, deployment failures, plugin issues, etc.

464

"""

465

pass

466

```

467

468

## Usage Examples

469

470

### Encryption and Security

471

472

```python

473

from tutor.utils import encrypt, verify_encrypted

474

475

# Encrypt a password

476

password = "my_secure_password"

477

encrypted = encrypt(password)

478

479

# Later verify the password

480

is_valid = verify_encrypted(encrypted, "my_secure_password") # True

481

is_invalid = verify_encrypted(encrypted, "wrong_password") # False

482

```

483

484

### File Operations

485

486

```python

487

from tutor.utils import ensure_file_directory_exists, ensure_directory_exists

488

489

# Ensure parent directory exists before creating file

490

file_path = "/path/to/deep/directory/config.yml"

491

ensure_file_directory_exists(file_path)

492

493

# Create directory structure

494

ensure_directory_exists("/path/to/new/directory")

495

```

496

497

### String Processing

498

499

```python

500

from tutor.utils import random_string, list_if, common_domain, reverse_host

501

502

# Generate random password

503

password = random_string(32)

504

505

# Process service list

506

services = [("lms", True), ("cms", True), ("forum", False)]

507

enabled_services = list_if(services) # '["lms", "cms"]'

508

509

# Domain processing

510

common = common_domain("learn.example.com", "studio.example.com") # "example.com"

511

reversed = reverse_host("learn.example.com") # "com.example.learn"

512

```

513

514

### YAML Operations

515

516

```python

517

from tutor.serialize import load, dumps, dump

518

from tutor.utils import ensure_file_directory_exists

519

520

# Load YAML configuration

521

with open("config.yml", "r") as f:

522

config = load(f)

523

524

# Serialize to string

525

yaml_str = dumps({"key": "value", "list": [1, 2, 3]})

526

527

# Save to file

528

ensure_file_directory_exists("output/config.yml")

529

with open("output/config.yml", "w") as f:

530

dump(config, f)

531

```

532

533

### Output Formatting

534

535

```python

536

from tutor.fmt import echo_info, echo_error, echo_alert, title, error

537

538

# Print styled messages

539

echo_info("Configuration loaded successfully")

540

echo_error("Failed to connect to database")

541

echo_alert("Running as root is not recommended")

542

543

# Create styled strings

544

header = title("Open edX Platform Status")

545

error_msg = error("Service unavailable")

546

print(header)

547

print(error_msg)

548

```

549

550

### Configuration Type Handling

551

552

```python

553

from tutor.types import cast_config, get_typed, TutorError

554

555

# Validate configuration

556

try:

557

config = cast_config({"PLATFORM_NAME": "My Platform", "HTTP_PORT": 80})

558

except TutorError as e:

559

print(f"Invalid configuration: {e}")

560

561

# Get typed values with defaults

562

platform_name = get_typed(config, "PLATFORM_NAME", str, "Default Platform")

563

http_port = get_typed(config, "HTTP_PORT", int, 8000)

564

debug_mode = get_typed(config, "DEBUG", bool, False)

565

```

566

567

### Working with Service Lists

568

569

```python

570

from tutor.utils import list_if

571

572

# Define services with their enabled status

573

services = [

574

("lms", True),

575

("cms", True),

576

("forum", False),

577

("discovery", True),

578

("ecommerce", False)

579

]

580

581

# Generate JSON list of enabled services

582

enabled_json = list_if(services)

583

print(enabled_json) # ["lms", "cms", "discovery"]

584

585

# Use in templates or configuration

586

config_update = {

587

"ENABLED_SERVICES": enabled_json

588

}

589

```

590

591

### Bind Mount Management

592

593

```python

594

from tutor.bindmount import get_mounts, iter_mounts, parse_mount

595

from tutor.types import Config

596

597

# Get mounts from configuration

598

config: Config = {"MOUNTS": ["lms:/host/code:/openedx/edx-platform", "/host/themes"]}

599

mounts = get_mounts(config)

600

601

# Parse specific mount strings

602

explicit_mount = parse_mount("lms,cms:/host/code:/openedx/edx-platform")

603

# Returns: [("lms", "/host/code", "/openedx/edx-platform"), ("cms", "/host/code", "/openedx/edx-platform")]

604

605

implicit_mount = parse_mount("/host/themes")

606

# Uses COMPOSE_MOUNTS filter to determine container paths

607

608

# Get mounts for specific services

609

user_mounts = ["lms:/host/code:/openedx/edx-platform", "/host/themes"]

610

lms_mounts = list(iter_mounts(user_mounts, "lms"))

611

```

612

613

### YAML Configuration Parsing

614

615

```python

616

from tutor.serialize import load, dumps, parse_key_value

617

import io

618

619

# Parse YAML string

620

yaml_content = """

621

platform:

622

name: "My Open edX"

623

debug: true

624

services:

625

- lms

626

- cms

627

"""

628

config = load(yaml_content)

629

630

# Parse command line arguments

631

key_value = parse_key_value("PLATFORM_NAME=My Custom Platform")

632

# Returns: ("PLATFORM_NAME", "My Custom Platform")

633

634

boolean_value = parse_key_value("DEBUG=true")

635

# Returns: ("DEBUG", True)

636

637

list_value = parse_key_value("SERVICES=[lms, cms, forum]")

638

# Returns: ("SERVICES", ["lms", "cms", "forum"])

639

640

# Serialize back to YAML

641

updated_config = {

642

"PLATFORM_NAME": "Updated Platform",

643

"HTTP_PORT": 8000,

644

"SERVICES": ["lms", "cms"]

645

}

646

yaml_string = dumps(updated_config)

647

```