-
Notifications
You must be signed in to change notification settings - Fork 0
API Docs
class InvokeEngine:
commands: dict[str, Command]In the following examples we will assume the following:
engine = InvokeEngine()engine.command(
self,
func: Union[callable, Command, meta] = None,
name: str = None,
aliases: list[str] = None,
) -> CommandTurns the decorated function into a Command object. This will also add the command to the engine's commands property, which is used to parse the command from a list of values.
By default name will be set to the name of the decorated function. Name is also not replaced when using aliases.
It is possible to add commands to multiple engines by stacking their decorators.
Examples:
Simple Decorator
@engine.command
def greet(user: str):
...Change Command Name
@engine.command(name="welcome")
def greet(user: str):
...
assert greet.name == "welcome"Change Aliases
@engine.command(aliases=["welcome", "hello"])
def greet(user: str):
...
assert greet.name == "greet"
assert greet.aliases == ["welcome", "hello"]engine.parse(
command_list: list[any],
_command: Command = None,
_callstack: list[Command] = None,
) -> tuple[Command, tuple[any, ...], tuple[Command, ...]]Recursively traverses the engine's command list, and any subcommands until no match can be found. Returns a tuple with the following values:
-
Command: The lowest command/subcommand that could be found. -
tuple[any, ...]: The rest of the list once no more subcommands could be found. -
tuple[Command, ...]: The callstack; A tuple of the all commands that were traversed.
The result can be unpacked like so:
cmd, args, cs = engine.parse(...)
# if you don't need any arguments or the callstack
cmd, *_ = engine.parse(...)Examples:
Parse Single Command
@engine.command
def greet(user: str) -> str:
return f"Hello {user}!"
cmd, args, _ = engine.parse(["greet", "iRedSC"])
result = cmd(*args)
assert result == "Hello iRedSC!"Parse Subcommand
@engine.command
def greet(user: str) -> str:
return f"Hello {user}!"
@greet.subcommand
def many(*users: str) -> str:
return f"Hello {', '.join(users)}!"
cmd, args, _ = engine.parse(["greet", "many", "iRedSC", "Blibs"])
result = cmd(*args)
assert result == "Hello iRedSC, Blibs!"
cmd, args, _ = engine.parse(["greet", "Blibs"])
result = cmd(*args)
assert result == "Hello Blibs!"class Command:
func: callable # The function or method that was transformed into a Command.
name: str
aliases: list[str]
requires: dict[str, bool] # The requirements for the command, this can be accessed for custom tests.
injections: dict[str, any] # Objects that will be injected into the command as kwargs.
children: dict[str, Command] # Similar to engine.commands; Lists the subcommands attached to a command.
helptext: str = NoneYou will generally only create Command objects with either the @engine.command decorator, or the @command.subcommand decorator.
In the following examples we will assume the following:
@engine.command
def greet(user: str):
...greet.subcommand(
self,
func: Union[callable, "Command", meta] = None,
name: str = None,
aliases: list[str] = None,
) -> CommandThe requirements of a command. See meta.require for setting requirements.
The objects that will be injected into a command. See meta.inject for setting injections.
class meta:
requires: dict[str, bool]
injections: dict[str, any]
func: callable = None
helptext: str = ""The meta class allows you to inject metadata about a command into the command's callable.
@engine.command
@meta.requires(req1=True, req2=True)
def greet(...):
...
assert greet.requires == {"req1": True, "req2": True}You can use the meta class to insert requirements for a command.
Arbitrary data can be passed without issue.
Requiring command=True will automatically inject the command into the command's callable.
Requiring engine=True will require an engine to be passed as a keyword argument, and will throw an EngineRequired exception if it isn't fulfilled.
Requiring a Command
@engine.command
@meta.require(command=True) # The command will automatically be injected.
def help(command):
print(command.helptext)Requiring an Engine
@engine.command
@meta.require(engine=True) # Sets requiring an engine, the engine will need to be manually passed.
def help(command):
print(command.helptext)If you want to automatically pass an engine in, please look at meta.inject.
var = 10
@engine.command
@meta.inject(num=var)
def greet(num):
return num
assert greet() == 10You can use the meta class to inject objects into the command's callable. The argument in the callable needs to match the parameter in the inject statement.
string_to_args(string: str) -> list[str, int, float, list]Invokify has a simple string parser that will return a list of values, keeping things like "quoted strings" intact.
Words
user_input = "simple test string"
result = string_to_args(user_input)
assert result == ["simple", "test", "string"]Numbers
user_input = "5 5.67 -76 -34.5 .5 9."
result = string_to_args(user_input)
assert result == [5, 5.67, -76, -34.5, 0.5, 9.0]Quoted Strings
user_input = 'here are "some quoted strings"'
result = string_to_args(user_input)
assert result == ["here", "are", "some quoted strings"]Lists
user_input = "here is [a, list of, values]"
result = string_to_args(user_input)
assert result == ["here", "is", ["a", "list of", "values"]]