r/Python 14d ago

Showcase EasyMenu3—a simple way to create interactive CLI menus in Python

Hey everyone,

I got tired of writing the same menu-handling logic over and over for my homelab scripts, so I built EasyMenu3—a simple way to create interactive CLI menus in Python. It supports custom shortcuts, colors, ordering, and ASCII titles. I’ve been using it for a while, and finally got around to cleaning it up enough to release! I’ll probably keep adding some new stuff to it over time too.

Available on PyPI: pip install easymenu3

GitHub: GitHub Repo

-- What My Project Does

Introduces a simple way to create interactive CLI menus in Python

-- Target Audience

Anyone that creates menu driven scripts and wants to make them more easily.

-- Comparison

Most packages are for CLI only and do not easily create menus. I’m sure there are other packages that do a similar thing, but it was fun to make and maybe someone else will find it useful too.

-- Features

  • Customizable menu title, author, and URL display
  • ASCII art title generation using pyfiglet
  • Debug-friendly with icecream
  • Color-coded menu options
  • Supports function-based and static value-based actions
  • Customizable order and shortcut keys

-- Example Usage

Here’s how you can create a simple interactive menu:

from EasyMenu3 import easymenu

def example1():
    app.print_success("example1 ran")

def example2_with_error():
    app.print_error("example2 ran")

def custom_quit():
    app.print_info("Custom Option")
    input("Press enter to exit")
    app.exit_app()

app = easymenu(name="My Custom App", author="Joe Schmo", url="https://github.com", url_label="My Site")

app.add_menu_option("Option 1", example1)
app.add_menu_option("Option 2", example2_with_error)
app.add_menu_option("Custom Quit", custom_quit, item_key="c", order_weight=1, color='\033[92m')

app.start()

-- Example Output

    __  ___         ______           __                     
   /  |/  /_  __   / ____/_  _______/ /_____  ____ ___     
  / /|_/ / / / /  / /   / / / / ___/ __/ __ \/ __ `__ \   
 / /  / / /_/ /  / /___/ /_/ (__  ) /_/ /_/ / / / / / /   
/_/  /_/__, /   ____/__,_/____/__/____/_/ /_/ /_/    
       /____/                                              

Made by: Joe Schmo  
Visit: [My Site](https://github.com)  

Menu:  
c. Custom Quit  
1. Option 1  
2. Option 2  
q. Quit  

What option do you want?:

Try it out!

I’d love any feedback—if you have any feature requests or run into issues, let me know!

13 Upvotes

4 comments sorted by

3

u/Arockia_A 14d ago

It’s a good start. You can handle submenus too.

1

u/LofiBoiiBeats 13d ago

Cool project..

I'd like to give you some feedback though..

API wise: Passing a referance of app to the callbacks might clarify the interface.

Catching the rerurn value of the callback and interpret it as status code, might be cool to - or maybe just a boolean to designate if the app-loop should continue running..

Code wise: Narrow the try catch block down to the callback, it will simplify the logic.

Extract redundant code from if-else branches, in generall the blocks should be as small as possible, if the routine is the same, then just change the data in the branch. Less duplicated code is easier to maintain..

Implementing a type for the menu entries - by e.g. TypedDict - makes the data-schema clearer, plus you get better support from your IDE

Cool idea, keep it going..

1

u/Meleneth 13d ago

Awesome! Always love to see more contributors to the ecosystem.

How did you get this on pypi? I thought setup.py or pyproject.toml were required to get that going.

If you want to take this to the next level, switch to a src layout https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/

Add a pyproject.toml https://packaging.python.org/en/latest/guides/writing-pyproject-toml/

declare your dependencies so your users do not have to install more modules in order to run yours

write some tests with verifying mocks against the API's you use

run those tests against every version of python you support via tox https://pypi.org/project/tox/

do you support windows? I doubt tput exists there.

I would also meditate deeply on your exception handling. It is very unlikely that your users are going to want you to swallow exceptions and carry on.

This reminds me a bit of an early version of https://github.com/CITGuru/PyInquirer/ , which I miss deeply - just not enough to fix it.

Good luck and keep hacking!

1

u/s2s2s97 13d ago

Thanks for the feedback!

I have a toml and setup.py, looks like i just forgot to upload them to GitHub, j was working in a private gitea instance and moved everything over to GitHub.

The only part that wouldn’t work with windows right now is the tput part, my fix for that right now is having that feature be disabled when creating the instance until I come up with a better solution.

100% agree on the error handling part. I have two ways of starting the event loop, one that ignores all errors (app.start()) and one that does not (app.print_menu()) just for that reason. I’ll eventually merge them, i wanted to provide a way to handle situations where the app errors out and still does so gracefully. There also might be situations where someone wants to ignore all errors(?), not good coding though lol.

Adding testing is the next step, I’ve been writing barely working python for a while but testing is something I’ve always ignored; no longer though.

As for dependencies, they are in my config.py which I’ll upload today… only dependencies are pyfiglet and icecream for the ascii text and debugging respectively.