or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdcharts-visualization.mdevents-interaction.mdindex.mdlayout-navigation.mdtheming-styling.mdui-controls.mdutilities-platform.md

utilities-platform.mddocs/

0

# Utilities and Platform

1

2

This document covers Flet's utility functions, platform detection capabilities, file operations, network utilities, storage systems, and helper classes for cross-platform development.

3

4

## Import

5

6

```python

7

import flet as ft

8

import flet.utils as flet_utils

9

```

10

11

## Platform Detection

12

13

### Platform Detection Functions

14

15

```python { .api }

16

def is_mobile() -> bool:

17

"""Check if running on mobile platform (Android or iOS)."""

18

19

def is_android() -> bool:

20

"""Check if running on Android."""

21

22

def is_ios() -> bool:

23

"""Check if running on iOS."""

24

25

def is_windows() -> bool:

26

"""Check if running on Windows."""

27

28

def is_macos() -> bool:

29

"""Check if running on macOS."""

30

31

def is_linux() -> bool:

32

"""Check if running on Linux."""

33

34

def is_linux_server() -> bool:

35

"""Check if running on Linux server (no GUI)."""

36

37

def is_embedded() -> bool:

38

"""Check if running in embedded mode."""

39

40

def is_pyodide() -> bool:

41

"""Check if running in Pyodide (web assembly)."""

42

43

def is_asyncio() -> bool:

44

"""Check if asyncio is available and running."""

45

46

def get_platform() -> str:

47

"""Get platform name (windows, macos, linux, android, ios, web)."""

48

49

def get_arch() -> str:

50

"""Get architecture name (x86, x64, arm64, etc.)."""

51

```

52

53

**Example:**

54

```python

55

def configure_for_platform():

56

if flet_utils.is_mobile():

57

# Mobile-specific configuration

58

page.window_width = None # Use full width

59

page.window_height = None # Use full height

60

elif flet_utils.is_windows():

61

# Windows-specific configuration

62

page.window_width = 800

63

page.window_height = 600

64

page.window_center()

65

elif flet_utils.is_macos():

66

# macOS-specific configuration

67

page.window_width = 900

68

page.window_height = 700

69

70

platform_info = ft.Text(

71

f"Platform: {flet_utils.get_platform()} ({flet_utils.get_arch()})"

72

)

73

74

# Conditional UI based on platform

75

if flet_utils.is_mobile():

76

return create_mobile_ui()

77

else:

78

return create_desktop_ui()

79

```

80

81

### Environment Variables

82

83

```python { .api }

84

def get_bool_env_var(name: str, default_value: bool = False) -> bool:

85

"""Get boolean environment variable with default fallback."""

86

```

87

88

**Example:**

89

```python

90

debug_mode = flet_utils.get_bool_env_var("DEBUG", False)

91

production = flet_utils.get_bool_env_var("PRODUCTION", True)

92

93

if debug_mode:

94

page.add(ft.Text("Debug mode enabled"))

95

```

96

97

## File and Directory Utilities

98

99

### Path Operations

100

101

```python { .api }

102

def get_current_script_dir() -> str:

103

"""Get directory of the currently executing script."""

104

105

def cleanup_path(path: str) -> str:

106

"""Clean and normalize file path."""

107

108

def is_within_directory(directory: str, target: str) -> bool:

109

"""Check if target path is within directory (security check)."""

110

```

111

112

**Example:**

113

```python

114

# Get assets directory relative to script

115

script_dir = flet_utils.get_current_script_dir()

116

assets_dir = os.path.join(script_dir, "assets")

117

118

# Clean user-provided path

119

safe_path = flet_utils.cleanup_path(user_input_path)

120

121

# Security check for file access

122

if flet_utils.is_within_directory(allowed_dir, requested_file):

123

# Safe to access file

124

with open(requested_file, 'r') as f:

125

content = f.read()

126

```

127

128

### Directory Operations

129

130

```python { .api }

131

def copy_tree(src: str, dst: str, ignore: callable = None) -> None:

132

"""Copy directory tree with optional ignore function."""

133

```

134

135

**Example:**

136

```python

137

# Copy assets directory, ignoring cache files

138

def ignore_cache(path, names):

139

return [name for name in names if name.startswith('.cache')]

140

141

flet_utils.copy_tree("src/assets", "dist/assets", ignore=ignore_cache)

142

```

143

144

### Archive Operations

145

146

```python { .api }

147

def safe_tar_extractall(tar_file, path: str = ".", members=None) -> None:

148

"""Safely extract tar archive preventing directory traversal attacks."""

149

```

150

151

**Example:**

152

```python

153

import tarfile

154

155

# Safely extract uploaded tar file

156

with tarfile.open(uploaded_file) as tar:

157

flet_utils.safe_tar_extractall(tar, "extracted_files/")

158

```

159

160

## Network Utilities

161

162

### Port and Network Detection

163

164

```python { .api }

165

def get_free_tcp_port() -> int:

166

"""Get available TCP port number."""

167

168

def get_local_ip() -> str:

169

"""Get local IP address."""

170

171

def which(command: str) -> str:

172

"""Find executable in PATH (cross-platform 'which' command)."""

173

```

174

175

**Example:**

176

```python

177

# Dynamic port allocation

178

free_port = flet_utils.get_free_tcp_port()

179

print(f"Starting server on port {free_port}")

180

181

# Network information

182

local_ip = flet_utils.get_local_ip()

183

print(f"Server accessible at: http://{local_ip}:{free_port}")

184

185

# Check for required executables

186

git_path = flet_utils.which("git")

187

if git_path:

188

print(f"Git found at: {git_path}")

189

else:

190

print("Git not available")

191

```

192

193

## String and Hash Utilities

194

195

### String Operations

196

197

```python { .api }

198

def slugify(text: str) -> str:

199

"""Convert string to URL-friendly slug."""

200

201

def random_string(length: int = 10, chars: str = None) -> str:

202

"""Generate random string of specified length."""

203

```

204

205

**Example:**

206

```python

207

# Create URL-friendly identifiers

208

title = "My Blog Post: Special Characters & Symbols!"

209

slug = flet_utils.slugify(title) # "my-blog-post-special-characters-symbols"

210

211

# Generate session IDs

212

session_id = flet_utils.random_string(16) # Random 16-character string

213

api_key = flet_utils.random_string(32, "ABCDEF0123456789") # Hex string

214

```

215

216

### Hash Functions

217

218

```python { .api }

219

def sha1(text: str) -> str:

220

"""Calculate SHA1 hash of text."""

221

222

def calculate_file_hash(file_path: str, algorithm: str = "sha256") -> str:

223

"""Calculate hash of file contents."""

224

```

225

226

**Example:**

227

```python

228

# Content hashing

229

content_hash = flet_utils.sha1("Hello, World!")

230

print(f"SHA1: {content_hash}")

231

232

# File integrity checking

233

file_hash = flet_utils.calculate_file_hash("important_file.dat", "sha256")

234

expected_hash = "abc123..."

235

if file_hash == expected_hash:

236

print("File integrity verified")

237

else:

238

print("File may be corrupted")

239

```

240

241

## Browser Integration

242

243

### Browser Operations

244

245

```python { .api }

246

def open_in_browser(url: str) -> None:

247

"""Open URL in default browser."""

248

```

249

250

**Example:**

251

```python

252

def open_help(e):

253

flet_utils.open_in_browser("https://flet.dev/docs")

254

255

def open_external_link(e):

256

flet_utils.open_in_browser("https://example.com")

257

258

ft.Row([

259

ft.ElevatedButton("Help", on_click=open_help),

260

ft.ElevatedButton("External Link", on_click=open_external_link)

261

])

262

```

263

264

## Storage Systems

265

266

### ClientStorage

267

268

```python { .api }

269

class ClientStorage:

270

"""Client-side storage (localStorage in web, file-based elsewhere)."""

271

272

def get(self, key: str) -> str:

273

"""Get value by key."""

274

275

def set(self, key: str, value: str) -> None:

276

"""Set key-value pair."""

277

278

def contains_key(self, key: str) -> bool:

279

"""Check if key exists."""

280

281

def remove(self, key: str) -> None:

282

"""Remove key."""

283

284

def clear(self) -> None:

285

"""Clear all stored data."""

286

287

def get_keys(self, prefix: str = "") -> List[str]:

288

"""Get all keys with optional prefix filter."""

289

```

290

291

**Example:**

292

```python

293

# Store user preferences

294

def save_preferences(theme, language):

295

page.client_storage.set("theme", theme)

296

page.client_storage.set("language", language)

297

298

def load_preferences():

299

theme = page.client_storage.get("theme") or "light"

300

language = page.client_storage.get("language") or "en"

301

return theme, language

302

303

# Settings UI

304

def toggle_theme(e):

305

current_theme = page.client_storage.get("theme") or "light"

306

new_theme = "dark" if current_theme == "light" else "light"

307

page.client_storage.set("theme", new_theme)

308

apply_theme(new_theme)

309

310

ft.Switch(

311

label="Dark Theme",

312

value=page.client_storage.get("theme") == "dark",

313

on_change=toggle_theme

314

)

315

```

316

317

### SessionStorage

318

319

```python { .api }

320

class SessionStorage:

321

"""Session-scoped storage (sessionStorage in web, memory elsewhere)."""

322

323

# Same API as ClientStorage but data persists only for session

324

def get(self, key: str) -> str: ...

325

def set(self, key: str, value: str) -> None: ...

326

def contains_key(self, key: str) -> bool: ...

327

def remove(self, key: str) -> None: ...

328

def clear(self) -> None: ...

329

def get_keys(self, prefix: str = "") -> List[str]: ...

330

```

331

332

**Example:**

333

```python

334

# Temporary session data

335

def store_form_data():

336

page.session.set("form_step", "2")

337

page.session.set("user_input", text_field.value)

338

339

def restore_form_data():

340

step = page.session.get("form_step") or "1"

341

user_input = page.session.get("user_input") or ""

342

return int(step), user_input

343

344

# Form wizard with session persistence

345

current_step, saved_input = restore_form_data()

346

```

347

348

## Utility Classes

349

350

### Vector

351

352

```python { .api }

353

class Vector:

354

"""2D vector utility class."""

355

356

def __init__(self, x: float, y: float):

357

self.x = x

358

self.y = y

359

360

def magnitude(self) -> float:

361

"""Calculate vector magnitude."""

362

363

def normalize(self) -> "Vector":

364

"""Get normalized vector."""

365

366

def dot(self, other: "Vector") -> float:

367

"""Dot product with another vector."""

368

369

def distance_to(self, other: "Vector") -> float:

370

"""Distance to another vector."""

371

372

def __add__(self, other: "Vector") -> "Vector":

373

"""Vector addition."""

374

375

def __sub__(self, other: "Vector") -> "Vector":

376

"""Vector subtraction."""

377

378

def __mul__(self, scalar: float) -> "Vector":

379

"""Scalar multiplication."""

380

```

381

382

**Example:**

383

```python

384

# Physics calculations

385

pos = flet_utils.Vector(100, 200)

386

velocity = flet_utils.Vector(5, -2)

387

388

# Update position

389

new_pos = pos + velocity

390

391

# Calculate distance between points

392

distance = pos.distance_to(target_pos)

393

394

# Normalize direction vector

395

direction = (target_pos - pos).normalize()

396

```

397

398

### Decorators

399

400

#### classproperty

401

402

```python { .api }

403

class classproperty:

404

"""Decorator for class-level properties."""

405

406

def __init__(self, func):

407

self.func = func

408

409

def __get__(self, instance, owner):

410

return self.func(owner)

411

```

412

413

**Example:**

414

```python

415

class AppConfig:

416

_theme = "light"

417

418

@flet_utils.classproperty

419

def current_theme(cls):

420

return cls._theme

421

422

@current_theme.setter

423

def current_theme(cls, value):

424

cls._theme = value

425

426

# Usage

427

print(AppConfig.current_theme) # Access as class property

428

```

429

430

#### deprecated

431

432

```python { .api }

433

def deprecated(reason: str = None):

434

"""Decorator to mark functions as deprecated."""

435

def decorator(func):

436

def wrapper(*args, **kwargs):

437

import warnings

438

warnings.warn(

439

f"{func.__name__} is deprecated. {reason or ''}",

440

DeprecationWarning,

441

stacklevel=2

442

)

443

return func(*args, **kwargs)

444

return wrapper

445

return decorator

446

```

447

448

**Example:**

449

```python

450

@flet_utils.deprecated("Use new_function() instead")

451

def old_function():

452

return "old implementation"

453

454

# Usage will show deprecation warning

455

result = old_function()

456

```

457

458

### Once

459

460

```python { .api }

461

class Once:

462

"""Execute-once utility."""

463

464

def __init__(self):

465

self._called = False

466

467

def __call__(self, func):

468

def wrapper(*args, **kwargs):

469

if not self._called:

470

self._called = True

471

return func(*args, **kwargs)

472

return wrapper

473

```

474

475

**Example:**

476

```python

477

# Ensure initialization happens only once

478

initialize_once = flet_utils.Once()

479

480

@initialize_once

481

def initialize_app():

482

print("App initialized")

483

# Expensive initialization code

484

485

# Multiple calls, but initialization runs only once

486

initialize_app() # Runs initialization

487

initialize_app() # Skipped

488

initialize_app() # Skipped

489

```

490

491

## Query and Routing Utilities

492

493

### QueryString

494

495

```python { .api }

496

class QueryString:

497

"""URL query string handler."""

498

499

def __init__(self, query_string: str = ""):

500

self.params = {}

501

502

def get(self, key: str, default: str = None) -> str:

503

"""Get query parameter value."""

504

505

def set(self, key: str, value: str) -> None:

506

"""Set query parameter."""

507

508

def remove(self, key: str) -> None:

509

"""Remove query parameter."""

510

511

def to_string(self) -> str:

512

"""Convert to query string."""

513

```

514

515

### TemplateRoute

516

517

```python { .api }

518

class TemplateRoute:

519

"""Template-based routing system."""

520

521

def __init__(self, route_template: str):

522

self.template = route_template

523

524

def match(self, route: str) -> dict:

525

"""Match route against template and extract parameters."""

526

527

def build(self, **params) -> str:

528

"""Build route from template with parameters."""

529

```

530

531

**Example:**

532

```python

533

# URL parameter handling

534

def handle_route_change(e):

535

route = e.route

536

query = flet_utils.QueryString(page.route.split('?')[1] if '?' in page.route else "")

537

538

# Extract query parameters

539

user_id = query.get('user_id')

540

tab = query.get('tab', 'profile')

541

542

if user_id:

543

load_user_profile(user_id, tab)

544

545

# Template routing

546

user_route = flet_utils.TemplateRoute("/user/{user_id}/tab/{tab}")

547

548

# Match incoming route

549

params = user_route.match("/user/123/tab/settings")

550

# Returns: {"user_id": "123", "tab": "settings"}

551

552

# Build route from parameters

553

new_route = user_route.build(user_id="456", tab="profile")

554

# Returns: "/user/456/tab/profile"

555

```

556

557

## Cross-Platform Patterns

558

559

### Adaptive UI Components

560

561

```python

562

def create_adaptive_button(text, on_click):

563

"""Create platform-appropriate button."""

564

if flet_utils.is_ios():

565

return ft.CupertinoButton(text=text, on_click=on_click)

566

else:

567

return ft.ElevatedButton(text=text, on_click=on_click)

568

569

def create_adaptive_dialog(title, content, actions):

570

"""Create platform-appropriate dialog."""

571

if flet_utils.is_ios():

572

return ft.CupertinoAlertDialog(

573

title=ft.Text(title),

574

content=ft.Text(content),

575

actions=actions

576

)

577

else:

578

return ft.AlertDialog(

579

title=ft.Text(title),

580

content=ft.Text(content),

581

actions=actions

582

)

583

```

584

585

### Platform-Specific Configuration

586

587

```python

588

class PlatformConfig:

589

"""Platform-specific configuration manager."""

590

591

def __init__(self):

592

self.config = self._load_platform_config()

593

594

def _load_platform_config(self):

595

base_config = {

596

"window_width": 800,

597

"window_height": 600,

598

"font_family": "default"

599

}

600

601

if flet_utils.is_mobile():

602

base_config.update({

603

"window_width": None,

604

"window_height": None,

605

"font_size": 16

606

})

607

elif flet_utils.is_macos():

608

base_config.update({

609

"font_family": "SF Pro Display",

610

"window_width": 900

611

})

612

elif flet_utils.is_windows():

613

base_config.update({

614

"font_family": "Segoe UI",

615

"window_width": 850

616

})

617

618

return base_config

619

620

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

621

return self.config.get(key, default)

622

623

# Usage

624

config = PlatformConfig()

625

page.window_width = config.get("window_width")

626

page.window_height = config.get("window_height")

627

```

628

629

### Resource Management

630

631

```python

632

def get_platform_asset(asset_name):

633

"""Get platform-specific asset path."""

634

platform = flet_utils.get_platform()

635

636

# Try platform-specific asset first

637

platform_asset = f"assets/{platform}/{asset_name}"

638

if os.path.exists(platform_asset):

639

return platform_asset

640

641

# Fall back to generic asset

642

return f"assets/{asset_name}"

643

644

def load_platform_strings():

645

"""Load platform-appropriate localized strings."""

646

if flet_utils.is_ios():

647

return load_strings("ios_strings.json")

648

elif flet_utils.is_android():

649

return load_strings("android_strings.json")

650

else:

651

return load_strings("desktop_strings.json")

652

```

653

654

### Performance Utilities

655

656

```python

657

def optimize_for_platform():

658

"""Apply platform-specific optimizations."""

659

if flet_utils.is_mobile():

660

# Mobile optimizations

661

page.scroll = ft.ScrollMode.AUTO

662

page.auto_scroll = True

663

elif flet_utils.is_web():

664

# Web optimizations

665

page.web_renderer = ft.WebRenderer.HTML

666

667

# Memory management

668

if flet_utils.is_linux_server():

669

# Server environment optimizations

670

disable_animations()

671

reduce_ui_complexity()

672

673

def create_efficient_list_for_platform(items):

674

"""Create optimized list based on platform capabilities."""

675

if flet_utils.is_mobile() and len(items) > 100:

676

# Use virtual scrolling for large lists on mobile

677

return create_virtual_list(items)

678

else:

679

# Standard list for desktop/smaller lists

680

return ft.ListView(controls=[

681

ft.ListTile(title=ft.Text(item)) for item in items

682

])

683

```

684

685

This covers Flet's comprehensive utility system and platform detection capabilities, enabling you to create truly cross-platform applications that adapt to different environments and provide optimal user experiences across all supported platforms.