or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

array-integration.mdenumerations.mdimage-creation.mdimage-operations.mdimage-output.mdindex.mdio-connections.mdproperties-metadata.mdsystem-control.md

system-control.mddocs/

0

# System Control

1

2

Advanced functionality for operation introspection, cache management, and low-level system control for fine-tuning performance and behavior. These utilities provide control over libvips internals and enable advanced optimization strategies.

3

4

## Capabilities

5

6

### Operation System

7

8

Direct access to libvips operations and introspection capabilities for dynamic operation calling and documentation generation.

9

10

```python { .api }

11

class Operation:

12

"""Call libvips operations and provide introspection."""

13

14

@classmethod

15

def call(cls, operation_name: str, *args, **kwargs):

16

"""

17

Call any libvips operation by name.

18

19

Parameters:

20

- operation_name: str, name of the libvips operation

21

- *args: positional arguments for the operation

22

- **kwargs: keyword arguments for the operation

23

24

Returns:

25

Operation result (varies by operation)

26

"""

27

28

@classmethod

29

def generate_docstring(cls, operation_name: str) -> str:

30

"""

31

Generate Google-style docstring for operation.

32

33

Parameters:

34

- operation_name: str, operation name

35

36

Returns:

37

str, formatted docstring with parameters and description

38

"""

39

40

@classmethod

41

def generate_sphinx(cls, operation_name: str) -> str:

42

"""

43

Generate Sphinx-style docstring for operation.

44

45

Parameters:

46

- operation_name: str, operation name

47

48

Returns:

49

str, Sphinx-formatted docstring

50

"""

51

52

@classmethod

53

def generate_sphinx_all(cls) -> str:

54

"""

55

Generate Sphinx documentation for all operations.

56

57

Returns:

58

str, complete Sphinx documentation

59

"""

60

61

class Introspect:

62

"""Build and cache introspection data for operations."""

63

64

@classmethod

65

def get(cls, operation_name: str) -> 'Introspect':

66

"""

67

Get cached introspection data for operation.

68

69

Parameters:

70

- operation_name: str, operation name

71

72

Returns:

73

Introspect object with operation details

74

"""

75

76

# Properties

77

description: str # Operation description

78

flags: int # Operation flags

79

required_input: list # Required input parameters

80

optional_input: list # Optional input parameters

81

required_output: list # Required output parameters

82

optional_output: list # Optional output parameters

83

```

84

85

Example usage:

86

87

```python

88

# Direct operation calling

89

result = pyvips.Operation.call('add', image1, image2)

90

blurred = pyvips.Operation.call('gaussblur', image, 2.0)

91

92

# Advanced operation with all parameters

93

resized = pyvips.Operation.call('resize', image,

94

scale=0.5,

95

vscale=0.8,

96

kernel='lanczos3')

97

98

# Get operation documentation

99

doc = pyvips.Operation.generate_docstring('gaussblur')

100

print(doc)

101

102

# Introspect operation details

103

introspect = pyvips.Introspect.get('resize')

104

print(f"Description: {introspect.description}")

105

print(f"Required inputs: {introspect.required_input}")

106

print(f"Optional inputs: {introspect.optional_input}")

107

108

# List all available operations

109

import pyvips

110

operations = []

111

def collect_operations(name, operation):

112

operations.append(name)

113

pyvips.type_map(pyvips.type_from_name('VipsOperation'), collect_operations)

114

print(f"Available operations: {len(operations)}")

115

116

# Dynamic operation discovery

117

def call_operation_safely(op_name, *args, **kwargs):

118

"""Safely call operation with error handling."""

119

try:

120

introspect = pyvips.Introspect.get(op_name)

121

print(f"Calling {op_name}: {introspect.description}")

122

return pyvips.Operation.call(op_name, *args, **kwargs)

123

except pyvips.Error as e:

124

print(f"Operation {op_name} failed: {e}")

125

return None

126

127

# Use dynamic calling

128

result = call_operation_safely('thumbnail', image, 200)

129

```

130

131

### Cache Management

132

133

Control libvips operation cache for memory management and performance optimization.

134

135

```python { .api }

136

def cache_set_max(mx: int) -> None:

137

"""

138

Set maximum number of operations in cache.

139

140

Parameters:

141

- mx: int, maximum cache entries (0 = unlimited)

142

"""

143

144

def cache_set_max_mem(mx: int) -> None:

145

"""

146

Set maximum cache memory usage.

147

148

Parameters:

149

- mx: int, maximum memory in bytes (0 = unlimited)

150

"""

151

152

def cache_set_max_files(mx: int) -> None:

153

"""

154

Set maximum open files in cache.

155

156

Parameters:

157

- mx: int, maximum open files (0 = unlimited)

158

"""

159

160

def cache_set_trace(trace: bool) -> None:

161

"""

162

Enable/disable cache operation tracing.

163

164

Parameters:

165

- trace: bool, enable tracing for debugging

166

"""

167

168

def cache_get_max() -> int:

169

"""Get maximum cache entries setting."""

170

171

def cache_get_size() -> int:

172

"""Get current cache size (number of entries)."""

173

174

def cache_get_max_mem() -> int:

175

"""Get maximum cache memory setting."""

176

177

def cache_get_max_files() -> int:

178

"""Get maximum open files setting."""

179

```

180

181

Example usage:

182

183

```python

184

# Cache configuration for memory-constrained environments

185

pyvips.cache_set_max_mem(100 * 1024 * 1024) # 100MB limit

186

pyvips.cache_set_max_files(50) # Limit open files

187

pyvips.cache_set_max(200) # Limit cache entries

188

189

# Cache configuration for high-performance environments

190

pyvips.cache_set_max_mem(1 * 1024 * 1024 * 1024) # 1GB limit

191

pyvips.cache_set_max_files(1000) # More open files

192

pyvips.cache_set_max(0) # Unlimited entries

193

194

# Monitor cache usage

195

def print_cache_stats():

196

print(f"Cache size: {pyvips.cache_get_size()}")

197

print(f"Max entries: {pyvips.cache_get_max()}")

198

print(f"Max memory: {pyvips.cache_get_max_mem()} bytes")

199

print(f"Max files: {pyvips.cache_get_max_files()}")

200

201

print_cache_stats()

202

203

# Enable cache tracing for debugging

204

pyvips.cache_set_trace(True)

205

image = pyvips.Image.new_from_file('test.jpg')

206

resized = image.resize(0.5) # Will show cache operations

207

pyvips.cache_set_trace(False)

208

209

# Adaptive cache management

210

def setup_cache_for_batch_processing(image_count, avg_image_size_mb):

211

"""Configure cache for batch processing workload."""

212

213

# Estimate memory needs

214

total_mem_mb = image_count * avg_image_size_mb * 2 # Factor for operations

215

216

# Set conservative limits

217

pyvips.cache_set_max_mem(min(total_mem_mb * 1024 * 1024, 512 * 1024 * 1024))

218

pyvips.cache_set_max_files(min(image_count * 2, 200))

219

pyvips.cache_set_max(min(image_count * 5, 500))

220

221

print(f"Cache configured for {image_count} images")

222

print_cache_stats()

223

224

# Dynamic cache adjustment

225

def monitor_and_adjust_cache():

226

"""Monitor cache performance and adjust settings."""

227

import psutil

228

229

# Get system memory info

230

memory = psutil.virtual_memory()

231

available_mb = memory.available // (1024 * 1024)

232

233

# Adjust cache based on available memory

234

if available_mb > 2048: # > 2GB available

235

pyvips.cache_set_max_mem(512 * 1024 * 1024) # Use 512MB

236

elif available_mb > 1024: # > 1GB available

237

pyvips.cache_set_max_mem(256 * 1024 * 1024) # Use 256MB

238

else: # Low memory

239

pyvips.cache_set_max_mem(64 * 1024 * 1024) # Use 64MB

240

241

print(f"Adjusted cache for {available_mb}MB available memory")

242

```

243

244

### Version Information

245

246

Access libvips version information for compatibility checking and feature detection.

247

248

```python { .api }

249

def version(flag: int) -> int:

250

"""

251

Get libvips version information.

252

253

Parameters:

254

- flag: int, version component (0=major, 1=minor, 2=micro)

255

256

Returns:

257

int, version number component

258

"""

259

260

def at_least_libvips(x: int, y: int) -> bool:

261

"""

262

Check if libvips version is at least x.y.

263

264

Parameters:

265

- x: int, major version

266

- y: int, minor version

267

268

Returns:

269

bool, True if version >= x.y

270

"""

271

```

272

273

Example usage:

274

275

```python

276

# Get version information

277

major = pyvips.version(0)

278

minor = pyvips.version(1)

279

micro = pyvips.version(2)

280

print(f"libvips version: {major}.{minor}.{micro}")

281

282

# Check for specific features

283

if pyvips.at_least_libvips(8, 13):

284

print("TargetCustom.on_end() is available")

285

# Use newer features

286

else:

287

print("Using legacy TargetCustom.on_finish()")

288

# Use older API

289

290

# Feature detection

291

def has_feature(feature_name, min_major, min_minor):

292

"""Check if a feature is available in current libvips version."""

293

return pyvips.at_least_libvips(min_major, min_minor)

294

295

# Check various features

296

features = {

297

'custom_sources': (8, 9),

298

'target_custom_end': (8, 13),

299

'heif_support': (8, 8),

300

'webp_animation': (8, 9)

301

}

302

303

for feature, (maj, min) in features.items():

304

available = has_feature(feature, maj, min)

305

print(f"{feature}: {'✓' if available else '✗'}")

306

307

# Version-dependent operation calling

308

def safe_operation_call(op_name, required_version, *args, **kwargs):

309

"""Call operation only if libvips version supports it."""

310

maj, min = required_version

311

if pyvips.at_least_libvips(maj, min):

312

return pyvips.Operation.call(op_name, *args, **kwargs)

313

else:

314

raise pyvips.Error(f"Operation {op_name} requires libvips >= {maj}.{min}")

315

316

# Use version checking

317

try:

318

result = safe_operation_call('heifload', (8, 8), 'image.heic')

319

print("HEIF loading successful")

320

except pyvips.Error as e:

321

print(f"HEIF not supported: {e}")

322

```

323

324

### Security Controls (libvips >= 8.13)

325

326

Security features for controlling potentially dangerous operations in untrusted environments.

327

328

```python { .api }

329

def block_untrusted_set(state: bool) -> None:

330

"""

331

Set global block state for untrusted operations.

332

333

Parameters:

334

- state: bool, True to block untrusted operations

335

"""

336

337

def operation_block_set(name: str, state: bool) -> None:

338

"""

339

Set block state for specific operation.

340

341

Parameters:

342

- name: str, operation name to block/unblock

343

- state: bool, True to block operation

344

"""

345

```

346

347

Example usage:

348

349

```python

350

# Security setup for web service

351

if pyvips.at_least_libvips(8, 13):

352

# Block potentially dangerous operations

353

pyvips.block_untrusted_set(True)

354

355

# Block specific operations that might be security risks

356

dangerous_ops = [

357

'system', # System command execution

358

'pdfload', # PDF might contain malicious content

359

'svgload', # SVG can contain scripts

360

'magickload' # ImageMagick has security history

361

]

362

363

for op in dangerous_ops:

364

try:

365

pyvips.operation_block_set(op, True)

366

print(f"Blocked operation: {op}")

367

except:

368

print(f"Could not block {op} (might not exist)")

369

370

# Safe image processing for user uploads

371

def process_user_upload(image_data, max_size_mb=10):

372

"""Safely process user-uploaded images."""

373

374

# Size check

375

if len(image_data) > max_size_mb * 1024 * 1024:

376

raise ValueError(f"Image too large: {len(image_data)} bytes")

377

378

# Enable security restrictions

379

if pyvips.at_least_libvips(8, 13):

380

pyvips.block_untrusted_set(True)

381

382

try:

383

# Load with restrictions

384

image = pyvips.Image.new_from_buffer(image_data, '')

385

386

# Limit output size

387

if image.width > 4096 or image.height > 4096:

388

image = image.thumbnail_image(4096)

389

390

# Safe processing only

391

result = (image

392

.colourspace('srgb')

393

.resize(0.8)

394

.sharpen())

395

396

return result.write_to_buffer('.jpg', Q=85, strip=True)

397

398

except pyvips.Error as e:

399

raise ValueError(f"Image processing failed: {e}")

400

401

finally:

402

# Reset security state if needed

403

if pyvips.at_least_libvips(8, 13):

404

pyvips.block_untrusted_set(False)

405

```

406

407

### System Management

408

409

Low-level system control and resource management functions.

410

411

```python { .api }

412

def leak_set(leak: bool) -> None:

413

"""

414

Enable/disable libvips leak checking.

415

416

Parameters:

417

- leak: bool, enable leak detection for debugging

418

"""

419

420

def shutdown() -> None:

421

"""

422

Shut down libvips system.

423

Call before program exit to clean up resources.

424

"""

425

```

426

427

Example usage:

428

429

```python

430

# Development/debugging setup

431

import atexit

432

433

def setup_debug_environment():

434

"""Configure libvips for debugging."""

435

# Enable leak checking

436

pyvips.leak_set(True)

437

438

# Enable cache tracing

439

pyvips.cache_set_trace(True)

440

441

# Register cleanup

442

atexit.register(pyvips.shutdown)

443

444

print("Debug environment configured")

445

446

# Production setup

447

def setup_production_environment():

448

"""Configure libvips for production."""

449

# Disable leak checking for performance

450

pyvips.leak_set(False)

451

452

# Optimize cache for server workload

453

pyvips.cache_set_max_mem(256 * 1024 * 1024) # 256MB

454

pyvips.cache_set_max_files(100)

455

pyvips.cache_set_max(1000)

456

457

# Security setup

458

if pyvips.at_least_libvips(8, 13):

459

pyvips.block_untrusted_set(True)

460

461

# Register cleanup

462

atexit.register(pyvips.shutdown)

463

464

print("Production environment configured")

465

466

# Application lifecycle management

467

class PyVipsManager:

468

"""Manage PyVips lifecycle and configuration."""

469

470

def __init__(self, environment='production'):

471

self.environment = environment

472

self.setup()

473

474

def setup(self):

475

"""Setup based on environment."""

476

if self.environment == 'development':

477

setup_debug_environment()

478

else:

479

setup_production_environment()

480

481

def get_system_info(self):

482

"""Get system and version information."""

483

return {

484

'pyvips_version': pyvips.__version__,

485

'libvips_version': f"{pyvips.version(0)}.{pyvips.version(1)}.{pyvips.version(2)}",

486

'api_mode': pyvips.API_mode,

487

'cache_size': pyvips.cache_get_size(),

488

'cache_max': pyvips.cache_get_max(),

489

'cache_max_mem': pyvips.cache_get_max_mem(),

490

'cache_max_files': pyvips.cache_get_max_files()

491

}

492

493

def cleanup(self):

494

"""Clean shutdown."""

495

print("Shutting down PyVips...")

496

pyvips.shutdown()

497

498

# Use lifecycle manager

499

manager = PyVipsManager('production')

500

print("System info:", manager.get_system_info())

501

502

# Register cleanup

503

import atexit

504

atexit.register(manager.cleanup)

505

```

506

507

## Performance Monitoring

508

509

```python

510

import time

511

import psutil

512

513

class PerformanceMonitor:

514

"""Monitor PyVips performance and resource usage."""

515

516

def __init__(self):

517

self.start_time = time.time()

518

self.initial_memory = psutil.Process().memory_info().rss

519

520

def log_stats(self, operation):

521

"""Log performance statistics."""

522

current_time = time.time()

523

current_memory = psutil.Process().memory_info().rss

524

525

cache_size = pyvips.cache_get_size()

526

527

print(f"Operation: {operation}")

528

print(f" Time: {current_time - self.start_time:.2f}s")

529

print(f" Memory: {(current_memory - self.initial_memory) / 1024 / 1024:.1f}MB")

530

print(f" Cache size: {cache_size} entries")

531

532

self.start_time = current_time

533

534

def optimize_for_workload(self, workload_type):

535

"""Optimize cache settings for specific workload."""

536

if workload_type == 'batch':

537

pyvips.cache_set_max(2000)

538

pyvips.cache_set_max_mem(512 * 1024 * 1024)

539

elif workload_type == 'interactive':

540

pyvips.cache_set_max(100)

541

pyvips.cache_set_max_mem(128 * 1024 * 1024)

542

elif workload_type == 'memory_constrained':

543

pyvips.cache_set_max(50)

544

pyvips.cache_set_max_mem(64 * 1024 * 1024)

545

546

# Use performance monitoring

547

monitor = PerformanceMonitor()

548

monitor.optimize_for_workload('batch')

549

550

image = pyvips.Image.new_from_file('large.tiff')

551

monitor.log_stats('load')

552

553

processed = image.resize(0.5).sharpen()

554

monitor.log_stats('process')

555

556

processed.write_to_file('output.jpg')

557

monitor.log_stats('save')

558

```