A lightweight Python command runner
Project description
🍥️ dony
A lightweight Python command runner with user interactions.
How it works
Write Python functions decorated with @dony.command(). Each command is a regular Python script with access to:
- Shell execution:
dony.shell()for running shell commands - User prompts:
dony.input(),dony.confirm(),dony.select()and more
# hello_world.py
import dony
@dony.command()
def hello_world():
dony.shell('echo "Hello, world!"')
if __name__ == "__main__":
hello_world()
Run it:
python hello_world.py
Quick Start
Install dony:
pip install dony
Optional dependencies for better experience:
# fzf for fuzzy selection (optional)
brew install fzf
# shfmt for shell command formatting (optional)
brew install shfmt
Core API
1. Commands
Decorate Python functions with @dony.command():
import dony
@dony.command()
def greet(name: str = 'World'):
"""Greets the user"""
dony.shell(f"echo Hello, {name}!")
if __name__ == "__main__":
greet()
The decorator handles:
- Changing to the correct working directory (configurable via
run_from) - Success/failure messages (configurable via
verbose)
Working directory options:
@dony.command(run_from=dony.RunFrom.GIT_ROOT) # Run from git root
@dony.command(run_from=dony.RunFrom.COMMAND_FILE) # Run from script's directory (default)
@dony.command(run_from=dony.RunFrom.CWD) # Run from current directory
@dony.command(run_from=dony.RunFrom.TEMP) # Run from temporary directory
@dony.command(run_from="/custom/path") # Run from custom path
2. Shell Execution
Execute shell commands with enhanced control and safety:
result = dony.shell('git status', quiet=True)
dony.shell('npm test', confirm=True) # Ask for confirmation first
dony.shell('ls', run_from='/tmp') # Run in specific directory
3. User Prompts
Rich interactive prompts for user input:
name = dony.input('Enter your name:', default='World')
if dony.confirm('Continue?'):
framework = dony.select('Pick a framework:', ['React', 'Vue', 'Angular'])
dony.success(f'You chose {framework}!')
Use cases
- Build, deploy, release scripts
- DevOps automation
- Testing workflows
- Git operations
- Any shell automation task
Important Notes
- Pure Python: Scripts are just Python functions - run them directly with
python script.py - Shell integration: Use
dony.shell()for any shell operations - Interactive by default: Built-in prompts make scripts user-friendly
- CLI is not currently implemented
API Reference
Available Functions
Prompts (based on questionary):
dony.input(message, default='', allow_empty=False, multiline=False): text entrydony.confirm(message, default=True): yes/no confirmation (uses select internally)dony.select(message, choices, default=None, fuzzy=True, allow_custom=False): single option pickerdony.select_many(message, choices, default=None, fuzzy=True): multi-option pickerdony.press_any_key(message): pause until keypress
Output:
dony.echo(message, style): styled text outputdony.error(message, prefix='✕ '): error message in reddony.success(message, prefix='✓ '): success message in green
Utilities:
dony.shell(command, **options): execute shell commandsdony.command(run_from, verbose): decorator for command functionsdony.find_git_root(path): find git repository root
Shell Command API
The dony.shell() function executes shell commands with enhanced features:
dony.shell(
command: str,
run_from: Optional[Union[str, Path]] = None, # Working directory
dry_run: bool = False, # Print command without executing
quiet: bool = False, # Suppress output
capture_output: bool = True, # Return output as string
abort_on_failure: bool = True, # Prepends 'set -e'
abort_on_unset_variable: bool = True, # Prepends 'set -u'
trace_execution: bool = False, # Prepends 'set -x'
show_command: bool = True, # Display formatted command
confirm: bool = False, # Ask before executing
) -> str
Example
import dony
@dony.command(run_from=dony.RunFrom.GIT_ROOT)
def deploy():
"""Deploy application"""
# Confirm action
if not dony.confirm("Deploy to production?"):
return
# Select environment
env = dony.select(
"Select environment:",
choices=["staging", "production"],
fuzzy=False
)
# Run build
dony.shell("npm run build")
# Run tests
dony.shell("npm test")
# Deploy
dony.shell(f"./deploy.sh {env}", confirm=True)
dony.success(f"Deployed to {env}")
if __name__ == "__main__":
deploy()
MIT License
Author
Mark Lidenberg marklidenberg@gmail.com
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dony-0.3.0.tar.gz.
File metadata
- Download URL: dony-0.3.0.tar.gz
- Upload date:
- Size: 49.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55e6693b271ebe0eaeb47b1986452a63c1ffc810c7a0e750d05374f408143894
|
|
| MD5 |
bbc3007cfa2284981722e2fea2743925
|
|
| BLAKE2b-256 |
4693d7161895f763456e085b11ded93609c42ab108a4660f9c824c8d7f9d038b
|
File details
Details for the file dony-0.3.0-py3-none-any.whl.
File metadata
- Download URL: dony-0.3.0-py3-none-any.whl
- Upload date:
- Size: 15.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c32b0e6f21491b53e9c44d8f05e8590a3c4a9650d7cf3a29b5fb2acad928b34a
|
|
| MD5 |
385eac0abb6429e168828ec3092fa803
|
|
| BLAKE2b-256 |
85f61679c11b288fee65781e540e2e446c343aa1bfea755217fee0d742d29b29
|