Skip to main content

A minimal access to GUI, TUI, CLI and config

Project description

Mininterface – access to GUI, TUI, CLI and config files

License: GPL v3 Build Status Downloads

Write the program core, do not bother with the input/output.

Hello world example: GUI window Hello world example: TUI fallback

Check out the code, which is surprisingly short, that displays such a window or its textual fallback.

from dataclasses import dataclass
from mininterface import run

@dataclass
class Env:
    """ This calculates something. """

    my_flag: bool = False
    """ This switches the functionality """

    my_number: int = 4
    """ This number is very important """

if __name__ == "__main__":
    m = run(Env, prog="My application")
    m.form()
    # Attributes are suggested by the IDE
    # along with the hint text 'This number is very important'.
    print(m.env.my_number)

Contents

You got CLI

It was all the code you need. No lengthy blocks of code imposed by an external dependency. Besides the GUI/TUI, you receive powerful YAML-configurable CLI parsing.

$ ./hello.py    --help
usage: My application [-h] [-v] [--my-flag | --no-my-flag] [--my-number INT]

This calculates something.

╭─ options ───────────────────────────────────────────────────────────────╮
│ -h, --help             show this help message and exit                  │
│ -v, --verbose          Verbosity level. Can be used twice to increase.  │
│ --my-flag, --no-my-flag                                                 │
│                        This switches the functionality (default: False) │
│ --my-number INT        This number is very important (default: 4)       │
╰─────────────────────────────────────────────────────────────────────────╯

You got config file management

Loading config file is a piece of cake. Alongside program.py, put program.yaml and put there some of the arguments. They are seamlessly taken as defaults.

my_number: 555

You got dialogues

Check out several useful methods to handle user dialogues. Here we bound the interface to a with statement that redirects stdout directly to the window.

with run(Env) as m:
    print(f"Your important number is {m.env.my_number}")
    boolean = m.is_yes("Is that alright?")

Small window with the text 'Your important number' The same in terminal'

Background

Wrapper between the tyro argparse replacement and tkinter_form that converts dicts into a GUI.

Writing a small and useful program might be a task that takes fifteen minutes. Adding a CLI to specify the parameters is not so much overhead. But building a simple GUI around it? HOURS! Hours spent on researching GUI libraries, wondering why the Python desktop app ecosystem lags so far behind the web world. All you need is a few input fields validated through a clickable window... You do not deserve to add hundred of lines of the code just to define some editable fields. Mininterface is here to help.

The config variables needed by your program are kept in cozy dataclasses. Write less! The syntax of tyro does not require any overhead (as its argparse alternatives do). You just annotate a class attribute, append a simple docstring and get a fully functional application:

  • Call it as program.py --help to display full help.
  • Use any flag in CLI: program.py --my-flag causes env.my_flag be set to True.
  • The main benefit: Launch it without parameters as program.py to get a full working window with all the flags ready to be edited.
  • Running on a remote machine? Automatic regression to the text interface.

Installation

Install with a single command from PyPi.

pip install mininterface

Minimal installation

Should you need just the CLI part and you are happy with basic text dialogs, use these commands instead:

pip install --no-dependencies mininterface
pip install tyro typing_extensions pyyaml

Docs

See the docs overview at https://cz-nic.github.io/mininterface/.

Examples

A powerful [m.form][mininterface.Mininterface.form] dialog method accepts either a dataclass or a dict. Take a look on both.

A complex dataclass.

from typing import Annotated
from dataclasses import dataclass
from mininterface.validators import not_empty
from mininterface import run, Tag, Validation

@dataclass
class NestedEnv:
  another_number: int = 7
  """ This field is nested """

@dataclass
class Env:
  nested_config: NestedEnv

  mandatory_str: str
  """ As there is no default value, you will be prompted automatically to fill up the field """

  my_number: int | None = None
  """ This is not just a dummy number, if left empty, it is None. """

  my_string: str = "Hello"
  """ A dummy string """

  my_flag: bool = False
  """ Checkbox test """

  my_validated: Annotated[str, Validation(not_empty)] = "hello"
  """ A validated field """

m = run(Env, title="My program")
# See some values
print(m.env.nested_config.another_number)  # 7
print(m.env)
# Env(nested_config=NestedEnv(another_number=7), my_number=5, my_string='Hello', my_flag=False, my_validated='hello')

# Edit values in a dialog
m.form()

As the attribute mandatory_str requires a value, a prompt appears automatically:

Complex example missing field

Then, full form appears:

Complex example

Form with paths

We have a dict with some paths. Here is how it looks.

from pathlib import Path
from mininterface import run, Tag

m = run(title="My program")
my_dictionary = {
  "paths": Tag("", annotation=list[Path]),
  "default_paths": Tag([Path("/tmp"), Path("/usr")], annotation=list[Path])
  }

# Edit values in a dialog
m.form(my_dictionary)

List of paths

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mininterface-0.7.0.tar.gz (58.8 kB view details)

Uploaded Source

Built Distribution

mininterface-0.7.0-py3-none-any.whl (71.5 kB view details)

Uploaded Python 3

File details

Details for the file mininterface-0.7.0.tar.gz.

File metadata

  • Download URL: mininterface-0.7.0.tar.gz
  • Upload date:
  • Size: 58.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.10

File hashes

Hashes for mininterface-0.7.0.tar.gz
Algorithm Hash digest
SHA256 ea676d1b37683f0cdac4cd523ae7e0cdf003de6c61c832c3c5c9b99ae630e96f
MD5 2204ec5fda649fd1cbfe55cb81d3b259
BLAKE2b-256 f78db9bc2c1969f0f46144330347b43a22cb06aabb6275e8c6bc1f7cd5604e71

See more details on using hashes here.

File details

Details for the file mininterface-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: mininterface-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 71.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.10

File hashes

Hashes for mininterface-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8e8b0650a67deef14e14e0798e919d403a78f54934eaae5c693bdd2e14b791c8
MD5 a7fde5fc194044ea918b3b533b7eeda1
BLAKE2b-256 c6a0a431e727d1488aaecd990cce69ca74aad58d0ed99356a3f5be5a0595e06a

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page