Skip to content

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.

env: EnvClass = EnvInstance

Parsed arguments, fetched from cli. 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

facet = Facet(None, self.env)

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

__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_number("What number")

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_number("What number") + 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_number("What number") + piped_in
print(result)
echo 2 | ./program.py
Asking: What number
3

alert(text)

Prompt the user to confirm the text.

ask(text)

Prompt the user to input a text.

ask_number(text)

Prompt the user to input a number. Empty input = 0.

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

Ask number dialog

Parameters:

Name Type Description Default
text str

The question text.

required

Returns:

Type Description
int

Number

choice(choices, title='', _guesses=None, skippable=True, launch=True, _multiple=True, default=None)

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

Parameters:

Name Type Description Default
choices ChoicesType

You can denote the choices in many ways. Either put options in an iterable:

from mininterface import run
m = run()
m.choice([1, 2])

Choices as a list

Or to a dict {name: value}. Then name are used as labels.

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

Alternatively, you may specify the names in Tags.

m.choice([Tag(1, name="one"), Tag(2, name="two")])  # returns 1

Choices with labels

Alternatively, you may use an Enum.

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

m.choice(Color)

Choices from enum

Alternatively, you may use an Enum instance.

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

m.choice(Color.BLUE)

Choices from enum

Alternatively, you may use an Enum instances list.

m.choice([Color.GREEN, Color.BLUE])

Choices from enum list

required
title str

Form title

''
default str | TagValue | None

The value of the checked choice.

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

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.

True

Returns:

Type Description
TagValue | list[TagValue] | Any

The chosen value.

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 Tag.choices.

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.

  • 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")}

  • 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)

is_yes(text)

Display confirm box, focusing yes.

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

Is yes window

is_no(text)

Display confirm box, focusing no.