Documentation added

This commit is contained in:
2026-04-12 12:03:17 +02:00
parent 5a60e47c12
commit 5d8865a9fa
6 changed files with 621 additions and 7 deletions

25
docs/api.md Normal file
View File

@@ -0,0 +1,25 @@
# API Reference
## AppEngine
::: appengine.AppEngine
---
## Commands
::: appengine.Commands
---
## CommandsLoader
::: appengine.CommandsLoader
---
## Errors
::: appengine.AEErrs
::: appengine.AppEngineException

103
docs/getting-started.md Normal file
View File

@@ -0,0 +1,103 @@
# Getting started
## Project structure
```
my_project/
├── main.py
├── config.ini
└── modules/
├── cmds_foo.py
└── cmds_bar.py
```
## Configuration file
```ini
[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
```python
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
```python
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)`:
```python
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`).

65
docs/index.md Normal file
View File

@@ -0,0 +1,65 @@
# pyappengine
A Python framework for building **modular, command-based applications** with dynamic module loading, thread-safe command dispatch, and structured lifecycle management.
## Features
- **Dynamic module loading** — drop a `cmds_*.py` file in your module directory, it's loaded automatically
- **Thread-safe command dispatch** — shared lock across all modules
- **Threaded modules** — opt-in background thread execution per module
- **Inter-module dependencies** — declarative dependency injection between modules
- **Built-in help system** — introspects docstrings at runtime
- **INI configuration** — per-module config sections
- **Graceful shutdown** — SIGINT handler + global stop event
## Installation
```bash
pip install pyappengine
```
## Quick start
**1. Create your application entry point:**
```python
from appengine import AppEngine
app = AppEngine(
"my_app",
conf_file="config.ini",
log_file="my_app.log",
debug=True,
)
app.exec(modpath="./modules")
```
**2. Create a module** — save as `modules/cmds_hello.py`:
```python
from appengine import Commands
class Hello(Commands):
def cmd_greet(self, name: str):
"""Greet someone.
Args:
name: The person to greet.
Returns:
str: A greeting string.
"""
return f"Hello, {name}!"
```
**3. Create a minimal config**`config.ini`:
```ini
[general]
default = hello
```
## License
Released under the [CeCILL-C](https://cecill.info/licences/Licence_CeCILL-C_V1-en.html) license.
Author: François Dausseur — fdausseur@free.fr