Hacker News new | past | comments | ask | show | jobs | submit login
Gooey: Turn almost any Python command line program into a GUI application (github.com/chriskiehl)
693 points by sandebert 44 days ago | hide | past | favorite | 115 comments

Gooey is a brilliant bit of software.

We use it in combination with Python Fire [0] to easily convert python code to something that users can interact with. Python fire converts our python code into a CLI without all the manual parameter parsing, and Gooey turns the CLI into a simple GUI.

[0] https://github.com/google/python-fire

Brilliant workflow!

Today I learned about Fire AND Gooey

Sometimes I get bogged down in writing proper argparse when it really is not needed.

Are there any edge cases where Fire does not work too well, like some strange parameters (for example tuple as dictionary key)?

If you like the look of fire for the ease of creating a cli but wish it automatically did validation based on type annotations, you might like Typer[0]. The pathlib parameters are especially handy, I find.

[0] https://github.com/tiangolo/typer

You had me at pathlib! I wish people used it more...

For anyone who doesn’t know what pathlib is: https://docs.python.org/3/library/pathlib.html

I love fastapi I wish I knew about this before!

I also recommend checking out Clicky. It is similar to Fire, but has been out there for very long time and has some more power features and documentation.

Same! TIL Fire & Gooey is a power move.

Same! Thanks.

I've been using Gooey quite a lot lately and I'm really tired of setting up Argparse every time. Your recommendation of Fire came at exactly the right time! Thanks

an interesting related tool is https://github.com/fredrik-corneliusson/click-web which builds on the click library to create web front ends automatically.

Oh damn, that's fantastic! I wanted to write a small server that did something between this and Fire above (i.e. allowed you to drop a Python script into a directory and would create a UI for its functions). It's a great way to make small, random functions I've written accessible to people with zero work.

Just found out about this, looks cool! Unfortunately file handling is a bit wonky, I suspect some of that is just the web platform (e.g. can't select directories), while some of it is probably due to a lack of bandwidth from what looks to mostly be a solo developer.

I’m not familiar with Fire, but I assume it uses argparse under the hood? Do you put the Gooey annotation on the function that calls fire.fire?

Actually, I misspoke slightly when I said it turns the GUI into a CLI. Rather, it turns the same underlying class into a GUI.

So we have one file which contains the class with all the functions we want to expose (in our case, the class is named JobManager). At the end, it goes

    if __name__ == '__main__':
which takes care of all the CLI access we could want.

Then we have a second file for the GUI, which has a main-function that does some argparse stuff. The GUI interface is simplified from the CLI interface, so it's not that much work to write the argparse code for that. Simplified, it looks a little like this :

    @Gooey(default_size=(1000, 600))
    def main():
        parser = GooeyParser(description="jobGUI")
        # argparser code
        args = parser.parse_args()
        JobManager(args.name, args.whatever)
    if __name__ == '__main__':

Seems like you have update your API in two locations when changes happen, once in the `JobManager` definition and another time in the parser. How do you avoid issues with inconsistency?

Thanks for the info. Where does your code/Gooey/Fire live? If I wanted to take a Python script to use, where do I put it with this setup?

In our setup, we have a class that does the heavy lifting. The file where that class lives ends with :

    if __name__ == '__main__':
which turns it into an instant CLI.

Then we have a separate gui.py file, which contains the Gooey code. This includes the class mentioned above, and builds a minimalistic GUI around it. This does need some argparse-based code, but in the GUI we only expose a small subset of the full power, so we only need a little bit of argparse-code.

P.S. I'm not certain this is the best way to approach things, but it's the way we use it, and we're happy with it so far.

Does anything like Fire exist for JS?

Fire is great

I've used this to provide simple UIs to scripts for consulting projects where something more complex wasn't justified.

It mostly works great. If you have a complicated UI with multi-selects, validations and default selections, it probably isn't for you. But if you really just need a desktop UI for a script, it does what it says. You can make a UI in a few minutes.

There's also Wooey - a web-based take on the same idea if you need a Django web app to queue up and run your scripts. That implementation is a little more janky, but it also mostly works.

This is the weirdest thing but I get a sort of "uncanny valley" effect from all the screenshots, I try to parse them as Installshield Wizards but they're actually regular apps.

Ah! I’m not the only one. That also was my first thought.

They certainly look like NSIS installers.

So, it looks really cool, but it requires wxpython, which in turn seems to be an issue installing on Linux. Which, since I'm using Ubuntu 20.04 (not an exotic flavor of Linux) and python3, was surprising to me, but it appears to be a common issue (lots of blog posts saying lots of different ways to get around this). Might be useful to make some docs on how to install on the most common flavors of Linux? If this already exists, my apologies, I didn't see it.

Previous discussion 2014 (74 comments): https://news.ycombinator.com/item?id=8218785

Does anyone have any experience on how this couples with nuitka, pyinstaller, py2exe?

There's a section on pyinstaller in the github page, but my experience is that this domain (packing a Python application into an executable) is hard, dirty and inefficient all around, so I'd appreciate having the opinions of people who tried it beyond toy problems

I've been successful using PyInstaller to make executables out of PySide2 (Qt5) applications for Windows, Mac and Linux. (I probably should do a write up on that at some point). It's been quite a while since I touched Wxwidgets, but its packaging process should be similar and may result in smaller binaries if it's calling out to shared libraries (ie for the toolkit on Win).

If you could I'd appreciate it. I've been struggling with reducing the size of the resulting executable or dist

Is it Windows-only?

I can't seem to find an answer to this in the docs - only implicitly, in that they only show Windows screenshots.

It seems to use wxPython underneath, and that supports MacOS/Linux as well: https://www.wxpython.org/pages/downloads/

The Gooey docs do mention mac: https://github.com/chriskiehl/Gooey/blob/master/docs/packagi..., and there's some code in the repo written specifically for Linux, so I think it ought to work.

Yep, definitely works on Linux as well.

Not sure about mac, but it certainly should as well.

Author here. Linux, MacOS, and Windows all work A-OK! I'll update the readme to make that clearer.

Also: whoa, didn't expect to see my project on the front page of HN this morning! ^_^

I've been looking for something just like this. Thank you for making it :)

I love their 'Why Gooey'. It captures why I think GUIs are needed (in certain situations) and why I built https://nocommandline.com

I laughed at >>> Because as much as we love the command prompt, the rest of the world looks at it like an ugly relic from the early '80s. <<<

I built something similar to this (for internal use) around Go, except instead of a local program, it turns the command line program into a web app which then runs in the cloud. So now, if we need a new internal tool it’s just a few lines of console code, and bam, the devs can run it on the cli and pipe to/from it, and customer support or whoever can use it on a (still pretty ugly) web UI.

I didn’t use direct capture of stdout because it’s useful to have first class support in the web UI for other types of data, like tables, where you want sort/filter/save to csv. Colors are simple if you interpret those ascii control codes. I did some long polling with incremental data fetch so huge and/or long-running commands work efficiently. Works a treat. Totally worth the investment.

Fascinating. Would you be able to share it? If it isn’t open-source-able due to internal assumptions would you be able to share it with me?

Unfortunately, untangling it from internal assumptions and getting it ready for sharing would take too long (several hours I think), so it's not something I can do right now.

Next step would be to pitch the boss about the usefulness of open source as a recruiting tool, and get some time budget for this kind of stuff.

Very cool!

Reading https://github.com/chriskiehl/Gooey#how-does-it-work

One simply attaches a decorator to whichever function/method your argparse uses.

I have dozens of argparse based programs that could use Gooey.

This is super clever!! I love it.

I wonder if it could be extended for almost all command line applications by running "--help" and parsing the output. It's not quite as standardized as programmatic access to argparse but there aren't that many variations.

If anything, given how many of them link against gnu genopt I wouldn't be surprised if there's an excellent tool that could be made…

I try to limit the dependencies I bring in but these days I prefer to use click[1] instead of argparse, it's got more batteries included, specifically for me a more composable cli and an overall better experience around the parameters. I do miss being able to have default values for optional arguments, but only if the arg is actually supplied (e.g. -j for max parallelism, -j <n> to specify, nothing for no parallelism).

[1] https://palletsprojects.com/p/click/

Would this work to convert youtube-dl to a windows app so my dad can use it.

I wish people would stop linking MrS0m30n3's GUI. It's no longer maintained and other fork(s) are active. The one which so far retains the look is called yt-dlg now.

We have a big list of youtube-dl GUI's over on /r/youtubedl's wiki: https://www.reddit.com/r/youtubedl/wiki/info-guis

Do any of those use this Gooey framework?

Great, thanks!

This brings me back to the late 90's when folks were writing Tcl/Tk (or whatever/Tk) wrappers for seemingly every CLI.

That was silly, but this makes sense for 1-offs. You write an internal CLI, realize the userbase isn't technical enough for it, and strap a GUI to it.

I've hit that plenty with things I made for an ops team that eventually got shifted to more BA/PM-types. I've usually turned them into a web-app, but it's a lot of lifting and a "thick client" approach would be nice.

I am spoiled, though, with Click, and don't ever want to go back to argparse, though. I'll keep an eye on it, though.

I wonder if something like this could turn a CLI tool into a webapp, maybe via wasm?

Just quoting a sibling comment (https://news.ycombinator.com/item?id=27500704):

>There's also Wooey - a web-based take on the same idea if you need a Django web app to queue up and run your scripts. That implementation is a little more janky, but it also mostly works.

Looks like Zenity/Xdialog for Python apps - these solutions work great within designed limits, and if your app is non-trivial you'll hit these limits sooner or later.

heh this makes me think an optparse-gui for Haskell would be both trivial to write and useful

This is for Python, but I see much more potential for implementing this in Raku which has built-in support for strongly-typed command-line syntax defined as the signature of the MAIN function.


See also GNU dialog, Zenity and KDialog.

Not the same.

The point Gooey is to use the definition of the arguments (which we could call the program command-line grammar) to automatically build an UI.

But I see much more potential for the Raku world where there is built-in syntax for declaring arguments with strong typing. https://docs.raku.org/language/create-cli#sub_MAIN

But I'm thinking about something similar for any program that provides shell completion scripts: it would have to parse the shell completion definition to build the UI.

I know it is not the same, and never claimed it was.

The utilities I mentioned let you create UIs for shell scripts with ease.

I've been obsessed with the mapping cli / gui for .. ever.

I'm not even jealous.. kudos

Is there something similar for config files instead of command line parameters?

You can check out ConfigArgParse[0]. It allows you to use command line arguments, environment variables and config files to control the behavior of your scripts. I'm not sure if you can use it with gooey or not.

[0] https://github.com/bw2/ConfigArgParse

Is it only compatible with Windows? i can’t see any examples on other platforms

It's cross-platform. I've developed gooey-interfaces on my macbook that later ran on a windows machine.

Looks like it's using WxWidgets so it should be cross platform

You could use this to turn just about any command line program into a GUI app since it's already pretty easy to make a python wrapper around another command line program. Nice.

I wonder if this + dependencies could be bundled into a golang binary with the new embed feature, then python could exec the bin or vice versa. I guess zenity would be better for that

This is cool as hell! I have had quite a few situations where I wanted to automate someone else's workflow, but asking them to open terminal was probably too much of an ask.

What's the web equivalent of this that's commonly used?

Zenity or yad

Very Cool! Going to play around with this. A great way to make quick visual text games with my kids instead of via CLI which can be intimidating.

I wonder if it is possible to take a subset of GUI apps including websites and turn them into CLI tools in a similar way?

Brilliant, thanks for sharing this! I'd love to know where it doesn't work.

I have hard time thinking of a real use case of this but ... it's really clever.

I'm very much a command line guy but ffmpeg still stumps me. Might be nice if it could save the various ffmpeg arg soups as some kind of friendly name, e.g. "combine jpegs into a timelapse" or "convert video to HTML5-friendly format" and then just drop-down and fill in the timelapse parameters or whatever.

If you want to see an example of that exact thing, I've got a small suite of wrapped FFMPEG tools doing exactly that via Gooey. Having things like screen recording, gif creation, trimming/truncating in a GUI just makes them way more convenient for my frail brain compared to FFMPEG's tough APIs.


FFmpeg was the first example I thought of too, but I don't think that there is a screen large enough to display all it's options and flags.

I just have a folder with a bunch of scripts with various descriptive names which launch ffmpeg with different painstakingly composed argument chains. I could join them into a mega-script which would prompt me upon execution but I don't see the point in an additional indirection.

Sometimes one script is just not enough/not convenient enough, and I write simple helper wrappers such as:

- https://indiscipline.github.io/post/movie-thumbnailer-announ...

- https://indiscipline.github.io/post/ffmpeg-loudnorm-helper-a...

Plenty of options, one I haven’t seen mentioned is Shutter Encoder. I don’t think it covers all of ffmpeg functionality, it focuses on format conversions useful for video professionals and does a fine job of it.


Handbrake is great for transcoding! Not sure if it can do the more esoteric tasks.

I don't use it myself, but maybe have a look at Staxrip? It's not quite that user friendly, but a lot more than remembering the commands for making a video from individual images.

I also like to use the command line, but I hate that flags are inconsistent, case sensitive (with unrelated meaning) and not good discoverable

I personally have no desire to use it outside of Windows, but Powershell fixes all there things if you're so inclined:

> flags are inconsistent

At least among the core command set, there is a set of "core flags" like -ErrorAction or -Verbose that are consistent. Though I don't know how often you'll find them in third-party commands.

> case sensitive

There's a preferred case that you'll get if you tab complete, but -Verbose is -VERBOSE is -VERBOSE.

> not good discoverable

Tab completion works for flags everywhere and each of them should be included in Get-Help regardless of if the author documents them.

Not everybody feels native to the terminal, so this could ease the use for non-tech-savvy users

If you made a nice script and people pester you for a GUI now, this looks like a nice low-effort way to satisfy them.

Really!? Try teaching your parents to use a command line.

My parents taught me how to use the command line.

Try teaching 10 randomly sampled parents how to use a command line?

10 randomly sampled adults, nevermind parents. My partner is an educated person who works on a computer all day and I think she would have a panic attack if I asked her to do something on a command prompt

I've been using CLIs for many years and I'd still rather use a (well-designed) GUI most of the time.

You're very young and the exception pal.

What are the tools my "non command line fluent parents" could/would want to use that don't already have a human crafted GUI ? This lib, as smart as I think it is, doesn't create "simplicity" from a void.

Never in the last two decades did I encountered a "parents" usage where any CLI tool were needed to do some work. Yes it did happen that I had to use them to repair things. But having auto-generated GUIs on these tools wouldn't change anything about the lack of understanding of what it is, why it's needed and what it does.

If we are talking about generating GUIs for complex production tools like ffmpeg, tar, git ... there already are plenty of wonderful and less wonderful frontends that a auto generated GUI could never beat.

But I'm not saying this tool is not nice. Just I think it's targeted at power users that don't want to open a terminal. It's not a lot, but it's something.

The way I would use it is for porting scripts used in a work environment to a GUI so my non-programmer coworkers can use them too.

> GUIs for complex production tools like ffmpeg, tar, git ... there already are plenty of wonderful and less wonderful frontends that a auto generated GUI could never beat.

My 12 year old is doing a fair bit of video work, and I just pointed him at Handbrake to get his submission file size down. It's an amazing bit of software, apart from that malware issue back in 2017...

I've been in a situation where I needed to share a configurable Python script with a non-technical person. This would've made that much easier.

That's a really cool use case I haven't anticipated :)

How about a tool like catt (cast all the things)?

catt lets you Chromecast direct from your local machine, which could be of interest to non-techies, but catt only ships with a command-line interface. (Although I believe an unofficial GUI exists that doesn't use Gooey.)

This is really cool, I'm going to try it on a few of my own cli programs.

Is anyone aware of a similar tool for JavaScript/TS or Golang?

You can actually use Gooey for any arbitrary program or language (if you don't mind configuring a few of your cli arguments in python). Gooey technically just uses Json behind the scenes, but Python remains the most first class way to generate that blob of json.

I wrote a brief guide awhile ago here[0]. For instance, all the screen shots and screen recordings throughout the README are done with a custom wrapper I made with Gooey which just acts as a pretty 'front end' for FFMPEG[0]

[0] https://chriskiehl.com/article/gooey-as-a-universal-frontend [1] https://github.com/chriskiehl/GooeyVideo

Saddly the opposite is much more complicated.

Awesome README.

Does it work with click?

I don't think so. It's based on argparse, while Click uses optparse.

Gooey works with Fire, though.

Does it? I haven't been able to get it to work correctly with Fire.

    def main():

    def hello(name="World"):
        return "Hello %s!" % name

    if __name__ == "__main__":
It just runs Fire instead of launching Gooey. I've tried quite a few other things re: getting Fire to work with Gooey but nothing seems to have an effect

The other way would be amazing. Making any gui to be command line

> Turn almost any Python command line program into a GUI application

Why would anybody need this? Xterm is already a GUI application and you can run the original program inside it. What benefit is there?

What I'd like is the inverse operation: turn an arbitrary GUI application into a command line program. Now, that would be really useful! That would allow a lot of automation that is difficult with GUI stuff. It seems a really, really hard problem though.

As you can see, it makes the program self-discoverable.

Instead of having to go back and forth between the --help output or a man page and the command you're typing, you can just read as you go.

This is great for non-trivial tools used occasionally by people who don't live in the terminal (aka most users).

Because 99% of the world's population doesn't know how to operate a terminal?

> Why would anybody need this?

Because they have no experience using a terminal, entering commands and finding documentation

"Why would anybody need this?"

For example to provide quick tools for non-professional users.

Single button automation for scripts that need to be run intermittently and are poor candidates for timed execution.

I am quite proficient at command line, but still prefer a single button that "does that one thing I need".

There are whole sections of the README directly answering your question (e.g. who is this for)

Yes, I read this, and it is essentially an aesthetic, UX issue. But it does not allow you to do things any easier in practice (at least if you are used to the command line). I was just asking it semi-rhetorically to introduce my question about the inverse transformation.

A command-line interface to clicking buttons on a headless GUI, by naming their labels, would be an extremely useful tool. Even if only worked for applications written with the major toolkits gtk, qt, electron etc.

EDIT: imagine that you could do this:

    ungooey gimp --menu file:open:lena.png --click eraser --drag "10,10-100,200" --menu file:saveas:lena2.png
and it created an image with a white diagonal band erased in white.

You can do that semi-easily on most linux apps using GTK, Qt with AT-SPI: https://delysid.org/gspi.html

most likely both Windows and macOS would have similar mechanisms for accessing their respective accessibility api

It looks like you want a CLI-ified AppleScript.


Applications are open for YC Winter 2022

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact