Overview
Via the run function you get access to the CLI, possibly enriched from the config file. Then, you receive all data as m.env
object and dialog methods in a proper UI.
graph LR
subgraph mininterface
run --> GUI
run --> TUI
run --> WebUI
run --> env
CLI --> run
id1[config file] --> CLI
end
program --> run
Basic usage
Use a common dataclass, an argparse ArgumentParser
, a Pydantic BaseModel or an attrs model to store the configuration. Wrap it to the run function that returns an interface m
. Access the configuration via m.env
or use it to prompt the user with methods like m.confirm("Is that alright?")
.
There are a lot of supported types you can use, not only scalars and well-known objects (Path
, datetime
), but also functions, iterables (like list[Path]
) and union types (like int | None
). To do even more advanced things, stick the value to a powerful Tag
or its subclasses. Ex. for a validation only, use its Validation alias
.
At last, use Facet
to tackle the interface from the back-end (m
) or the front-end (Tag
) side.
IDE suggestions
The immediate benefit is the type suggestions provided by your IDE.
Dataclass showcase
Imagine following code:
from dataclasses import dataclass
from mininterface import run
@dataclass
class Env:
my_paths: list[Path]
""" The user is forced to input Paths. """
@dataclass
class Dialog:
my_number: int = 2
""" A number """
Now, accessing the main env will trigger the hint.
Calling the form with an empty parameter will trigger editing the main env
Putting there a dict will return the dict too.
Putting there a dataclass type causes it to be resolved.
Should you have a resolved dataclass instance, put it there.
As you see, its attributes are hinted alongside their description.
Should the dataclass cannot be easily investigated by the IDE (i.e. a required field), just annotate the output.
Select showcase
We push an intuitive type inference everywhere. Here is an example with the m.select
dialog.
from mininterface import run
m = run()
# x = m.select([1, 2, 3], default=2) # -> int
# x = m.select([1, 2, 3], multiple=True) # -> list[int]
# x = m.select([1, 2, 3], default=[2]) # -> list[int]
By default, the inferred type is an int
.
When you flag the selection as multiple or when you submit multiple default values...
that means your IDE sees a list
instead of a single value and you can automatically append to it etc.
Nested configuration
You can easily nest the configuration. (See also Tyro Hierarchical Configs.)
Just put another dataclass inside the config file:
@dataclass
class FurtherConfig:
token: str
host: str = "example.org"
@dataclass
class Env:
further: FurtherConfig
...
m = run(Env)
print(m.env.further.host) # example.org
The attributes can by defaulted by CLI:
And in a YAML config file. Note that you are not obliged to define all the attributes, a subset will do.
(Ex. you do not need to specify token
too.)
Bash completion
Run your program with a bundled mininterface
executable to start a tutorial that will install bash completion.
$ mininterface integrate ./program
System dialog toolkit
Mininterface can be used as a standalone dialog layer for sh scripts. See mininterface --help
.