An application is better when it encourages and enables discoverability. Instead of being expected to memorize an entire user manual up front, users learn the application by using and exploring it. When I write Python applications, I like to use the Trogon library, which allows me to create a simple in-terminal GUI (called a “TUI”) to help users navigate the application visually.
Requirements
To follow along with this tutorial, you must have:
- Linux distribution, preferably one that uses RPM (Like Fedora or Red Hat Enterprise Linux)
- Python 3.7 or greater
- Git
- A familiarity with virtual environments
- An Internet connection so you can download dependencies
Using Trogon
For this tutorial, I reuse the source code of my open source rpm_query application. The rpm_query application is a collection of simple commands that can query your system’s RPM database from a terminal.
Adding Trogon to your code is easy. First, add the new Trogon library as part of your code’s requirements.txt and setup.cfg files.
Then, add a new decorator to your code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#!/usr/bin/env python """ A simple CLI to query the sizes of RPM on your system Author: Jose Vicente Nunez """ import click from trogon import tui from reporter.rpm_query import QueryHelper @tui() @click.command() @click.option('--limit', default=QueryHelper.MAX_NUMBER_OF_RESULTS, help="By default results are unlimited but you can cap the results") @click.option('--name', help="You can filter by a package name.") @click.option('--sort', default=True, help="Sorted results are enabled bu default, but you fan turn it off") def command( name: str, limit: int, sort: bool ) -> None: with QueryHelper( name=name, limit=limit, sorted_val=sort ) as rpm_query: for package in rpm_query: click.echo(f"{package['name']}-{package['version']}: {package['size']:,.0f}") if __name__ == "__main__": command() |
Yes, all it takes is one annotation (@tui
) and an import!
Trogon in action
One reason I love Trogon so much is that your user doesn’t have to use a TUI if they don’t want to. The command-line is always available, as usual:
1 2 3 4 5 6 7 8 9 |
(env)$ rpmq_trogon.py --help Usage: rpmq_trogon.py [OPTIONS] COMMAND [ARGS]... Options: --help Show this message and exit. Commands: command tui Open Textual TUI. |
If you want to use the CLI options, you prepend the subcommand command
before you provide any arguments. If you want to use the TUI, then you use the tui
subcommand.
For help, you pass the --help
option after the command
subcommand:
1 2 3 4 5 6 7 8 9 10 |
(env)$ rpmq_trogon.py command --help Usage: rpmq_trogon.py command [OPTIONS] Options: --limit INTEGER By default results are unlimited but you can cap the results --name TEXT You can filter by a package name. --sort BOOLEAN Sorted results are enabled bu default, but you fan turn it off --help Show this message and exit. |
The command works as expected:
1 2 3 4 |
(env)$ rpmq_trogon.py command --limit 5 --name kernel kernel-6.2.11: 0 kernel-6.2.14: 0 kernel-6.2.15: 0 |
The TUI mode helps users discover its features:
Using setuptools and Trogon
You can use setuptools with Trogon. Create a package called scripts inside the package called reporter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[metadata] name = CLIWithClickAndTrogon version = 0.0.1 author = Jose Vicente Nunez Zuleta author-email = kodegeek.com@example.com license = Apache 2.0 summary = Query your RPM database with the CLI or TUI. home-page = https://github.com/josevnz/cliwithclickandtrogon description = Query your RPM database with the CLI or TUI. A tutorial. long_description = file: README.md long_description_content_type = text/markdown [options] packages = reporter setup_requires = setuptools wheel build pip twine install_requires = importlib; python_version == "3.9" click scripts = scripts/rpmq_simple.py scripts/rpmq_click.py [options.entry_points] console_scripts = rpmq = reporter.scripts:command |
Add the import and the annotation to the command
function section:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import click from trogon import tui from reporter.rpm_query import QueryHelper @tui() @click.command() @click.option('--limit', default=QueryHelper.MAX_NUMBER_OF_RESULTS, help="By default results are unlimited but you can cap the results") @click.option('--name', help="You can filter by a package name.") @click.option('--sort', default=True, help="Sorted results are enabled bu default, but you fan turn it off") def command( name: str, limit: int, sort: bool ) -> None: # .... real code goes here pass |
A script called rpmq is created by setuptools, and it works exactly as expected.
What is next
- Download the source code for this tutorial and start experimenting.
- Trogon has great documentation and online support. Take advantage of it!
0 Comments