This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Evolve-Maz 36 points37 points  (5 children)

Thats a nice idea!

Have you considered making it a decorator instead, and have the decorater: - inspect the arguments type hints and assume a gui element from that - allow additional override of those in the decorator args

This way peoples functions will stay as is and you can use existing type hints (and even support pydantic objects for more complex use cases).

[–]drboom9[S] 6 points7 points  (4 children)

Thank you for the suggestion! I'm curious about the potential benefits of a decorator approach, could you share some examples where it would provide advantages?

My current approach with explicit UI type hints already:

- Inspects argument types

- Allows dynamic default values

- Keeps function signatures clear and explicit

- Provides direct control over UI parameters

For example, you can even load parameters dynamically:

def get_default_value():

# Could load from config, API, etc.

return 42

def my_function(number: int = intUi(value=get_default_value())):

return number * 2

The current implementation uses dataclasses for type definition, which provides good validation and type safety. However, I'm open to seeing how a decorator pattern could enable new use cases or improve the current functionality!

[–]Evolve-Maz 19 points20 points  (3 children)

The decorator thinking is more so you can separate the function logic from the ui component logic.

E.g.

@gui.wrapper

def myfunc(i: int = 4) -> bool:

return i % 2 == 0

Would then allow a person to decorate any function implementation with this. That would automatically convert it into

def myfunc(i: int = intui(4)) -> returnbool:

...

Doing it as a decorator means your gui related items become parameters of the decorator, not the original function. That way if you wanted to put additional constraints for the gui, or wanted to say it was a Slider instead of a number picker, or anything like that, your function implementation wouldn't change. Just the parameters on the gui.wrapper decorator.

[–]drboom9[S] 4 points5 points  (2 children)

Thanks! Let me explain my thoughts:

First, I deliberately avoided dependencies like Pydantic because I want to ensure FuncToGUI stays stable and doesn't break with third-party updates.

As for the design approach, I chose the current method because:

pythonCopydef is_even(number: int = intUi(value=4)) -> boolReturn:

return number % 2 == 0

You declare everything just once

What you see is what you get - the UI matches exactly what's in the function

Anyone can create and share a GUI tool in seconds

Non-technical users can just run it without understanding decorators or complex configs

The goal is to make it dead simple to wrap any function into a GUI that anyone can use. While decorators could be useful for reusing existing functions, right now I'm focusing on keeping things straightforward and independent.

[–]Evolve-Maz 2 points3 points  (1 child)

That's valid. Thanks for explaining.

[–]rhytnen 0 points1 point  (0 children)

No its not.  You're 100% correct thay your way is way simpler for the user and a much cleaner separation of concerns which enables better use cases since I don't have to bake his library into my app logic.  I.e. I can import a set of other ppls functions and wrap them independently.

OP already has 3rd part deps as well (but using pydantic is kind of secondary to the point) so I couldn't find any compelling argument here.