2.4 KiB
2.4 KiB
Getting started
Project structure
my_project/
├── main.py
├── config.ini
└── modules/
├── cmds_foo.py
└── cmds_bar.py
Configuration file
[general]
default = foo # default module (used when no module is specified)
# methods_prefix = cmd_ # optional: override command method prefix
# modules_prefix = cmds_ # optional: override module file prefix
[foo]
alias = f # optional: short name for the module
my_setting = value # any key accessible via self.config.get("my_setting")
[bar]
# ...
Writing a module
from appengine import Commands, AppEngineException, AEErrs
class Foo(Commands):
# Set to True to run this module in a background thread
threaded = False
# Declare dependencies on other modules
# dependencies = ["bar"] # list form → self.bar = cmods["bar"]
# dependencies = {"b": "bar"} # dict form → self.b = cmods["bar"]
def cmd_add(self, a: float, b: float):
"""Add two numbers.
Args:
a: First operand.
b: Second operand.
Returns:
float: The sum of *a* and *b*.
"""
return float(a) + float(b)
def cmd_fail(self):
"""Demonstrate structured error reporting."""
raise AppEngineException(AEErrs.INVALID_PARAMS, "Nothing to do here")
def free(self):
# Close connections, files, etc.
pass
Threaded module
import time
from appengine import Commands
class Worker(Commands):
threaded = True # will be started as a Thread
def run(self):
while not self.stopped:
self.info("tick")
time.sleep(1)
def free(self):
self.info("worker cleaned up")
Dispatching commands
Commands are dispatched via execute_command(module, method, *args):
success, result = my_commands_instance.execute_command("foo", "add", 1, 2)
Built-in help
| Call | Result |
|---|---|
execute_command("", "help") |
List of all modules |
execute_command("", "help", "foo") |
List of commands in foo |
execute_command("", "help", "foo.add") |
Docstring of foo.add |
Error handling
Commands return (success: bool, result).
On error, result is a tuple (error_code: int, message: str).
Error codes follow the JSON-RPC convention (see AEErrs).