or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

appengine-integration.mdcore-admin.mdfile-admin.mdforms.mdgeoalchemy-integration.mdhelpers-utilities.mdindex.mdmodel-views.mdmongoengine-integration.mdredis-integration.mdsqlalchemy-integration.md

file-admin.mddocs/

0

# File Management

1

2

File and directory administration interface with upload, download, edit capabilities, and flexible storage backend system for managing files through Flask-Admin.

3

4

## Capabilities

5

6

### File Storage Backend

7

8

Storage abstraction layer supporting different file storage backends with consistent interface.

9

10

```python { .api }

11

class LocalFileStorage:

12

def __init__(self, base_path):

13

"""

14

Initialize local filesystem storage backend.

15

16

Args:

17

base_path (str): Base directory path for file operations

18

"""

19

20

def get_base_path(self):

21

"""

22

Get base directory path.

23

24

Returns:

25

str: Base directory path

26

"""

27

28

def make_dir(self, path, directory):

29

"""

30

Create directory.

31

32

Args:

33

path (str): Parent directory path

34

directory (str): New directory name

35

36

Returns:

37

bool: True if successful

38

"""

39

40

def get_files(self, path, directory):

41

"""

42

List files and directories in given path.

43

44

Args:

45

path (str): Directory path to list

46

directory (str): Directory name

47

48

Returns:

49

list: File and directory information

50

"""

51

52

def delete_tree(self, directory):

53

"""

54

Delete directory recursively.

55

56

Args:

57

directory (str): Directory path to delete

58

59

Returns:

60

bool: True if successful

61

"""

62

63

def delete_file(self, file_path):

64

"""

65

Delete single file.

66

67

Args:

68

file_path (str): Path to file to delete

69

70

Returns:

71

bool: True if successful

72

"""

73

74

def path_exists(self, path):

75

"""

76

Check if path exists.

77

78

Args:

79

path (str): Path to check

80

81

Returns:

82

bool: True if path exists

83

"""

84

85

def rename_path(self, src, dst):

86

"""

87

Rename file or directory.

88

89

Args:

90

src (str): Source path

91

dst (str): Destination path

92

93

Returns:

94

bool: True if successful

95

"""

96

97

def is_dir(self, path):

98

"""

99

Check if path is directory.

100

101

Args:

102

path (str): Path to check

103

104

Returns:

105

bool: True if path is directory

106

"""

107

108

def send_file(self, file_path):

109

"""

110

Send file to user for download.

111

112

Args:

113

file_path (str): Path to file

114

115

Returns:

116

Response: Flask file response

117

"""

118

119

def read_file(self, path):

120

"""

121

Read file contents.

122

123

Args:

124

path (str): File path to read

125

126

Returns:

127

str: File contents as string

128

"""

129

130

def write_file(self, path, content):

131

"""

132

Write content to file.

133

134

Args:

135

path (str): File path to write

136

content (str): Content to write

137

138

Returns:

139

bool: True if successful

140

"""

141

142

def save_file(self, path, file_data):

143

"""

144

Save uploaded file data.

145

146

Args:

147

path (str): Destination file path

148

file_data: File data from upload

149

150

Returns:

151

bool: True if successful

152

"""

153

```

154

155

### Base File Admin

156

157

Foundation class for file administration interfaces with comprehensive file and directory management.

158

159

```python { .api }

160

class BaseFileAdmin(BaseView, ActionsMixin):

161

def __init__(

162

self,

163

base_url=None,

164

name=None,

165

category=None,

166

endpoint=None,

167

url=None,

168

verify_path=True,

169

menu_class_name=None,

170

menu_icon_type=None,

171

menu_icon_value=None,

172

storage=None

173

):

174

"""

175

Initialize base file administration interface.

176

177

Args:

178

base_url (str, optional): Base URL for file serving

179

name (str, optional): View name for menu

180

category (str, optional): Menu category

181

endpoint (str, optional): Blueprint endpoint

182

url (str, optional): URL prefix

183

verify_path (bool): Verify path accessibility

184

menu_class_name (str, optional): Menu CSS class

185

menu_icon_type (str, optional): Icon type

186

menu_icon_value (str, optional): Icon identifier

187

storage: Storage backend instance

188

"""

189

190

# Permission configuration

191

can_upload = True # Allow file uploads

192

can_download = True # Allow file downloads

193

can_delete = True # Allow file deletion

194

can_delete_dirs = True # Allow directory deletion

195

can_mkdir = True # Allow directory creation

196

can_rename = True # Allow renaming files/directories

197

198

# File type restrictions

199

allowed_extensions = None # Allowed file extensions (None = all)

200

editable_extensions = ('md', 'txt', 'py', 'js', 'html', 'css', 'json', 'xml', 'yaml', 'yml', 'ini', 'cfg')

201

202

# Interface configuration

203

list_template = 'admin/file/list.html'

204

upload_template = 'admin/file/upload.html'

205

mkdir_template = 'admin/file/mkdir.html'

206

207

def is_accessible_path(self, path):

208

"""

209

Check if path is accessible for current user.

210

211

Args:

212

path (str): Path to check

213

214

Returns:

215

bool: True if accessible

216

"""

217

218

def get_base_path(self):

219

"""

220

Get base path for file operations.

221

222

Returns:

223

str: Base path

224

"""

225

226

def is_file_allowed(self, filename):

227

"""

228

Check if file upload is permitted based on extension.

229

230

Args:

231

filename (str): Filename to check

232

233

Returns:

234

bool: True if allowed

235

"""

236

237

def is_file_editable(self, filename):

238

"""

239

Check if file can be edited inline.

240

241

Args:

242

filename (str): Filename to check

243

244

Returns:

245

bool: True if editable

246

"""

247

248

# View methods (exposed via @expose decorator)

249

def index(self):

250

"""

251

File browser index view.

252

253

Returns:

254

str: Rendered file browser template

255

"""

256

257

def upload(self):

258

"""

259

File upload view.

260

261

Returns:

262

str: Rendered upload template or redirect

263

"""

264

265

def download(self):

266

"""

267

File download view.

268

269

Returns:

270

Response: File download response

271

"""

272

273

def edit(self):

274

"""

275

File edit view for text files.

276

277

Returns:

278

str: Rendered edit template or redirect

279

"""

280

281

def rename(self):

282

"""

283

Rename file or directory view.

284

285

Returns:

286

str: Rendered rename template or redirect

287

"""

288

289

def mkdir(self):

290

"""

291

Create directory view.

292

293

Returns:

294

str: Rendered mkdir template or redirect

295

"""

296

297

# Action methods

298

def action_delete(self, items):

299

"""

300

Batch delete action for selected files/directories.

301

302

Args:

303

items (list): List of file/directory paths to delete

304

"""

305

306

def action_edit(self, items):

307

"""

308

Batch edit action for selected text files.

309

310

Args:

311

items (list): List of file paths to edit

312

"""

313

314

class FileAdmin(BaseFileAdmin):

315

def __init__(self, base_path, *args, **kwargs):

316

"""

317

Simple file management interface for local filesystem.

318

319

Args:

320

base_path (str): Base directory path to manage

321

*args: Additional positional arguments

322

**kwargs: Additional keyword arguments

323

"""

324

```

325

326

### Amazon S3 Storage Backend

327

328

Cloud storage backend for Amazon S3 with full file management capabilities including upload, download, and directory operations.

329

330

```python { .api }

331

from flask_admin.contrib.fileadmin.s3 import S3Storage

332

333

class S3Storage:

334

def __init__(

335

self,

336

bucket_name,

337

region,

338

aws_access_key_id,

339

aws_secret_access_key

340

):

341

"""

342

Amazon S3 storage backend.

343

344

Parameters:

345

- bucket_name: str, Name of the S3 bucket

346

- region: str, AWS region where bucket is located

347

- aws_access_key_id: str, AWS Access Key ID

348

- aws_secret_access_key: str, AWS Secret Access Key

349

"""

350

```

351

352

### Azure Blob Storage Backend

353

354

Microsoft Azure Blob Storage backend for cloud-based file management with container support.

355

356

```python { .api }

357

from flask_admin.contrib.fileadmin.azure import AzureStorage

358

359

class AzureStorage:

360

def __init__(self, container_name, connection_string):

361

"""

362

Azure Blob Storage backend.

363

364

Parameters:

365

- container_name: str, Name of the Azure storage container

366

- connection_string: str, Azure Blob Storage connection string

367

"""

368

```

369

370

## Usage Examples

371

372

### Basic File Administration

373

374

```python

375

from flask import Flask

376

from flask_admin import Admin

377

from flask_admin.contrib.fileadmin import FileAdmin

378

import os.path as op

379

380

app = Flask(__name__)

381

app.config['SECRET_KEY'] = 'secret-key'

382

383

# Initialize admin

384

admin = Admin(app, name='File Manager')

385

386

# Add file admin for uploads directory

387

path = op.join(op.dirname(__file__), 'uploads')

388

admin.add_view(FileAdmin(path, '/uploads/', name='Upload Files'))

389

390

# Add file admin for static files with restricted permissions

391

static_path = op.join(op.dirname(__file__), 'static')

392

admin.add_view(FileAdmin(

393

static_path,

394

'/static/',

395

name='Static Files',

396

category='Files'

397

))

398

```

399

400

### Custom File Admin with Restrictions

401

402

```python

403

from flask_admin.contrib.fileadmin import FileAdmin

404

from flask_login import current_user

405

406

class RestrictedFileAdmin(FileAdmin):

407

# File type restrictions

408

allowed_extensions = ('txt', 'md', 'py', 'js', 'css', 'html', 'json', 'xml')

409

editable_extensions = ('txt', 'md', 'py', 'js', 'css', 'html', 'json')

410

411

# Permission configuration

412

can_upload = True

413

can_download = True

414

can_delete = False # Disable deletion

415

can_delete_dirs = False

416

can_mkdir = True

417

can_rename = True

418

419

def is_accessible(self):

420

"""Only allow access to authenticated admin users."""

421

return current_user.is_authenticated and current_user.is_admin

422

423

def is_accessible_path(self, path):

424

"""Restrict access to certain directories."""

425

# Prevent access to hidden directories

426

if '/.git' in path or '/.env' in path:

427

return False

428

429

# Prevent access to Python cache directories

430

if '__pycache__' in path:

431

return False

432

433

return super().is_accessible_path(path)

434

435

def is_file_allowed(self, filename):

436

"""Additional file upload restrictions."""

437

# Block executable files

438

if filename.lower().endswith(('.exe', '.bat', '.sh', '.com')):

439

return False

440

441

return super().is_file_allowed(filename)

442

443

# Register with admin

444

uploads_path = op.join(op.dirname(__file__), 'uploads')

445

admin.add_view(RestrictedFileAdmin(

446

uploads_path,

447

'/uploads/',

448

name='Managed Files',

449

category='File Management'

450

))

451

```

452

453

### Custom Storage Backend

454

455

```python

456

from flask_admin.contrib.fileadmin import BaseFileAdmin, LocalFileStorage

457

import os

458

import shutil

459

from werkzeug.utils import secure_filename

460

461

class S3FileStorage:

462

"""Example custom storage backend for AWS S3."""

463

464

def __init__(self, bucket_name, aws_access_key, aws_secret_key):

465

"""

466

Initialize S3 storage backend.

467

468

Args:

469

bucket_name (str): S3 bucket name

470

aws_access_key (str): AWS access key

471

aws_secret_key (str): AWS secret key

472

"""

473

self.bucket_name = bucket_name

474

# Initialize S3 client here

475

pass

476

477

def get_files(self, path, directory):

478

"""List files in S3 bucket path."""

479

# Implement S3 listing logic

480

pass

481

482

def save_file(self, path, file_data):

483

"""Upload file to S3."""

484

# Implement S3 upload logic

485

pass

486

487

def delete_file(self, file_path):

488

"""Delete file from S3."""

489

# Implement S3 deletion logic

490

pass

491

492

# Implement other required methods...

493

494

class CustomFileAdmin(BaseFileAdmin):

495

def __init__(self, storage_config, *args, **kwargs):

496

# Initialize with custom storage backend

497

storage = S3FileStorage(**storage_config)

498

super().__init__(storage=storage, *args, **kwargs)

499

500

# Usage with custom storage

501

s3_config = {

502

'bucket_name': 'my-files-bucket',

503

'aws_access_key': 'your-access-key',

504

'aws_secret_key': 'your-secret-key'

505

}

506

507

admin.add_view(CustomFileAdmin(

508

s3_config,

509

name='S3 Files',

510

category='Cloud Storage'

511

))

512

```

513

514

### Advanced File Operations

515

516

```python

517

from flask_admin.contrib.fileadmin import FileAdmin

518

from flask import flash, request, redirect, url_for

519

import os

520

import zipfile

521

from PIL import Image

522

523

class AdvancedFileAdmin(FileAdmin):

524

# Enhanced file type support

525

allowed_extensions = ('txt', 'md', 'py', 'js', 'css', 'html', 'json', 'xml',

526

'jpg', 'jpeg', 'png', 'gif', 'pdf', 'zip', 'tar', 'gz')

527

528

editable_extensions = ('txt', 'md', 'py', 'js', 'css', 'html', 'json', 'xml', 'yaml', 'yml')

529

530

def on_file_upload(self, directory, path, filename):

531

"""Hook called after successful file upload."""

532

file_path = os.path.join(path, filename)

533

534

# Auto-generate thumbnails for images

535

if filename.lower().endswith(('jpg', 'jpeg', 'png')):

536

self.generate_thumbnail(file_path)

537

538

# Auto-extract ZIP files

539

if filename.lower().endswith('.zip') and request.form.get('auto_extract'):

540

self.extract_zip(file_path, directory)

541

542

def generate_thumbnail(self, image_path):

543

"""Generate thumbnail for uploaded image."""

544

try:

545

with Image.open(image_path) as img:

546

img.thumbnail((200, 200))

547

thumb_path = image_path.rsplit('.', 1)[0] + '_thumb.' + image_path.rsplit('.', 1)[1]

548

img.save(thumb_path)

549

flash(f'Generated thumbnail: {os.path.basename(thumb_path)}', 'success')

550

except Exception as ex:

551

flash(f'Failed to generate thumbnail: {str(ex)}', 'warning')

552

553

def extract_zip(self, zip_path, target_dir):

554

"""Extract ZIP file contents."""

555

try:

556

with zipfile.ZipFile(zip_path, 'r') as zip_ref:

557

extract_path = os.path.join(target_dir, 'extracted')

558

os.makedirs(extract_path, exist_ok=True)

559

zip_ref.extractall(extract_path)

560

flash(f'Extracted ZIP contents to: extracted/', 'success')

561

except Exception as ex:

562

flash(f'Failed to extract ZIP: {str(ex)}', 'error')

563

564

@expose('/compress/')

565

def compress_files(self):

566

"""Custom action to compress selected files."""

567

if request.method == 'POST':

568

file_paths = request.form.getlist('file_paths')

569

if file_paths:

570

zip_name = request.form.get('zip_name', 'archive.zip')

571

self.create_zip_archive(file_paths, zip_name)

572

return redirect(url_for('.index'))

573

574

return self.render('admin/file/compress.html')

575

576

def create_zip_archive(self, file_paths, zip_name):

577

"""Create ZIP archive from selected files."""

578

try:

579

zip_path = os.path.join(self.get_base_path(), zip_name)

580

with zipfile.ZipFile(zip_path, 'w') as zip_file:

581

for file_path in file_paths:

582

full_path = os.path.join(self.get_base_path(), file_path)

583

if os.path.exists(full_path):

584

zip_file.write(full_path, file_path)

585

586

flash(f'Created archive: {zip_name}', 'success')

587

except Exception as ex:

588

flash(f'Failed to create archive: {str(ex)}', 'error')

589

590

# Register advanced file admin

591

admin.add_view(AdvancedFileAdmin(

592

uploads_path,

593

'/uploads/',

594

name='Advanced Files',

595

category='File Management'

596

))

597

```

598

599

### Image Gallery File Admin

600

601

```python

602

from markupsafe import Markup

603

604

class ImageGalleryFileAdmin(FileAdmin):

605

# Only allow image uploads

606

allowed_extensions = ('jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp')

607

608

list_template = 'admin/file/image_gallery.html' # Custom template

609

610

def __init__(self, *args, **kwargs):

611

super().__init__(*args, **kwargs)

612

# Add custom column formatter for image preview

613

self.column_formatters = {

614

'name': self._image_formatter

615

}

616

617

def _image_formatter(self, view, context, model, name):

618

"""Show image thumbnails in file list."""

619

if model and hasattr(model, 'name'):

620

filename = model.name

621

if self.is_image_file(filename):

622

# Generate image tag with thumbnail

623

image_url = f"{self.base_url}{filename}"

624

return Markup(f'''

625

<div class="image-preview">

626

<img src="{image_url}" style="max-width: 100px; max-height: 100px;" />

627

<br><small>{filename}</small>

628

</div>

629

''')

630

return filename

631

632

def is_image_file(self, filename):

633

"""Check if file is an image."""

634

return filename and filename.lower().endswith(self.allowed_extensions)

635

636

# Register image gallery

637

gallery_path = op.join(op.dirname(__file__), 'gallery')

638

admin.add_view(ImageGalleryFileAdmin(

639

gallery_path,

640

'/gallery/',

641

name='Image Gallery',

642

category='Media'

643

))

644

```