Simple and extensible admin interface framework for Flask
86
Quality
Pending
Does it follow best practices?
Impact
86%
1.30xAverage score across 10 eval scenarios
File and directory administration interface with upload, download, edit capabilities, and flexible storage backend system for managing files through Flask-Admin.
Storage abstraction layer supporting different file storage backends with consistent interface.
class LocalFileStorage:
def __init__(self, base_path):
"""
Initialize local filesystem storage backend.
Args:
base_path (str): Base directory path for file operations
"""
def get_base_path(self):
"""
Get base directory path.
Returns:
str: Base directory path
"""
def make_dir(self, path, directory):
"""
Create directory.
Args:
path (str): Parent directory path
directory (str): New directory name
Returns:
bool: True if successful
"""
def get_files(self, path, directory):
"""
List files and directories in given path.
Args:
path (str): Directory path to list
directory (str): Directory name
Returns:
list: File and directory information
"""
def delete_tree(self, directory):
"""
Delete directory recursively.
Args:
directory (str): Directory path to delete
Returns:
bool: True if successful
"""
def delete_file(self, file_path):
"""
Delete single file.
Args:
file_path (str): Path to file to delete
Returns:
bool: True if successful
"""
def path_exists(self, path):
"""
Check if path exists.
Args:
path (str): Path to check
Returns:
bool: True if path exists
"""
def rename_path(self, src, dst):
"""
Rename file or directory.
Args:
src (str): Source path
dst (str): Destination path
Returns:
bool: True if successful
"""
def is_dir(self, path):
"""
Check if path is directory.
Args:
path (str): Path to check
Returns:
bool: True if path is directory
"""
def send_file(self, file_path):
"""
Send file to user for download.
Args:
file_path (str): Path to file
Returns:
Response: Flask file response
"""
def read_file(self, path):
"""
Read file contents.
Args:
path (str): File path to read
Returns:
str: File contents as string
"""
def write_file(self, path, content):
"""
Write content to file.
Args:
path (str): File path to write
content (str): Content to write
Returns:
bool: True if successful
"""
def save_file(self, path, file_data):
"""
Save uploaded file data.
Args:
path (str): Destination file path
file_data: File data from upload
Returns:
bool: True if successful
"""Foundation class for file administration interfaces with comprehensive file and directory management.
class BaseFileAdmin(BaseView, ActionsMixin):
def __init__(
self,
base_url=None,
name=None,
category=None,
endpoint=None,
url=None,
verify_path=True,
menu_class_name=None,
menu_icon_type=None,
menu_icon_value=None,
storage=None
):
"""
Initialize base file administration interface.
Args:
base_url (str, optional): Base URL for file serving
name (str, optional): View name for menu
category (str, optional): Menu category
endpoint (str, optional): Blueprint endpoint
url (str, optional): URL prefix
verify_path (bool): Verify path accessibility
menu_class_name (str, optional): Menu CSS class
menu_icon_type (str, optional): Icon type
menu_icon_value (str, optional): Icon identifier
storage: Storage backend instance
"""
# Permission configuration
can_upload = True # Allow file uploads
can_download = True # Allow file downloads
can_delete = True # Allow file deletion
can_delete_dirs = True # Allow directory deletion
can_mkdir = True # Allow directory creation
can_rename = True # Allow renaming files/directories
# File type restrictions
allowed_extensions = None # Allowed file extensions (None = all)
editable_extensions = ('md', 'txt', 'py', 'js', 'html', 'css', 'json', 'xml', 'yaml', 'yml', 'ini', 'cfg')
# Interface configuration
list_template = 'admin/file/list.html'
upload_template = 'admin/file/upload.html'
mkdir_template = 'admin/file/mkdir.html'
def is_accessible_path(self, path):
"""
Check if path is accessible for current user.
Args:
path (str): Path to check
Returns:
bool: True if accessible
"""
def get_base_path(self):
"""
Get base path for file operations.
Returns:
str: Base path
"""
def is_file_allowed(self, filename):
"""
Check if file upload is permitted based on extension.
Args:
filename (str): Filename to check
Returns:
bool: True if allowed
"""
def is_file_editable(self, filename):
"""
Check if file can be edited inline.
Args:
filename (str): Filename to check
Returns:
bool: True if editable
"""
# View methods (exposed via @expose decorator)
def index(self):
"""
File browser index view.
Returns:
str: Rendered file browser template
"""
def upload(self):
"""
File upload view.
Returns:
str: Rendered upload template or redirect
"""
def download(self):
"""
File download view.
Returns:
Response: File download response
"""
def edit(self):
"""
File edit view for text files.
Returns:
str: Rendered edit template or redirect
"""
def rename(self):
"""
Rename file or directory view.
Returns:
str: Rendered rename template or redirect
"""
def mkdir(self):
"""
Create directory view.
Returns:
str: Rendered mkdir template or redirect
"""
# Action methods
def action_delete(self, items):
"""
Batch delete action for selected files/directories.
Args:
items (list): List of file/directory paths to delete
"""
def action_edit(self, items):
"""
Batch edit action for selected text files.
Args:
items (list): List of file paths to edit
"""
class FileAdmin(BaseFileAdmin):
def __init__(self, base_path, *args, **kwargs):
"""
Simple file management interface for local filesystem.
Args:
base_path (str): Base directory path to manage
*args: Additional positional arguments
**kwargs: Additional keyword arguments
"""Cloud storage backend for Amazon S3 with full file management capabilities including upload, download, and directory operations.
from flask_admin.contrib.fileadmin.s3 import S3Storage
class S3Storage:
def __init__(
self,
bucket_name,
region,
aws_access_key_id,
aws_secret_access_key
):
"""
Amazon S3 storage backend.
Parameters:
- bucket_name: str, Name of the S3 bucket
- region: str, AWS region where bucket is located
- aws_access_key_id: str, AWS Access Key ID
- aws_secret_access_key: str, AWS Secret Access Key
"""Microsoft Azure Blob Storage backend for cloud-based file management with container support.
from flask_admin.contrib.fileadmin.azure import AzureStorage
class AzureStorage:
def __init__(self, container_name, connection_string):
"""
Azure Blob Storage backend.
Parameters:
- container_name: str, Name of the Azure storage container
- connection_string: str, Azure Blob Storage connection string
"""from flask import Flask
from flask_admin import Admin
from flask_admin.contrib.fileadmin import FileAdmin
import os.path as op
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret-key'
# Initialize admin
admin = Admin(app, name='File Manager')
# Add file admin for uploads directory
path = op.join(op.dirname(__file__), 'uploads')
admin.add_view(FileAdmin(path, '/uploads/', name='Upload Files'))
# Add file admin for static files with restricted permissions
static_path = op.join(op.dirname(__file__), 'static')
admin.add_view(FileAdmin(
static_path,
'/static/',
name='Static Files',
category='Files'
))from flask_admin.contrib.fileadmin import FileAdmin
from flask_login import current_user
class RestrictedFileAdmin(FileAdmin):
# File type restrictions
allowed_extensions = ('txt', 'md', 'py', 'js', 'css', 'html', 'json', 'xml')
editable_extensions = ('txt', 'md', 'py', 'js', 'css', 'html', 'json')
# Permission configuration
can_upload = True
can_download = True
can_delete = False # Disable deletion
can_delete_dirs = False
can_mkdir = True
can_rename = True
def is_accessible(self):
"""Only allow access to authenticated admin users."""
return current_user.is_authenticated and current_user.is_admin
def is_accessible_path(self, path):
"""Restrict access to certain directories."""
# Prevent access to hidden directories
if '/.git' in path or '/.env' in path:
return False
# Prevent access to Python cache directories
if '__pycache__' in path:
return False
return super().is_accessible_path(path)
def is_file_allowed(self, filename):
"""Additional file upload restrictions."""
# Block executable files
if filename.lower().endswith(('.exe', '.bat', '.sh', '.com')):
return False
return super().is_file_allowed(filename)
# Register with admin
uploads_path = op.join(op.dirname(__file__), 'uploads')
admin.add_view(RestrictedFileAdmin(
uploads_path,
'/uploads/',
name='Managed Files',
category='File Management'
))from flask_admin.contrib.fileadmin import BaseFileAdmin, LocalFileStorage
import os
import shutil
from werkzeug.utils import secure_filename
class S3FileStorage:
"""Example custom storage backend for AWS S3."""
def __init__(self, bucket_name, aws_access_key, aws_secret_key):
"""
Initialize S3 storage backend.
Args:
bucket_name (str): S3 bucket name
aws_access_key (str): AWS access key
aws_secret_key (str): AWS secret key
"""
self.bucket_name = bucket_name
# Initialize S3 client here
pass
def get_files(self, path, directory):
"""List files in S3 bucket path."""
# Implement S3 listing logic
pass
def save_file(self, path, file_data):
"""Upload file to S3."""
# Implement S3 upload logic
pass
def delete_file(self, file_path):
"""Delete file from S3."""
# Implement S3 deletion logic
pass
# Implement other required methods...
class CustomFileAdmin(BaseFileAdmin):
def __init__(self, storage_config, *args, **kwargs):
# Initialize with custom storage backend
storage = S3FileStorage(**storage_config)
super().__init__(storage=storage, *args, **kwargs)
# Usage with custom storage
s3_config = {
'bucket_name': 'my-files-bucket',
'aws_access_key': 'your-access-key',
'aws_secret_key': 'your-secret-key'
}
admin.add_view(CustomFileAdmin(
s3_config,
name='S3 Files',
category='Cloud Storage'
))from flask_admin.contrib.fileadmin import FileAdmin
from flask import flash, request, redirect, url_for
import os
import zipfile
from PIL import Image
class AdvancedFileAdmin(FileAdmin):
# Enhanced file type support
allowed_extensions = ('txt', 'md', 'py', 'js', 'css', 'html', 'json', 'xml',
'jpg', 'jpeg', 'png', 'gif', 'pdf', 'zip', 'tar', 'gz')
editable_extensions = ('txt', 'md', 'py', 'js', 'css', 'html', 'json', 'xml', 'yaml', 'yml')
def on_file_upload(self, directory, path, filename):
"""Hook called after successful file upload."""
file_path = os.path.join(path, filename)
# Auto-generate thumbnails for images
if filename.lower().endswith(('jpg', 'jpeg', 'png')):
self.generate_thumbnail(file_path)
# Auto-extract ZIP files
if filename.lower().endswith('.zip') and request.form.get('auto_extract'):
self.extract_zip(file_path, directory)
def generate_thumbnail(self, image_path):
"""Generate thumbnail for uploaded image."""
try:
with Image.open(image_path) as img:
img.thumbnail((200, 200))
thumb_path = image_path.rsplit('.', 1)[0] + '_thumb.' + image_path.rsplit('.', 1)[1]
img.save(thumb_path)
flash(f'Generated thumbnail: {os.path.basename(thumb_path)}', 'success')
except Exception as ex:
flash(f'Failed to generate thumbnail: {str(ex)}', 'warning')
def extract_zip(self, zip_path, target_dir):
"""Extract ZIP file contents."""
try:
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
extract_path = os.path.join(target_dir, 'extracted')
os.makedirs(extract_path, exist_ok=True)
zip_ref.extractall(extract_path)
flash(f'Extracted ZIP contents to: extracted/', 'success')
except Exception as ex:
flash(f'Failed to extract ZIP: {str(ex)}', 'error')
@expose('/compress/')
def compress_files(self):
"""Custom action to compress selected files."""
if request.method == 'POST':
file_paths = request.form.getlist('file_paths')
if file_paths:
zip_name = request.form.get('zip_name', 'archive.zip')
self.create_zip_archive(file_paths, zip_name)
return redirect(url_for('.index'))
return self.render('admin/file/compress.html')
def create_zip_archive(self, file_paths, zip_name):
"""Create ZIP archive from selected files."""
try:
zip_path = os.path.join(self.get_base_path(), zip_name)
with zipfile.ZipFile(zip_path, 'w') as zip_file:
for file_path in file_paths:
full_path = os.path.join(self.get_base_path(), file_path)
if os.path.exists(full_path):
zip_file.write(full_path, file_path)
flash(f'Created archive: {zip_name}', 'success')
except Exception as ex:
flash(f'Failed to create archive: {str(ex)}', 'error')
# Register advanced file admin
admin.add_view(AdvancedFileAdmin(
uploads_path,
'/uploads/',
name='Advanced Files',
category='File Management'
))from markupsafe import Markup
class ImageGalleryFileAdmin(FileAdmin):
# Only allow image uploads
allowed_extensions = ('jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp')
list_template = 'admin/file/image_gallery.html' # Custom template
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Add custom column formatter for image preview
self.column_formatters = {
'name': self._image_formatter
}
def _image_formatter(self, view, context, model, name):
"""Show image thumbnails in file list."""
if model and hasattr(model, 'name'):
filename = model.name
if self.is_image_file(filename):
# Generate image tag with thumbnail
image_url = f"{self.base_url}{filename}"
return Markup(f'''
<div class="image-preview">
<img src="{image_url}" style="max-width: 100px; max-height: 100px;" />
<br><small>{filename}</small>
</div>
''')
return filename
def is_image_file(self, filename):
"""Check if file is an image."""
return filename and filename.lower().endswith(self.allowed_extensions)
# Register image gallery
gallery_path = op.join(op.dirname(__file__), 'gallery')
admin.add_view(ImageGalleryFileAdmin(
gallery_path,
'/gallery/',
name='Image Gallery',
category='Media'
))Install with Tessl CLI
npx tessl i tessl/pypi-flask-admindocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10