Shell Completion
Cyclopts provides shell completion (tab completion) for bash, zsh, and fish shells.
Development & Standalone Scripts
Shell completion systems (bash, zsh, fish) can only provide completion for installed commands (executables in your $PATH), not for arbitrary Python scripts like python myapp.py. This is a fundamental limitation of how shells work.
To work around this during development, Cyclopts provides a cyclopts run command that acts as a wrapper:
$ cyclopts run myapp.py --help
$ cyclopts run myapp.py:app --verbose
Since cyclopts itself is an installed command, the shell can provide completion for it. The cyclopts run command then loads and executes your script, giving you completion for your development scripts without needing to package and install them.
Script Path Format:
cyclopts run script.py- Auto-detects the App object. If an App object cannot be determined, it will raise an error.cyclopts run script.py:app- Explicitly specifies the App object to run
This is particularly useful during development before packaging your application.
Virtual Environment Behavior:
cyclopts run imports your script directly into the same Python process (no subprocess is created). This means:
It uses whatever Python interpreter is currently running
cycloptsYour script has access to all packages installed in the current environment
You must install
cycloptsin your project's virtual environmentTo use: activate your venv, then run
cyclopts run script.py
$ source .venv/bin/activate # or your venv activation method
$ cyclopts run myapp.py
Note
Completion for your script's commands comes through the cyclopts CLI completion.
Install it once with: cyclopts --install-completion
Warning
Performance: cyclopts run uses dynamic completion, which imports your script and calls Python on every tab press. This can be slow if your script has heavy imports.
To mitigate slow imports during development, consider using Lazy Loading for your commands. For production or frequent use, install static completion using the methods below. Static completion is pre-generated and does not call Python, making it instantaneous.
To install completion specifically for your standalone script (without using cyclopts run), you can use the Manual Installation approach below with your script's App object.
Installation
Programmatic Installation (Recommended)
Add completion installation to your CLI application using App.register_install_completion_command:
from cyclopts import App
app = App(name="myapp")
app.register_install_completion_command()
# Your commands here...
if __name__ == "__main__":
app()
Users can then install completion by running:
myapp --install-completion
Manual Installation
For programmatic control, use App.install_completion directly:
from cyclopts import App
from pathlib import Path
app = App(name="myapp")
# Install for current shell
install_path = app.install_completion()
print(f"Installed completion to {install_path}")
# Install for specific shell
install_path = app.install_completion(shell="zsh")
# Install to custom location
install_path = app.install_completion(
shell="bash",
output=Path("/custom/path/completion.sh"),
)
Default Installation Paths
Zsh:
~/.zsh/completions/_<app_name>Bash:
~/.local/share/bash-completion/completions/<app_name>Fish:
~/.config/fish/completions/<app_name>.fish
Script Generation
To generate a completion script without installing it, use App.generate_completion:
from cyclopts import App
app = App(name="myapp")
script = app.generate_completion(shell="zsh")
print(script)
Shell Configuration
By default, Cyclopts modifies your shell RC file to enable completion:
Zsh: Adds to
~/.zshrcBash: Adds to
~/.bashrcFish: No modification needed (automatically loads from
~/.config/fish/completions/)
After installation, restart your shell or source the RC file.
To install without modifying shell RC files, use:
app.register_install_completion_command(add_to_startup=False)