# Argenta ### Python library for creating TUI --- ## Contents - [**Installing**](#installing) - [**Quick Start**](#quick-start) - [**Documentation**](#documentation) - [**App** Objects](#app-objects) - [\_\_init\_\_](#__init__) - [set\_description\_message\_pattern](#set\_description\_message\_pattern) - [set\_invalid\_input\_flags\_handler](#set\_invalid\_input\_flags\_handler) - [set\_repeated\_input\_flags\_handler](#set\_repeated\_input\_flags\_handler) - [set\_unknown\_command\_handler](#set\_unknown\_command\_handler) - [set\_empty\_command\_handler](#set\_empty\_command\_handler) - [set\_exit\_command\_handler](#set\_exit\_command\_handler) - [run\_polling](#run\_polling) - [include\_router](#include\_router) - [include\_routers](#include\_routers) - [add\_message\_on\_startup](#add\_message\_on\_startup) - [**AutoCompleter** Objects](#autocompleter-objects) - [\_\_init\_\_](#\_\_init\_\_) - [**PredefinedMessages** Objects](#predefinedmessages-objects) - [**StaticDividingLine** Objects](#staticdividingline-objects) - [\_\_init\_\_](#\_\_init\_\_) - [get\_full\_static\_line](#get\_full\_static\_line) - [**DynamicDividingLine** Objects](#dynamicdividingline-objects) - [\_\_init\_\_](#\_\_init\_\_) - [get\_full\_dynamic\_line](#get\_full\_dynamic\_line) - [**NoRegisteredHandlersException** Objects](#noregisteredhandlersexception-objects) - [**UnprocessedInputFlagException** Objects](#unprocessedinputflagexception-objects) - [**RepeatedInputFlagsException** Objects](#repeatedinputflagsexception-objects) - [**EmptyInputCommandException** Objects](#emptyinputcommandexception-objects) - [**PredefinedFlags** Objects](#predefinedflags-objects) - [**InputFlag** Objects](#inputflag-objects) - [\_\_init\_\_](#\_\_init\_\_) - [get\_value](#get\_value) - [**Flag** Objects](#flag-objects) - [\_\_init\_\_](#\_\_init\_\_) - [**Flags** Objects](#flags-objects) - [\_\_init\_\_](#\_\_init\_\_) - [get\_flags](#get\_flags) - [add\_flag](#add\_flag) - [add\_flags](#add\_flags) - [get\_flag](#get\_flag) - [**InputFlags** Objects](#inputflags-objects) - [\_\_init\_\_](#\_\_init\_\_) - [get\_flags](#get\_flags) - [add\_flag](#add\_flag) - [add\_flags](#add\_flags) - [get\_flag](#get\_flag) - [**Command** Objects](#command-objects) - [\_\_init\_\_](#\_\_init\_\_) - [**PositionalArgument** Objects](#positionalargument-objects) - [\_\_init\_\_](#\_\_init\_\_) - [**OptionalArgument** Objects](#optionalargument-objects) - [\_\_init\_\_](#\_\_init\_\_) - [**BooleanArgument** Objects](#booleanargument-objects) - [\_\_init\_\_](#\_\_init\_\_) - [**ArgParse** Objects](#argparse-objects) - [\_\_init\_\_](#\_\_init\_\_) - [set\_args](#set\_args) - [**Orchestrator** Objects](#orchestrator-objects) - [\_\_init\_\_](#\_\_init\_\_) - [start\_polling](#start\_polling) - [get\_input\_args](#get\_input\_args) - [**Router** Objects](#router-objects) - [\_\_init\_\_](#\_\_init\_\_) - [@command](#@command) - [set\_invalid\_input\_flag\_handler](#set\_invalid\_input\_flag\_handler) - [input\_command\_handler](#input\_command\_handler) - [set\_command\_register\_ignore](#set\_command\_register\_ignore) - [get\_triggers](#get\_triggers) - [get\_aliases](#get\_aliases) - [get\_title](#get\_title) - [set\_title](#set\_title) - [**RepeatedFlagNameException** Objects](#repeatedflagnameexception-objects) - [**TooManyTransferredArgsException** Objects](#toomanytransferredargsexception-objects) - [**RequiredArgumentNotPassedException** Objects](#requiredargumentnotpassedexception-objects) - [**IncorrectNumberOfHandlerArgsException** Objects](#incorrectnumberofhandlerargsexception-objects) - [**TriggerContainSpacesException** Objects](#triggercontainspacesexception-objects) --- ![preview](https://github.com/koloideal/Argenta/blob/kolo/imgs/mock_app_preview3.png?raw=True) An example of the TUI appearance --- # Installing ```bash pip install argenta ``` or ```bash poetry add argenta ``` --- # Quick start Example of the simplest TUI with a single command ```python # routers.py from argenta.router import Router from argenta.command import Command router = Router() @router.command(Command("hello")) def handler(): print("Hello, world!") ``` ```python # main.py from argenta.app import App from argenta.orchestrator import Orchestrator from routers import router app: App = App() orchestrator: Orchestrator = Orchestrator() def main() -> None: app.include_router(router) orchestrator.start_polling(app) if __name__ == '__main__': main() ``` Example TUI with a command that has processed flags ```python # routers.py import re from argenta.router import Router from argenta.command import Command from argenta.orchestrator import Orchestrator from argenta.command.flag.defaults import PredefinedFlags from argenta.command.flag import Flags, Flag, InputFlags router = Router() registered_flags = Flags(PredefinedFlags.HOST, Flag('port', '--', re.compile(r'^[0-9]{1,4}$'))) @router.command(Command("hello")) def handler(): print("Hello, world!") @router.command(Command(trigger="ssh", description='connect via ssh', flags=registered_flags)) def handler_with_flags(flags: InputFlags): for flag in flags: print(f'Flag name: {flag.get_name()}\n' f'Flag value: {flag.get_value()}') ``` --- # Documentation # `.app` ## App Objects ```python class App(BaseApp) ``` #### \_\_init\_\_ ```python def __init__(prompt: str = '[italic dim bold]What do you want to do?\n', initial_message: str = '\nArgenta\n', farewell_message: str = '\nSee you\n', exit_command: Command = Command('Q', 'Exit command'), system_router_title: str | None = 'System points:', ignore_command_register: bool = True, dividing_line: StaticDividingLine | DynamicDividingLine = StaticDividingLine(), repeat_command_groups: bool = True, override_system_messages: bool = False, autocompleter: AutoCompleter = AutoCompleter(), print_func: Callable[[str], None] = Console().print) -> None ``` Public. The essence of the application itself. Configures and manages all aspects of the behavior and presentation of the user interacting with the user **Arguments**: - `prompt`: displayed before entering the command - `initial_message`: displayed at the start of the app - `farewell_message`: displayed at the end of the app - `exit_command`: the entity of the command that will be terminated when entered - `system_router_title`: system router title - `ignore_command_register`: whether to ignore the case of the entered commands - `dividing_line`: the entity of the dividing line - `repeat_command_groups`: whether to repeat the available commands and their description - `override_system_messages`: whether to redefine the default formatting of system messages - `autocompleter`: the entity of the autocompleter - `print_func`: system messages text output function **Returns**: `None` --- #### set\_description\_message\_pattern ```python def set_description_message_pattern( pattern: Callable[[str, str], str]) -> None ``` Public. Sets the output pattern of the available commands **Arguments**: - `pattern`: output pattern of the available commands **Returns**: `None` --- #### set\_invalid\_input\_flags\_handler ```python def set_invalid_input_flags_handler(handler: Callable[[str], None]) -> None ``` Public. Sets the handler for incorrect flags when entering a command **Arguments**: - `handler`: handler for incorrect flags when entering a command **Returns**: `None` --- #### set\_repeated\_input\_flags\_handler ```python def set_repeated_input_flags_handler(handler: Callable[[str], None]) -> None ``` Public. Sets the handler for repeated flags when entering a command **Arguments**: - `handler`: handler for repeated flags when entering a command **Returns**: `None` --- #### set\_unknown\_command\_handler ```python def set_unknown_command_handler(handler: Callable[[str], None]) -> None ``` Public. Sets the handler for unknown commands when entering a command **Arguments**: - `handler`: handler for unknown commands when entering a command **Returns**: `None` --- #### set\_empty\_command\_handler ```python def set_empty_command_handler(handler: Callable[[], None]) -> None ``` Public. Sets the handler for empty commands when entering a command **Arguments**: - `handler`: handler for empty commands when entering a command **Returns**: `None` --- #### set\_exit\_command\_handler ```python def set_exit_command_handler(handler: Callable[[], None]) -> None ``` Public. Sets the handler for exit command when entering a command **Arguments**: - `handler`: handler for exit command when entering a command **Returns**: `None` --- #### run\_polling ```python def run_polling() -> None ``` Private. Starts the user input processing cycle **Returns**: `None` --- #### include\_router ```python def include_router(router: Router) -> None ``` Public. Registers the router in the application **Arguments**: - `router`: registered router **Returns**: `None` --- #### include\_routers ```python def include_routers(*routers: Router) -> None ``` Public. Registers the routers in the application **Arguments**: - `routers`: registered routers **Returns**: `None` --- #### add\_message\_on\_startup ```python def add_message_on_startup(message: str) -> None ``` Public. Adds a message that will be displayed when the application is launched **Arguments**: - `message`: the message being added **Returns**: `None` --- # `.app.autocompleter` ## AutoCompleter Objects ```python class AutoCompleter() ``` #### \_\_init\_\_ ```python def __init__(history_filename: str = False, autocomplete_button: str = 'tab') -> None ``` Public. Configures and implements auto-completion of input command **Arguments**: - `history_filename`: the name of the file for saving the history of the autocompleter - `autocomplete_button`: the button for auto-completion **Returns**: `None` --- # `.app.defaults` ## PredefinedMessages Objects ```python @dataclass class PredefinedMessages() ``` Public. A dataclass with predetermined messages for quick use --- # `.app.dividing_line` ## StaticDividingLine Objects ```python class StaticDividingLine(BaseDividingLine) ``` #### \_\_init\_\_ ```python def __init__(unit_part: str = '-', length: int = 25) -> None ``` Public. The static dividing line **Arguments**: - `unit_part`: the single part of the dividing line - `length`: the length of the dividing line **Returns**: `None` --- #### get\_full\_static\_line ```python def get_full_static_line(is_override: bool) -> str ``` Private. Returns the full line of the dividing line **Arguments**: - `is_override`: has the default text layout been redefined **Returns**: full line of dividing line as str --- ## DynamicDividingLine Objects ```python class DynamicDividingLine(BaseDividingLine) ``` #### \_\_init\_\_ ```python def __init__(unit_part: str = '-') -> None ``` Public. The dynamic dividing line **Arguments**: - `unit_part`: the single part of the dividing line **Returns**: `None` --- #### get\_full\_dynamic\_line ```python def get_full_dynamic_line(length: int, is_override: bool) -> str ``` Private. Returns the full line of the dividing line **Arguments**: - `length`: the length of the dividing line - `is_override`: has the default text layout been redefined **Returns**: full line of dividing line as str --- # `.app.exceptions` ## NoRegisteredHandlersException Objects ```python class NoRegisteredHandlersException(Exception) ``` The router has no registered handlers --- # `.command.exceptions` ## UnprocessedInputFlagException Objects ```python class UnprocessedInputFlagException(BaseInputCommandException) ``` Private. Raised when an unprocessed input flag is detected --- ## RepeatedInputFlagsException Objects ```python class RepeatedInputFlagsException(BaseInputCommandException) ``` Private. Raised when repeated input flags are detected --- ## EmptyInputCommandException Objects ```python class EmptyInputCommandException(BaseInputCommandException) ``` Private. Raised when an empty input command is detected --- # `.command.flag.defaults` ## PredefinedFlags Objects ```python @dataclass class PredefinedFlags() ``` Public. A dataclass with predefined flags and most frequently used flags for quick use --- # `.command.flag` ## InputFlag Objects ```python class InputFlag(BaseFlag) ``` #### \_\_init\_\_ ```python def __init__(name: str, prefix: Literal['-', '--', '---'] = '--', value: str = None) ``` Public. The entity of the flag of the entered command **Arguments**: - `name`: the name of the input flag - `prefix`: the prefix of the input flag - `value`: the value of the input flag **Returns**: `None` --- #### get\_value ```python def get_value() -> str | None ``` Public. Returns the value of the flag **Returns**: the value of the flag as str --- ## Flag Objects ```python class Flag(BaseFlag) ``` #### \_\_init\_\_ ```python def __init__(name: str, prefix: Literal['-', '--', '---'] = '--', possible_values: list[str] | Pattern[str] | False = True) -> None ``` Public. The entity of the flag being registered for subsequent processing **Arguments**: - `name`: The name of the flag - `prefix`: The prefix of the flag - `possible_values`: The possible values of the flag, if False then the flag cannot have a value **Returns**: `None` --- ## Flags Objects ```python class Flags(BaseFlags) ``` #### \_\_init\_\_ ```python def __init__(*flags: Flag) ``` Public. A model that combines the registered flags **Arguments**: - `flags`: the flags that will be registered **Returns**: `None` --- #### get\_flags ```python def get_flags() -> list[Flag] ``` Public. Returns a list of flags **Returns**: list of flags as list[Flag] --- #### add\_flag ```python def add_flag(flag: Flag) -> None ``` Public. Adds a flag to the list of flags **Arguments**: - `flag`: flag to add **Returns**: `None` --- #### add\_flags ```python def add_flags(flags: list[Flag]) -> None ``` Public. Adds a list of flags to the list of flags **Arguments**: - `flags`: list of flags to add **Returns**: `None` --- #### get\_flag ```python def get_flag(name: str) -> Flag | None ``` Public. Returns the flag entity by its name or None if not found **Arguments**: - `name`: the name of the flag to get **Returns**: entity of the flag or None --- ## InputFlags Objects ```python class InputFlags(BaseFlags) ``` #### \_\_init\_\_ ```python def __init__(*flags: InputFlag) ``` Public. A model that combines the input flags of the input command **Arguments**: - `flags`: all input flags **Returns**: `None` --- #### get\_flags ```python def get_flags() -> list[InputFlag] ``` Public. Returns a list of flags **Returns**: list of flags --- #### add\_flag ```python def add_flag(flag: InputFlag) -> None ``` Public. Adds a flag to the list of flags **Arguments**: - `flag`: flag to add **Returns**: `None` --- #### add\_flags ```python def add_flags(flags: list[InputFlag]) -> None ``` Public. Adds a list of flags to the list of flags **Arguments**: - `flags`: list of flags to add **Returns**: `None` --- #### get\_flag ```python def get_flag(name: str) -> InputFlag ``` Public. Returns the flag entity by its name or None if not found **Arguments**: - `name`: the name of the flag to get **Returns**: entity of the flag or None --- # `.command.models` ## Command Objects ```python class Command(BaseCommand) ``` #### \_\_init\_\_ ```python def __init__(trigger: str, description: str = None, flags: Flag | Flags = None, aliases: list[str] = None) ``` Public. The command that can and should be registered in the Router **Arguments**: - `trigger`: A string trigger, which, when entered by the user, indicates that the input corresponds to the command - `description`: the description of the command - `flags`: processed commands - `aliases`: string synonyms for the main trigger --- # `.orchestrator.argparse.arguments` ## PositionalArgument Objects ```python class PositionalArgument(BaseArgument) ``` #### \_\_init\_\_ ```python def __init__(name: str) ``` Public. Required argument at startup **Arguments**: - `name`: name of the argument, must not start with minus (-) --- ## OptionalArgument Objects ```python class OptionalArgument(BaseArgument) ``` #### \_\_init\_\_ ```python def __init__(name: str, prefix: Literal['-', '--', '---'] = '--') ``` Public. Optional argument, must have the value **Arguments**: - `name`: name of the argument - `prefix`: prefix of the argument --- ## BooleanArgument Objects ```python class BooleanArgument(BaseArgument) ``` #### \_\_init\_\_ ```python def __init__(name: str, prefix: Literal['-', '--', '---'] = '--') ``` Public. Boolean argument, does not require a value **Arguments**: - `name`: name of the argument - `prefix`: prefix of the argument --- # `.orchestrator.argparser` ## ArgParse Objects ```python class ArgParse() ``` #### \_\_init\_\_ ```python def __init__(processed_args: list[PositionalArgument | OptionalArgument | BooleanArgument], name: str = 'Argenta', description: str = 'Argenta available arguments', epilog: str = 'github.com/koloideal/Argenta | made by kolo') -> None ``` Public. Cmd argument parser and configurator at startup **Arguments**: - `name`: the name of the ArgParse instance - `description`: the description of the ArgParse instance - `epilog`: the epilog of the ArgParse instance - `processed_args`: registered and processed arguments --- #### set\_args ```python def set_args(*args: PositionalArgument | OptionalArgument | BooleanArgument) -> None ``` Public. Sets the arguments to be processed **Arguments**: - `args`: processed arguments **Returns**: `None` --- # `.orchestrator` ## Orchestrator Objects ```python class Orchestrator() ``` #### \_\_init\_\_ ```python def __init__(arg_parser: ArgParse = False) ``` Public. An orchestrator and configurator that defines the behavior of an integrated system, one level higher than the App **Arguments**: - `arg_parser`: Cmd argument parser and configurator at startup **Returns**: `None` --- #### start\_polling ```python @staticmethod def start_polling(app: App) -> None ``` Public. Starting the user input processing cycle **Arguments**: - `app`: a running application **Returns**: `None` --- #### get\_input\_args ```python def get_input_args() -> Namespace | None ``` Public. Returns the arguments parsed **Returns**: `None` --- # `.router` ## Router Objects ```python class Router() ``` #### \_\_init\_\_ ```python def __init__(title: str = None) ``` Public. Directly configures and manages handlers **Arguments**: - `title`: the title of the router, displayed when displaying the available commands **Returns**: `None` --- #### @command ```python def command(command: Command) -> Callable ``` Public. Registers handler **Arguments**: - `command`: Registered command **Returns**: decorated handler as Callable[[Any], Any] --- #### set\_invalid\_input\_flag\_handler ```python def set_invalid_input_flag_handler(func) -> None ``` Public. Registers handler for invalid input flag **Arguments**: - `func`: registered handler **Returns**: `None` --- #### input\_command\_handler ```python def input_command_handler(input_command: InputCommand) -> None ``` Private. One handler for all input commands **Arguments**: - `input_command`: input command as InputCommand **Returns**: `None` --- #### set\_command\_register\_ignore ```python def set_command_register_ignore(_: bool) -> None ``` Private. Sets the router behavior on the input commands register **Arguments**: - `_`: is command register ignore **Returns**: `None` --- #### get\_triggers ```python def get_triggers() -> list[str] ``` Public. Gets registered triggers **Returns**: registered in router triggers as list[str] --- #### get\_aliases ```python def get_aliases() -> list[str] ``` Public. Gets registered aliases **Returns**: registered in router aliases as list[str] --- #### get\_title ```python def get_title() -> str | None ``` Public. Gets title of the router **Returns**: the title of the router as str or None --- #### set\_title ```python def set_title(title: str) -> None ``` Public. Sets the title of the router **Arguments**: - `title`: title that will be setted **Returns**: `None` --- # `.router.exceptions` ## RepeatedFlagNameException Objects ```python class RepeatedFlagNameException(Exception) ``` Private. Raised when a repeated flag name is registered --- ## TooManyTransferredArgsException Objects ```python class TooManyTransferredArgsException(Exception) ``` Private. Raised when too many arguments are passed --- ## RequiredArgumentNotPassedException Objects ```python class RequiredArgumentNotPassedException(Exception) ``` Private. Raised when a required argument is not passed --- ## IncorrectNumberOfHandlerArgsException Objects ```python class IncorrectNumberOfHandlerArgsException(Exception) ``` Private. Raised when incorrect number of arguments are passed --- ## TriggerContainSpacesException Objects ```python class TriggerContainSpacesException(Exception) ``` Private. Raised when there is a space in the trigger being registered --- # Tests Run tests: ```bash python -m unittest discover ``` or ```bash python -m unittest discover -v ``` --- # made by kolo `MIT` `2025`