Skip to content

Mininterface

mininterface.Mininterface

The base interface. You get one through mininterface.run which fills CLI arguments and config file to mininterface.env or you can create one directly (without benefiting from the CLI parsing).

Raise

Cancelled: A SystemExit based exception noting that the program exits without a traceback, ex. if user hits the escape.

Raise

InterfaceNotAvailable: Interface failed to init, ex. display not available in GUI. You don't have to check for it when invoking an interface through safe methods run or get_interface.

facet: Facet

Access to the UI facet from the back-end side. (Read Tag.facet to access from the front-end side.)

from mininterface import run
with run(title='My window title') as m:
    m.facet.set_title("My form title")
    m.form({"My form": 1})

Facet back-end

env: EnvClass | SimpleNamespace = EnvInstance

Parsed arguments from the EnvClass. Contains whole configuration (previously fetched from CLI and config file).

$ program.py --number 10
from dataclasses import dataclass
from mininterface import run

@dataclass
class Env:
    number: int = 3
    text: str = ""

m = run(Env)
print(m.env.number)  # 10

__enter__()

Usage within the with statement makes the program to attempt for the following benefits:

Continual window

Do not vanish between dialogs (the GUI window stays the same)

Stdout redirection

Redirects the stdout to a text area instead of a terminal.

from mininterface import run

with run() as m:
    print("This is a printed text")
    m.alert("Alert text")

With statement print redirect

Make the session interactive

If run from an interactive terminal or if a GUI is used, nothing special happens.

# $ ./program.py
with run() as m:
    m.ask("What number", int)

Asking number

However, when run in a non-interactive session with TUI (ex. no display), TextInterface is used which is able to turn it into an interactive one.

piped_in = int(sys.stdin.read())

with run(interface="tui") as m:
    result = m.ask("What number", int) + piped_in
print(result)
$ echo 2 | ./program.py
What number: 3
5

If the with statement is not used, the result is the same as if an interactive session is not available, like in a cron job. In that case, plain Mininterface is used.

piped_in = int(sys.stdin.read())

m = run(interface="tui")
result = m.ask("What number", int) + piped_in
print(result)
echo 2 | ./program.py
Asking: What number
3

alert(text)

Prompt the user to confirm the text.

ask(text, annotation=str, validation=None)

Prompt the user to input a value – text, number, ...

By default, it resembles the input() built-in.

m = run()  # receives a Mininterface object
m.ask("What's your name?")  # -> str

You may specify the type:

m = run()  # receives a Mininterface object
m.ask("What's your age?", int)

Ask number dialog

The type might be complex. This enforces a list of paths.

from mininterface import run
from pathlib import Path

m = run()
m.ask("Enlist input files", list[Path])

Also, you can further specify the value with a Tag. This enforces an existing file:

from mininterface import run
from mininterface.tag import PathTag

m = run()
m.ask("Give me input file", PathTag(is_file=True))

Parameters:

Name Type Description Default
text str

The question text.

required
annotation Type[TagValue] | Tag[TagValue]

The return type.

from datetime import time
from mininterface import run

m = run()
m.ask("Give me a time", time)

str
validation Iterable[ValidationCallback] | ValidationCallback | None

Limit the value.

from annotated_types import Gt
from mininterface import run

m = run()
m.ask("Give me a positive number", int, Gt(0))

None

Returns:

Type Description
TagValue

The type from the annotation. By default str but might be int, datetime...

confirm(text, default=True)

Display confirm box and returns bool.

m = run()
print(m.confirm("Is that alright?"))  # True/False

Is yes window

Parameters:

Name Type Description Default
text str

Displayed text.

required
default bool

Focus the button with this value.

True

Returns:

Name Type Description
bool bool

Whether the user has chosen the Yes button.

select(options, title='', default=None, tips=None, multiple=None, skippable=True, launch=True)

Prompt the user to select. Useful for a menu creation.

Parameters:

Name Type Description Default
options OptionsType[TagValue]

You can denote the options in many ways. Either put options in an iterable, or to a dict with keys as labels. You can also use tuples for keys to get a table-like formatting. Use the Enums or nested Tags... See the OptionsType for more details.

required
title str

Form title

''
default TagValue | OptionsType[TagValue] | None

The value of the checked choice.

m.select({"one": 1, "two": 2}, default=2)  # returns 2
Default choice

If the list is given, this implies multiple choice.

None
tips OptionsType[TagValue] | None

Options to be highlighted. Use the list of choice values to denote which one the user might prefer.

None
multiple Optional[bool]

If True, the user can choose multiple values and we return a list.

None
skippable bool

If there is a single option, choose it directly, without a dialog.

True
launch bool

If the chosen value is a callback, we directly call it and return its return value.

def do_cmd1():
    return "cmd1"

def do_cmd2():
    return "cmd2"

m = run()
out = m.select({"Open file...": do_cmd1, "Apply filter...": do_cmd2})
print(out)  # 'cmd1' or 'cmd2'
True

Returns:

Name Type Description
TagValue TagValue | list[TagValue] | Any

The chosen value.

list TagValue | list[TagValue] | Any

If multiple=True, return chosen values.

Any TagValue | list[TagValue] | Any

If launch=True and the chosen value is a callback, we call it and return its result.

Info

To tackle a more detailed form, see SelectTag.options.

form(form=None, title='', *, submit=True)

Prompt the user to fill up an arbitrary form.

Use scalars, enums, enum instances, objects like datetime, Paths or their list.

from enum import Enum
from mininterface import run, Tag

class Color(Enum):
    RED = "red"
    GREEN = "green"
    BLUE = "blue"

m = run()
out = m.form({
    "my_number": 1,
    "my_boolean": True,
    "my_enum": Color,
    "my_tagged": Tag("", name='Tagged value', description='Long hint'),
    "my_path": Path("/tmp"),
    "my_paths": [Path("/tmp")],
    "My enum with default": Color.BLUE
})

Complex form dict

Parameters:

Name Type Description Default
form DataClass | Type[DataClass] | FormDict | None

We accept a dataclass type, a dataclass instance, a dict or None.

  • A dataclass type is resolved to a dataclass instance that is returned.

  • A dataclass instance is updated by the form and returned.

  • If dict, we expect a dict of {labels: value}. The form widget infers from the default value type. The dict can be nested, it can contain a subgroup. The value might be a Tag that allows you to add descriptions.

A checkbox example: {"my label": Tag(True, "my description")}

The original dict values are updated and a new dict (where all Tags are resolved to their values) is returned.

  • If None, the self.env is being used as a form, allowing the user to edit whole configuration. (Previously fetched from CLI and config file.)
None
title str

Optional form title

''
submit str | bool

Set the submit button text (by default 'Ok') or hide it with False.

True

Returns:

Name Type Description
dataclass FormDict | DataClass | EnvClass

If the form is null, the output is self.env.

dataclass FormDict | DataClass | EnvClass

If the form is a dataclass type or a dataclass instance, the output is the dataclass instance.

dict FormDict | DataClass | EnvClass

If the form is a dict, the output is another dict.

Whereas the original dict stays intact (with the values updated), we return a new raw dict with all values resolved (all Tag objects are resolved to their value).

original = {"my label": Tag(True, "my description")}
output = m.form(original)  # Sets the label to False in the dialog

# Original dict was updated
print(original["my label"])  # Tag(False, "my description")

# Output dict is resolved, contains only raw values
print(output["my label"])  # False

Why this behaviour? You need to do some validation, hence you put Tag objects in the input dict. Then, you just need to work with the values.

original = {"my label": Tag(True, "my description")}
output = m.form(original)  # Sets the label to False in the dialog
output["my_label"]

In the case you are willing to re-use the dict, you need not to lose the definitions, hence you end up with accessing via the .val.

original = {"my label": Tag(True, "my description")}

for i in range(10):
    m.form(original, f"Attempt {i}")
    print("The result", original["my label"].val)

Info

For minimal installation (pip install mininterface only), using Type[DataClass] like m.form(Env) will end up with Install the missing dependency by running: pip install mininterface[basic]. However using a dataclass instance m.form(Env()) will work. A lot of the stuff under the hood is needed to instantaniate a dataclass with all the checks.

OSZAR »