Hey, what the -- this is my thing. ^_^ What's it doing at the top of HN?
A quick reply to some of the comments about argparse. Gooey is super old at this point. Argparse was a solid choice at the time when Gooey started. These days, Gooey itself speaks in JSON and is decoupled from argparse itself. However, argparse remains the main "blessed" interface (mostly because nobody else has built a different one).
Some fun FYIs: You can also invoke any arbitrary executable[0], not just python, which is pretty handy.
Re: last commit being 2 years ago. It gets harder to justify working for free on niche software as you get older and priorities change :( If it's any consolation, I DO feel guilty all the time. I have no idea why, but where I live, there's "GOOEY" graffiti tagged all over the place, so it's a nice ever-present reminder of the issue tracker that's currently going unloved. haha.
Argparse is still a pretty solid choice, because it's so ubiquitous and well documented and fairly easy. Typer and Click are both very nice, with some good ergonomics, but I find Typer's "tutorial" style documentation to be rather hard to search to find answers to things like "What arguments does Typer.App() take?"
I have a program I'm working on right now that does user-initiated argument parsing, and argparse is a great fit for it. I'd love to have a text-based UI as an option to drop users into, but Textualize requires Click (IIRC), and using Textual directly in my code to create the UI I've spent hours on and had absolutely no luck even getting started.
That right there is the real winner. I already get queasy when my dependency list gets too long. Invoking an extra collection for what is mostly developer quality of life is not a trade-off I like to make.
While Typer looks nice, I found it to be annoying. It outputs everything depending on the width of your terminal emulator with spaces instead of newlines. Not sure who thought that was a good idea, but try copy pasting any output of it in any chat or anywhere that is not the same width in chars as your terminal emulator. The output becomes complete shit and unreadable. The second thing is, that it forces you to adhere to its paradigm of being a global mutable state object, instrad of being passed around neatly like argsparse, which makes code less understandable and tests needlessly more complicated.
Overall I have found it to be very much not worth it adding typer as a dependency. Hard pass.
On the other hand, I've switched to using Typer for most of my argument parsing because it's not an object I have to pass around. It lets me have the arguments co-located with the code, which is convenient. Especially for more complicated argument parsing, like one of my commands for our deploy process which has maybe 15 sub-commands, that sort of parsing with argparse is kind of a nightmare.
The solution to this kind of issue is something like parameters (See for example https://www.gnu.org/software/guile/manual/html_node/Paramete...). They are also thread safe. One can easily set them in tests without having to mock things. I am not sure it is possible to even have something like this in Python. Have not seen it anywhere in Python.
> Passing arguments to functions is thread-safe, but that soon becomes tedious when there’s more than a few or when they need to pass down through several layers of calls before reaching the point they should affect. Introducing a new setting to existing code is often easier with a parameter object than adding arguments.
But also, if you really wanted to, you could set the argsparse object to a global variable and then import it everywhere else. So that is not a limitation.
My issue with argparse isn't that it's not global, it's that you have to create sub-parsers for multiple commands, and then add arguments to those subparsers. Those parsers are all typically defined in a central location, but copying arguments between those parsers as I define new commands can get them jumbled up because the sub-parser comes along with the argument:
If I copy "sub1.add_argument" and put it under "sub2", and forget to change "sub1" to "sub2", it is a hard to track down bug. I've had this happen a lot as the parser gets more complex.
Typer completely eliminates this potential bug, because the arguments are defined as type annotations in the sub-command function itself.
This is a really cool idea. I love interface disconnected from APIs. We have so many annoyances these days because applications can't be programmatically controlled. Honestly, I'd like to see legislation saying all application functionality needs to have APIs.
I think legislation demanding most tools have an API would be a good thing. Not 'tho shalt expose a REST endpoint'. But instead something like 'every operation a user can do with this tool, they also need to be able to trigger with an interface that is programable, and that interface needs to be documented'.
Saying 'our programable interface is the gui, use autohotkey' is fine, as long as you properly document all click regions.
This would be a massive productivity boost to anyone using such tools. It would also be great for disabled people.
I would not like to have to concern myself with exposing government-compliant APIs when coding any arbitrary tool...the free market can reward good development.
No way, especially because all the people taking most market-business-related decisions (eg which software to buy) are not tech-oriented. If we had more power on these decisions, that would mean that development, and even advertising of products, would be closer to what the parent comment suggest. But alas.
Markets cannot regulate nuanced behavior like this. Microsoft is a trivial example of anti-user practices and generally garbage design nonetheless being adopted due to their tremendous efforts of corporate propaganda and scaremongering the decision makers about their products.
This is true, but the abuse would still be possible today if someone is reverse engineering software or talking to servers where everything is over APIs anyway. I'm talking about local interface decoupled with a local API from implementation. The problem today is that programmers can't compose or build software on top of other software they have.
> I'm talking about local interface decoupled with a local API from implementation.
To expose this "local API" usefully, you must either:
1. Share memory with other processes (new attack vector), or
2. Listen on some kind of network or native socket for messages and authn+authz the commands that come through it based on some security protocol (new attack vector).
The value proposition of an API is to allow control and data flow between an application and some external entity. It seems to me that it has security implications by definition.
Hey! Cool project! I have a question: why do you dump out sys.argv to a local file in the CWD? [0] tmp.txt is hardly a unique name… or am I missing something?
Seems like it's potentially used for debugging, especially given that pycharm apparently appends additional params when invoking a new process (as noted in the comment at the top of the file).
> These days, Gooey itself speaks in JSON and is decoupled from argparse itself.
This sounds cool. I saw the headline and before clicking anything, my first thought was "bet this heavily depends on argparse", so this is surprising - in a very nice way.
I'm a hardcore getopt fan, mostly because I believe the developer's convenience is nowhere as important as the convenience of the user, and the user shouldn't need to care what programming language or option parsing library the developer chose. argparse, Click, Go's flag/X11-style, and many other similar libraries break conventions that are ingrained in half a century's collective muscle memory.
But with a layer in the middle, it sounds like you can eat your cake and have it too.
It's only super old because you abandoned it (and I don't mean to be judgemental, it is what it is). Worse yet, no viable alternative has shown up to replace it nor either of its forks gained traction.
No its super old cause it was created a long time ago? Why dont you go update it or make a free up to date version? Why do people act like software creators owe the world something?
Shouldn't this be qualified with "argparse-based"?
Argparse is good for simple stuff but there are many Click based CLI's and a lot of popular CLI libraries build on top of Click. There are also other Python CLI tools that aren't built on argparse or Click, though I will say that these two are probably the most popular ones.
Is this confirmed to work with Click? I only see references to argparse. I would go so far to say, if the answer is no, that "almost any" is a flat out lie, and a much more accurate title would be "Turn almost any argparse-based Python command line program into a full GUI application".
Also, the last substantial commit was over two years ago. This isn't itself a bad thing, but given the open issue count does not really signal confidence in the project.
Otherwise it is a cool project. I would like to see more of this - it's one of those neat force multipliers, as referenced in the README, that some enterprising person could implement as a CLI and then share their automation for the rest of the nontechnical office in an easy way. Kind of like how Access did the same thing for DB's. Like Access, you would butt up against limitations once you started to introduce some level of size or complexity, but it could be "good enough" for a lot of small office use cases.
I was genuinely seeking feedback. I use argparse regularly. I have found it somewhat difficult to use when creating nested subparsers. That Click is part of the The Pallets Project gives me more confidence in it being maintained indefinitely, but ...
I used it for exactly this in my previous role. I automated a lot of tasks and built tools for my previous team. Most of them weren't Python programmers so I used gooey to create simple GUI's on top of my scripts. It worked really well.
We've banned this account for breaking the site guidelines frequently and ignoring our requests to stop.
If you don't want to be banned, you're welcome to email hn@ycombinator.com and give us reason to believe that you'll follow the rules in the future. They're here: https://news.ycombinator.com/newsguidelines.html.
The author’s comment actually confirms that it doesn’t currently support anything else other than argparse though. The author says they wrote it to be generic enough to extend to other libraries easily, which is great, but that is not the same at all as currently supporting said libraries. They provided a link that said it supports any cli, but when you follow the link, the instructions tell you to implement an argparse compatible wrapper for your cli in Python, which of course, is supporting argparse
I know we are in semantics land now but most people would probably say that shelling out to another process doesn’t really constitute an integration. Put another way, you could just say that you could easily turn any CLI into a simple Python CLI with only a few lines of code with argparse itself, and that argparse supports any other CLI by just wrapping it, removing mentioning the Gooey part entirely. You’re essentially describing just the benefits and drawbacks of Python’s subprocess and argparse libraries at this point and not really saying anything about Gooey aside from the fact that it is argparse compatible.
In other words: “Hey look at this cool thing argparse can do, and because Gooey is basically api compatible with argparse, it can do it too!” And don’t get me wrong, I think Python’s expressiveness with the argparse library and in general its ability to make CLI’s in very few lines of code is great. But really the magic is argparse and Python in that regard.
> I know we are in semantics land now but most people would probably say that shelling out to another process doesn’t really constitute an integration.
Most people would be an exaggeration. Purists may think that, but the reality is most GUI wrappers use subprocessing.
While I agree that click integration would be nice, how would you turn any CLI tool to a GUI application without shelling out?
> But really the magic is argparse and Python in that regard.
True, but this is simply semantics. If I submit a PR to the Gooey project that lets you write a YAML configuration file to declaratively document the interface of a CLI tool, then automatically convert that config file to Python source, would that be any different? Is it because it's YAML you manually write and not Python? Or even something that uses ChatGPT to convert a man page to an argparse wrapper? The argparse is the trivial part. The real magic is Gooey.
I wish that the OS and shell had better insight on how to run programs without need for specific library parsing libraries.
I'd love to see programs communicate through a typed JSON/proto format that shed enough details to make this more independent, and get useful shell command structuring/completion or full blown GUIs from simply introspecting the expected input and output types.
Today it seems that the best you can get is still made out of carefully placed straws as programs need to export completion files to many shells, there's vastly different styles for flags across programs and parsing libraries, and obviously, there's no GUIs around.
Kind of like some generic gRPC interchange/CLI API with native OS support? Something like that could be neat. I conjecture the main problem with gRPC is that a lot of developers (myself included) find dealing with it a bit unwieldy compared to more native (by native I mean in-language) solutions.
If you look into IPC primitives in each OS you can find goodies that do expose structured metadata about what interfaces are available and how they can be called. D-Bus, sd-bus, COM, Binder, to name a few.
It’s just that the tooling around it isn’t as easily exposed and they aren’t tailored for on-demand launch via command line. If the shell treated such as a more first class citizen, good results may come out.
Another big problem is portability, if you designed your app with sdbus, it’s not going to work on a non systemd distro, even less on Windows. What’s needed is a standardized abstraction layer on top.
> I'd love to see programs communicate through a typed JSON/proto format that shed enough details to make this more independent, and get useful shell command structuring/completion or full blown GUIs from simply introspecting the expected input and output types.
You should try PowerShell. It's basically Microsoft's .NET ecosystem molded into an interactive command line. I'm not entirely sure if PoweShell can make full use of the static types that build up its core, but its ability to exchange objects in the command line is almost unmatched.
PowerShell is available on macOS and Linux as well (source on Github: https://github.com/PowerShell/PowerShell). It may not be as well-integrated with things like system services management, but the language still works well. You can still use all the command line tools you're used to on Linux, of course.
nushell does look interesting, though the lack of a .deb repository does put it pretty low on my to-do list.
I sometimes find GUIs equivalent to comfort-food as you can just stroll through a gui interface without lot of cognitive overload that may come from a rarely used CLI.
A bit tangential to current discussion, but i came across CUDATEXT editor a few months ago here which provides a single file python API to let me use arbitrary GUI elements like MENU, INPUTS etc which editor is itself using.
I currently generate my blog from editor itself with configuration done through these simple GUI elements.
"Textual: lean application framework for Python. Build sophisticated user interfaces with a simple Python API. Run your apps in the terminal and a web browser." [1]
Hey, I just want to say thanks for making this wonderful piece of software! I love gooey and have used it extensively for several different programs. For me, it perfectly fits this area where you have a python script that does something important, and now you need to set it up so that non-programmers can use it as well.
This reminds me naked objects. The idea was that you only define Java classes with some annotations + theme and the whole GUI (or web frontend) application will be generated for you.
Very cool idea but it never worked out (to my knowledge).
Django has a similar philosophy: define your models and they are reflected directly into database tables and you can auto-generate forms using them.
IMO, the trouble is that it couples vertical concerns (presentation, domain, infrastructure). It's fine as long as the domain model has trivial presentational and database representations.
However, if you want to make a complex interface with many convenience features, you'll have to let those requirements bleed into your domain layer; and if want to create complex domain models, it's impractical to enforce invariants at the language level (since anything with a reference to a Model can do arbitrary things to it).
I would like to be able to use a gui to set up parameter sweeps based on info pulled from argparse and then convert back to a shell script that runs and saves the output sensibly.
A WYSIWYG editor that spits out a CLI you mean? That would pretty neat, though I think would necessarily be kind of constrained. I wonder who has tried that approach, I can't think of any examples
Actually, something like a "zotero for argparse" would be cool. Where you enter arguments, their type, help string, defaults etc in a gui and then you can check the ones you need for a given python script and copy the relevant python code into your paste buffer.
I don't think it would be a massive time saver however what I usually do now is find some previous script that had similar arguments and copy them, and then copy-paste-edit to add new arguments.
The other advantage is you could enter the arguments agnostically and export as whatever language you're working in.
how? you're going to modify the binary so that it can accept command line parameters? or clone the GUI's functionality in a CLI? that's akin to just creating the application from scratch.
With the old Macintosh Programmer's Workshop (MPW; a text-based shell for Mac OS of the 80s and 90s) there was similar functionality called Commando for almost every command. The commando information was kept in a 'cmdo' resource. Something similar could be done today with extended attributes, if support wasn't so hit or miss.
Oh, apparently, A/UX had commando as well. If you double-clicked a terminal command from the Finder, it would pop up the commando box to choose your CLI options, then run it in a shell window. Today, running a terminal command from Finder just runs it without any arguments in a shell window.
Wow, what a nice coincidence to see this on HN! Just two days ago, I was hacking up a similar project. https://github.com/livetheoogway/python-uime
This one is a much smaller hack to spruce up your local scripts. Although it's still a work in progress with features pending, I'd really appreciate any initial feedback or thoughts. Thanks for checking it out!
How would one integrate this with a CLI tool that expects some user input during execution?
Would love to package this around a bisect script I use to debug issues for my game engine. Giving it a GUI would make it possible to share it with users such that they too can help bisect problems.
Anything that can be handled by a compiler can be hacked to interface with anything that can be handled by an interpreter. That’s the kind of fundamental daoist “code is data is code” that underlies the power of computing.
Did something similar with my pokemon emerald randomizer. This parses output of wasm/wasi program's --help output and generates a web interface https://cloudef.github.io/pokeemerald-randomizer/ the aruments are then passed to the wasi/wasm binary to generate the final rom.
I wonder if Gooey could be made to target generating a React or even JS-free vanilla web app, instead of a native GUI?
In spirit, Gooey reminds me of one of my favorite low-code tools for technically savvy individuals to put a web frontend in front of arbitrary CLI programs:
Launching it only on demand is an interesting idea, and I totally get your sentiment on bloat. I was a 90s teen, 32MB of ram was enough for just about everything at the time, while today that's "embedded" territory, haha. Still, these days my web browser is generally already open.
Anyhow, maybe my writing could have been more clear. I was thinking of it differently, running the app as a persistent webserver. Then I could access the things from anywhere. "Accessible from any web browser" is one of the primary properties I like about the Python Script Server (mentioned/linked in my first post).
Just imagine if someone somehow figured out how to make a Gooey equivalent for Go or Rust. If done well, it could become very popular. Especially considering the difficulty of creating UIs in those languages! Much more challenging than Python.
Ok, a webserver I could get behind, yes. It’s everything being made into Electron apps that bothers me. Spotify takes up well over 1 GiB of RAM, and for what?
When it's launching a new tab in an existing browser it's rather less overhead, and also tends to be convenient in a way nothing I've dealt with other than Tcl/Tk is.
(notably Tcl/Tk deals with remote X over ssh nicely and far too many things these days don't so much)
And then there is me who tries to fight with all my clients to have their GUI friendly applications to, at least, have command parameters, so that it can be automated through services/task scheduler/cron
Cool! I've wanted to write something similar to turn a python cli into a web app, something like those sites that convert file types but general purpose.
"Almost any Python command line program" seems to be an exaggeration. It relies on the command-line program using argparse, and explicitly doesn't work for any that rely on optparse, which, sure, is older, but also means that things which rely on the popular Click command-line library won't work either.
Which is arguably a good reason Click should look for an alternative basis (though, OTOH, the reasons Click remains on optparse are, arguably, a reason that optparse, while it perhaps should not be further developed but for bug fixes, should not be considered deprecated), but in fact a lot of Python command-line programs depend on Click, so something that only works on argparse-based programs does not, in fact, support "almost any Python command line program".
A quick reply to some of the comments about argparse. Gooey is super old at this point. Argparse was a solid choice at the time when Gooey started. These days, Gooey itself speaks in JSON and is decoupled from argparse itself. However, argparse remains the main "blessed" interface (mostly because nobody else has built a different one).
Some fun FYIs: You can also invoke any arbitrary executable[0], not just python, which is pretty handy.
Re: last commit being 2 years ago. It gets harder to justify working for free on niche software as you get older and priorities change :( If it's any consolation, I DO feel guilty all the time. I have no idea why, but where I live, there's "GOOEY" graffiti tagged all over the place, so it's a nice ever-present reminder of the issue tracker that's currently going unloved. haha.
[0] https://chriskiehl.com/article/gooey-as-a-universal-frontend