Skip to main content

EZInput

PyPI Python Version Downloads Docs License Tests Coverage Contributors GitHub stars GitHub forks DOI

EZInput Logo

Write once, run everywhere - Create interactive GUIs that work seamlessly in both Jupyter notebooks and terminal environments with the exact same code.

EZInput is a Python library that simplifies creating user interfaces for data science, image analysis, and computational research. Whether you're prototyping in a notebook or deploying a command-line tool, your UI code remains identical.

✨ Key Features

  • 🔄 Unified API: Same code works in Jupyter notebooks (.ipynb) and terminal scripts (.py)
  • 📋 Copy-Pastable: Move code between notebooks and scripts without modification
  • 💾 Auto-Persistence: Widget values are automatically saved and restored between sessions
  • 🎯 Type-Safe: Validated inputs with type checking (int, float, text, paths, etc.)
  • 🎨 Rich Widgets: Sliders, dropdowns, text inputs, file pickers, and more
  • ⚡ Zero Boilerplate: No environment detection code needed - it just works

Note: This project is currently in alpha stage and may undergo API changes.

🎯 Perfect For

  • Image analysis pipelines requiring user parameters
  • Data science workflows with interactive configuration
  • Research tools that need both notebook and CLI interfaces
  • Teaching and tutorials with reproducible parameter sets

📦 Installation

Install EZInput using pip:

pip install ezinput

For development with all optional dependencies:

pip install ezinput[all]

Requirements

  • Python >= 3.9
  • Dependencies are automatically installed:
    • ipywidgets and ipyfilechooser for Jupyter notebooks
    • prompt-toolkit for terminal interfaces
    • pyyaml for configuration persistence

🚀 Quick Start

The Simplest Example

from ezinput import EZInput

# Create a GUI (works in both Jupyter and terminal!)
gui = EZInput("my_app")

# Add widgets - order of adding determines display order
name = gui.add_text("name", "Enter your name:")
age = gui.add_int_range("age", "Select age:", 18, 100)
confirm = gui.add_check("confirm", "Proceed with analysis?")

# In Jupyter: display the widgets
gui.show()

# Access values
print(f"Hello {name.value}, you are {age.value} years old")
if confirm.value:
    print("Starting analysis...")

Running Jupyter Notebooks from Terminal

Execute notebooks as scripts using the ezinput command:

# Run a notebook from terminal
ezinput my_notebook.ipynb

# The notebook will execute with terminal-style prompts
# for all EZInput widgets

This is perfect for:

  • Running analysis pipelines in batch mode
  • Deploying notebook-based tools as CLI applications
  • CI/CD integration

💡 Copy-Paste Friendly: This exact code works in both:

  • Jupyter notebooks (.ipynb files) - displays interactive widgets
  • Terminal scripts (.py files) - shows interactive prompts

Run in terminal with:

python my_script.py

Real-World Example: Image Analysis

Here's a complete example for an image analysis pipeline:

from ezinput import EZInput
import numpy as np

# One EZInput instance per analysis task recommended
gui = EZInput("image_analysis_v1")

# Configuration section
gui.add_label(value="=== Image Processing Parameters ===")
input_file = gui.add_text("input", "Input image path:", 
                          placeholder="/path/to/image.tif")
threshold = gui.add_float_range("threshold", "Detection threshold:", 
                                0.0, 1.0)
min_size = gui.add_int_range("min_size", "Minimum object size (pixels):", 
                             10, 1000)

gui.add_label(value="=== Output Options ===")
save_results = gui.add_check("save", "Save results to disk?")
output_format = gui.add_dropdown("format", ["PNG", "TIFF", "JPEG"], 
                                 "Output format:")

# Display GUI (in Jupyter) or collect inputs (in terminal)
gui.show()

# Your analysis code using the values
def run_analysis(values):
    """Process image with user-provided parameters."""
    print(f"Processing {values['input'].value}")
    print(f"Using threshold: {values['threshold'].value}")
    print(f"Minimum size: {values['min_size'].value}")
    
    # Your image processing code here
    # ...
    
    if values['save'].value:
        print(f"Saving as {values['format'].value}")

# Add a callback button (in Jupyter: creates button, in terminal: executes after show())
gui.add_callback("process", run_analysis, gui.get_values(), 
                 description="Run Analysis")

Key Points:

  • Widget tags (like "input", "threshold") must be unique within each GUI instance
  • Create one EZInput instance per analysis task or computational pipeline
  • The order you add widgets is the order they appear on screen
  • Use remember_value=True parameter on widgets to persist values between runs

Terminal vs Jupyter: Same Code, Different Experience

In Jupyter Notebook:

  • Widgets appear as interactive UI elements
  • Sliders, dropdowns, and buttons are fully visual
  • Call gui.show() to display the interface

In Terminal:

  • Interactive prompts appear sequentially
  • Type-validated input with autocomplete
  • Press Enter to submit each value
  • Run with: python your_script.py

📚 Core Concepts

1. Automatic Environment Detection

EZInput automatically detects whether it's running in Jupyter or terminal:

from ezinput import EZInput

# No environment detection code needed!
gui = EZInput("my_app")

# Or import specific versions if needed:
from ezinput import EZInputJupyter  # Jupyter-specific
from ezinput import EZInputPrompt   # Terminal-specific

2. Value Persistence & Priority

Values are automatically saved to ~/.ezinput/{title}.yml. Priority order:

  1. Loaded parameters (from load_parameters())
  2. Remembered values (from previous runs, if remember_value=True parameter)
  3. Explicit defaults (passed via default= parameter)
  4. Widget defaults (empty string, 0, False, etc.)
# Values automatically persist when remember_value=True (default for most widgets)
gui = EZInput("my_app")
age = gui.add_int_range("age", "Age:", 0, 120, remember_value=True)
# Next time: shows the previously entered value!

# Load from specific configuration file
gui = EZInput("my_app")
gui.load_parameters("experiment_config.yml")

# Or save current values to share
gui.save_parameters("my_optimal_params.yml")

3. Configuration Files

Create shareable configuration files:

gui = EZInput("my_analysis")

# ... add widgets and collect values ...

# Save current values
gui.save_parameters("my_config.yml")  # Explicit filename
# or
gui.save_parameters("")  # Auto-named: my_analysis_parameters.yml

# Share this file with colleagues!
# They can load it:
gui2 = EZInput("my_analysis", params_file="my_config.yml")

Config file location:

  • Explicit saves: wherever you specify
  • Auto-saved settings: ~/.ezinput/{title}.yml

Resetting to defaults:

# Clear all remembered values - returns widgets to original defaults
gui.restore_defaults()

# ⚠️ Important: Re-run your cell (Jupyter) or script (terminal) to see the reset take effect
# The method removes the memory file but doesn't immediately change displayed widgets

🎨 Available Widgets

All widgets work identically in Jupyter and terminal. Here's the complete reference:

Text Input Widgets

Widget Description Example
add_text() Single-line text input gui.add_text("name", "Your name:")
add_text_area() Multi-line text input gui.add_text_area("notes", "Comments:")
# Text input with placeholder
email = gui.add_text("email", "Email address:", 
                     placeholder="user@example.com")

# Multi-line text area
notes = gui.add_text_area("description", "Project description:",
                          placeholder="Enter detailed description...")

Numeric Input Widgets

Widget Description Example
add_int_range() Integer slider/input with bounds gui.add_int_range("count", "Count:", 1, 100)
add_float_range() Float slider/input with bounds gui.add_float_range("alpha", "Alpha:", 0.0, 1.0)
add_int_text() Integer input (no bounds) gui.add_int_text("age", "Age:")
add_float_text() Float input (no bounds) gui.add_float_text("weight", "Weight:")
add_bounded_int_text() Integer input with validation gui.add_bounded_int_text("percent", "%:", 0, 100)
add_bounded_float_text() Float input with validation gui.add_bounded_float_text("ratio", "Ratio:", 0.0, 1.0)
# Slider-style (Jupyter) or validated prompt (terminal)
iterations = gui.add_int_range("iter", "Iterations:", 10, 1000)

# Free-form number input
temperature = gui.add_float_text("temp", "Temperature (°C):")

# Bounded input with automatic clamping
percentage = gui.add_bounded_int_text("coverage", "Coverage %:", 0, 100)

Selection Widgets

Widget Description Example
add_check() Boolean yes/no or checkbox gui.add_check("verbose", "Enable verbose output?")
add_dropdown() Single selection from list gui.add_dropdown("method", ["A", "B", "C"], "Method:")
# Boolean checkbox (Jupyter) or yes/no prompt (terminal)
debug = gui.add_check("debug", "Enable debug mode?")

# Dropdown with autocomplete in terminal
algorithm = gui.add_dropdown("algo", 
                             ["linear", "rbf", "polynomial"],
                             "Interpolation method:")

File & Path Widgets

Widget Environment Description
add_path_completer() Terminal only Path input with autocomplete
add_file_upload() Jupyter only Visual file picker
# Terminal: autocomplete-enabled path input
input_file = gui.add_path_completer("input", "Select input file:")

# Jupyter: visual file browser
input_file = gui.add_file_upload("input", accept="*.tif")

Display Widgets

Widget Description Example
add_label() Static text/header gui.add_label(value="=== Settings ===")
add_output() Output display area (Jupyter) gui.add_output("results")
add_HTML() Rich HTML content (Jupyter only) gui.add_HTML("info", "<b>Note:</b> ...")
# Section headers
gui.add_label(value="=== Input Parameters ===")

# Output area for results (Jupyter)
gui.add_output("results")
with gui["results"]:
    print("Analysis complete!")

# Rich formatting (Jupyter only)
gui.add_HTML("warning", '<p style="color:red">⚠️ Experimental feature</p>')

Callback & Actions

# add_callback ensures naming consistency between Jupyter and terminal
def process_data(values):
    """Process data with current parameter values."""
    threshold = values["threshold"].value
    method = values["method"].value
    print(f"Processing with {method} at threshold {threshold}")
    # Your processing code here...

# In Jupyter: creates a button
# In terminal: executes immediately
gui.add_callback("run", process_data, gui.get_values(), 
                 description="Start Processing")

Why add_callback? The name maintains API consistency between Jupyter (button-based) and terminal (immediate execution) interfaces.

💡 Best Practices

1. Unique Widget Tags

# ✅ Good: unique tags
gui.add_text("input_file", "File:")
gui.add_text("output_file", "Output:")

# ❌ Bad: duplicate tags
gui.add_text("file", "File:")
gui.add_text("file", "Output:")  # Overwrites the first one!

2. One GUI Per Task

# ✅ Good: separate GUIs for different analyses
preprocessing_gui = EZInput("preprocessing_v1")
analysis_gui = EZInput("main_analysis_v2")

# ❌ Avoid: reusing the same GUI instance for different purposes
gui = EZInput("multi_purpose")  # Config files may conflict

3. Meaningful Titles

# ✅ Good: descriptive, versioned titles
gui = EZInput("cell_segmentation_v2")
gui = EZInput("image_denoising_2024")

# ✅ Also good: user/project specific
gui = EZInput("john_experiment_setup")

# ❌ Avoid: generic titles that may conflict
gui = EZInput("test")
gui = EZInput("gui")

4. Display Order Matters

# Widgets appear in the order you add them
gui = EZInput("my_app")

# This order...
gui.add_label(value="=== Step 1 ===")
gui.add_text("name", "Name:")
gui.add_int_range("age", "Age:", 0, 120)
gui.add_label(value="=== Step 2 ===")  
gui.add_check("confirm", "Confirm?")

# ...is the order users see them in
gui.show()

📖 Documentation

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

📄 License

This project is licensed under the MIT License - see the LICENSE.txt file for details.


Made with ❤️ for the scientific Python community

Metadata

Release files for ezinput 0.0.18

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ezinput 0.0.18
File Size Uploaded
ezinput-0.0.18.tar.gz 29.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ezinput 0.0.18
File Interpreter ABI Platform
ezinput-0.0.18-py3-none-any.whl Python 3 none any Details

Total release size: 53.1 kB

Release files / ezinput-0.0.18.tar.gz

Download URL ezinput-0.0.18.tar.gz
Size 29.4 kB
Tags Source
SHA-256 checksum
How to use checksums
4a0a4b3aaefd1f1992a7622c82d75f6a9ac89c92617e2a503c6c7ea01c1871f6
BLAKE2b-256 checksum
How to use checksums
d0ec2004c82fa30dfe051f4f4fdd058cf2f91666ab7023b3a62176c3eb2bf9a5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release files / ezinput-0.0.18-py3-none-any.whl

Download URL ezinput-0.0.18-py3-none-any.whl
Size 23.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
aa226e7ab694338e97885d04c044aa9ef2fc8480801faf6d030413ed05951f45
BLAKE2b-256 checksum
How to use checksums
bac53d13f3e4a7b1f9d71f492b124ae6f3750ec2be6932a70243431c46e2ea57
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

0.0.18 This release

2 release files

0.0.13

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page