A modern, feature-rich Python library for creating interactive command-line selection interfaces. Pyckify (pick-it-for-you) offers an enhanced selection experience with support for multiselect, grouping, filtering, search, and rich styling.
- 🎨 Rich terminal UI with customizable themes
- ✨ Single and multi-selection modes
- 🔍 Built-in search functionality
- 🏷️ Option grouping and tagging
- ⌨️ Keyboard shortcuts
- 🎯 Custom filtering
- 📝 Option descriptions and icons
- ⚡ Smooth scrolling for large lists
- 🎭 Disabled options support
- 🎪 Windows/Unix compatible
pip install pyckifyfrom pyckify import Pyck, Option
# Simple string options
options = ["Red", "Blue", "Green", "Yellow"]
selected, index = Pyck(options, title="Choose a color")
print(f"Selected color: {selected}")
# Using Option objects
options = [
Option("🍎 Apple", description="Fresh from the garden"),
Option("🍌 Banana", description="Rich in potassium"),
Option("🍊 Orange", description="Vitamin C boost")
]
selected, index = Pyck(options, title="Choose a fruit")
print(f"Selected fruit: {selected.label}")from pyckify import Pyck, Option
options = [
Option("Python", description="General-purpose language"),
Option("JavaScript", description="Web development"),
Option("Rust", description="Systems programming"),
Option("Go", description="Cloud infrastructure")
]
result = Pyck(
options=options,
title="Select Programming Languages",
subtitle="Choose 2-3 languages for your project",
multiselect=True,
minSelectionCount=2,
maxSelectionCount=3,
separateValues=True # Returns a PickResult object
)
if result:
print("\nSelected languages:")
for lang in result.values:
print(f"- {lang.label}: {lang.description}")options = [
# Development Tools
Option("📝 VS Code",
description="Popular code editor",
group="Development Tools",
shortcut="v",
tags=["editor", "free"]),
Option("⚡ PyCharm",
description="Python IDE",
group="Development Tools",
shortcut="p",
tags=["ide", "paid"]),
# Version Control
Option("😺 GitHub",
description="Code hosting platform",
group="Version Control",
shortcut="g",
tags=["git", "cloud"]),
Option("🦊 GitLab",
description="DevOps platform",
group="Version Control",
shortcut="l",
tags=["git", "cloud"])
]
result = Pyck(
options=options,
title="Development Stack",
subtitle="Select your tools",
multiselect=True,
group_by="group",
show_shortcuts=True
)options = (
[Option(f" 🎞️ {video}", group="🎞️ Video Tracks", value=video) for video in videos] +
[Option(f" 🔊 {audio}", group="🔊 Audio Tracks", value=audio) for audio in audios] +
[Option(f" 💬 {subtitle}", group="💬 Subtitle Tracks", value=subtitle) for subtitle in subtitles]
)
result = Pyck(
options=options,
group_by="group",
multiselect=True,
minSelectionCount=1,
separateValues=True,
)
results = [value.value for option in result for value in option if isinstance(value, Option)]
if any(isinstance(value, VideoTrack) for value in results):
videos = [value for value in results if isinstance(value, VideoTrack)]
elif any(isinstance(value, AudioTrack) for value in results):
audios = [value for value in results if isinstance(value, AudioTrack)]
elif any(isinstance(value, SubtitleTrack) for value in results):
subtitles = [value for value in results if isinstance(value, SubtitleTrack)]Output:
↑↓ navigate • space select • a select all • enter confirm • / search • esc clear filters/quit
↑ More options above
🎞️ Video Tracks
🎞️ VIDEO: BnGFobSd | avc1.4d401f | SDR | 480x360 | 901 kbps | 29.970 FPS
🎞️ VIDEO: 6EFRMq5M | avc1.4d401f | SDR | 480x360 | 494 kbps | 29.970 FPS
🔊 Audio Tracks
🔊 AUDIO: KuHayhsL | AAC | 2.0 | 128 kbps | yue
🔊 AUDIO: 4r83sM8H | AAC | 2.0 | 128 kbps | da
🔊 AUDIO: BpZJpQs8 | AAC | 2.0 | 128 kbps | de
🔊 AUDIO: eXSUTLgz | AAC | 2.0 | 128 kbps | en
🔊 AUDIO: kZ9xNLh5 | AAC | 2.0 | 128 kbps | es-ES
🔊 AUDIO: RRZLJ5Lj | AAC | 2.0 | 128 kbps | es-419
🔊 AUDIO: 9ciYXZEy | AAC | 2.0 | 128 kbps | fr-FR
→ 🔊 AUDIO: QyEd8Mp6 | AAC | 2.0 | 128 kbps | el
↓ More options below
Selected: 0 (minimum: 1)
from dataclasses import dataclass
from pyckify import Pyck, Option
@dataclass
class Language:
name: str
type: str
year: int
popularity: int
options = [
Option(f"🌟 {lang.name}",
description=f"Created in {lang.year}",
value=lang,
tags=[lang.type],
group=f"Popularity: {lang.popularity}/10")
for lang in [
Language("Python", "interpreted", 1991, 10),
Language("JavaScript", "interpreted", 1995, 9),
Language("Rust", "compiled", 2010, 7),
Language("Go", "compiled", 2009, 7)
]
]
# Custom filter for modern languages
def modern_languages(option: Option) -> bool:
return option.value.year >= 2010
result = Pyck(
options=options,
title="Programming Language Selection",
subtitle="Modern languages only (2010+)",
multiselect=True,
filter_fn=modern_languages,
group_by="group"
)options = [
Option("✨ Premium Plan",
description="All features included",
enabled=True),
Option("💎 Enterprise Plan",
description="Custom solutions",
enabled=True),
Option("🔒 Legacy Plan",
description="No longer available",
enabled=False)
]
result = Pyck(
options=options,
title="Subscription Plans",
subtitle="Select an available plan"
)The main function for creating selection interfaces.
def Pyck(
options: Sequence[OPTION_T],
title: Optional[str] = None,
subtitle: Optional[str] = None,
indicator: str = "→",
defaultIndex: int = 0,
multiselect: bool = False,
minSelectionCount: int = 0,
maxSelectionCount: Optional[int] = None,
filter_fn: Optional[Callable[[OPTION_T], bool]] = None,
show_shortcuts: bool = True,
group_by: Optional[str] = None,
separateValues: bool = False,
) -> Union[PickResult, Union[List[PICK_RETURN_T], PICK_RETURN_T]]options: List of options to choose from (strings or Option objects)title: Title displayed at the topsubtitle: Subtitle displayed below the titleindicator: Cursor indicator symboldefaultIndex: Starting selection indexmultiselect: Enable multiple selectionsminSelectionCount: Minimum required selections (multiselect mode)maxSelectionCount: Maximum allowed selections (multiselect mode)filter_fn: Custom filtering functionshow_shortcuts: Show keyboard shortcutsgroup_by: Group options by attributeseparateValues: Return separated values and indices
Class for creating rich options with metadata.
@dataclass
class Option:
label: str
value: Union[object, str, Any] = None
description: Optional[str] = None
enabled: bool = True
shortcut: Optional[str] = None
icon: Optional[str] = None
group: Optional[str] = None
tags: List[str] = field(default_factory=list)label: Display textvalue: Associated value (optional)description: Additional descriptionenabled: Whether the option can be selectedshortcut: Keyboard shortcut keyicon: Display icongroup: Group name for groupingtags: List of tags for categorization
Class for creating visual separators in the option list.
@dataclass
class Separator(Option):
def __init__(self, label: str, description: Optional[str] = None):
super().__init__(label, description=description, enabled=False)↑/↓: Navigate optionsEnter: Confirm selectionSpace: Toggle selection (multiselect mode)a: Select/deselect all (multiselect mode)/: Enable searchEsc: Clear filters/exit
Pyckify uses a custom theme system for consistent styling:
custom_theme = {
"title": Style(bold=True, color="dark_orange"),
"subtitle": Style(italic=True, color="cyan"),
"indicator": Style(bold=True, color="bright_yellow"),
"selected": Style(bold=True, color="green"),
"active": Style(bold=True, color="white", bgcolor="blue"),
"disabled": Style(dim=True, color="grey70"),
"description": Style(italic=True, color="bright_blue"),
"shortcut": Style(bold=True, color="red"),
}Check out the examples directory for more usage scenarios:
- Basic selection
- Multi-select with constraints
- Grouped options
- Custom filtering
- Disabled options
- Rich formatting
- Search functionality
- Keyboard shortcuts
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
ReiDoBrega (@ReiDoBrega)
Made with ❤️ using Python