Building Web Interfaces for Python CLI Applications with Wooey
Creating command-line interfaces that are accessible to non-technical users can be challenging. Wooey solves this problem by automatically generating web-based frontends for Python scripts, making them accessible through a browser without requiring users to interact with a terminal.
Wooey is built on Django and transforms ordinary Python functions into web applications with minimal configuration. This approach bridges the gap between developers who prefer writing scripts and end-users who need graphical interfaces.
Installation and Setup
Install Wooey using pip:
pip install wooey
Creating a Basic Web-Enabled Script
The core concept behind Wooey is wrapping Python functions with the AppRunner class. This automatically generates a web form based on the function's parameters and docstring.
# greeter.py
from wooey import AppRunner
def greet_user(username):
"""
Displays a personalized greeting message.
:param username: The name of the person to greet.
"""
print(f"Greetings, {username}! Welcome aboard.")
if __name__ == '__main__':
AppRunner(greet_user)
When executed with python greeter.py, Wooey launches a local web server displaying an interface where users can input the username parameter and execute the function.
Advanced Configuration
Customizing the Web Interface
Wooey allows customization of the generated interface through Django settings. Configure the appearance by modifying WOOEY_SETTINGS:
# settings.py
WOOEY_SETTINGS = {
'HEADER_CONTENT': 'Data Processing Dashboard',
'HEADER_HELP': 'Upload files and configure parameters below',
'PAGE_TITLE': 'Automation Tools',
}
Typed Parameters and Input Validation
Wooey supports various field types for parameter validation, including integers, floats, files, and choices. These fields automatically generate appropriate input widgets in the web interface.
# calculator.py
from wooey import AppRunner, IntegerField
def calculate_power(base: int, exponent: int = 2):
"""
Computes the power of a number.
:param base: The base number.
:param exponent: The exponent to raise the base to.
"""
result = base ** exponent
print(f"{base} raised to the power of {exponent} equals {result}")
if __name__ == '__main__':
AppRunner(calculate_power, fields=[
IntegerField("base"),
IntegerField("exponent", initial=2)
])
Practical Use Cases
File Processing Pipeline
Building tools for processing uploaded files is straightforward with Wooey's FileField. This is particularly useful for data transformation tasks:
# file_converter.py
from wooey import AppRunner, FileField
def convert_text_file(source_path: str, destination_path: str):
"""
Reads a text file and saves a modified version.
:param source_path: Path to the source file.
:param destination_path: Path for the output file.
"""
with open(source_path, 'r', encoding='utf-8') as source:
content = source.read()
# Transform: convert to lowercase and add line numbers
lines = content.split('\n')
numbered_lines = [f"{idx + 1}: {line}" for idx, line in enumerate(lines)]
transformed_content = '\n'.join(numbered_lines)
with open(destination_path, 'w', encoding='utf-8') as dest:
dest.write(transformed_content)
if __name__ == '__main__':
AppRunner(convert_text_file, fields=[
FileField("source_path"),
FileField("destination_path")
])
Image Manipulation Tool
Wooey works well with image processing libraries. The following example creates a web interface for batch image resizing:
# resizer.py
from wooey import AppRunner, FileField, FloatField, ChoiceField
from PIL import Image
def resize_image(input_path: str, output_path: str, factor: float, format_type: str):
"""
Resizes an image by a specified factor.
:param input_path: Source image file.
:param output_path: Destination for resized image.
:param factor: Scaling multiplier (0.1 to 3.0).
:param format_type: Output image format.
"""
original = Image.open(input_path)
original_width, original_height = original.size
new_dimensions = (
int(original_width * factor),
int(original_height * factor)
)
resized = original.resize(new_dimensions, Image.Resampling.LANCZOS)
resized.save(output_path, format=format_type.upper())
print(f"Image saved to {output_path} with dimensions {new_dimensions}")
if __name__ == '__main__':
AppRunner(resize_image, fields=[
FileField("input_path"),
FileField("output_path"),
FloatField("factor", initial=1.0, min_value=0.1, max_value=3.0),
ChoiceField("format_type", choices=["PNG", "JPEG", "WEBP"])
])
This implementation allows users to upload images through the browser, specify scaling factors within defined bounds, and select output formats from a dropdown menu.
Integration with Django Projects
For more complex applications, Wooey can be integrated into existing Django projects. Add 'wooey' to your INSTALLED_APPS and run migrations to set up the database tables that store script configurations and execution history.
# settings.py in Django project
INSTALLED_APPS = [
# ... existing apps ...
'wooey',
]
# Optional: Configure Wooey behavior
WOOEY_SETTINGS = {
'SCRIPT_DIR': '/path/to/scripts',
'ALLOW_ANONYMOUS': False,
}
The Django integration provides user authentication, execution history tracking, and the ability to share scripts across teams while maintaining access control.