main
md 93 lines 3.19 KB
Rendered Raw
1 # API And WebUI
2
3 ## Source Anchors
4
5 - HTTP handler base and route registration: `/a0/helpers/api.py`
6 - API DOX: `/a0/api/AGENTS.md`
7 - WebSocket handler base: `/a0/helpers/ws.py`
8 - WebUI shell DOX: `/a0/webui/AGENTS.md`
9 - Component and JS DOX: `/a0/webui/components/AGENTS.md`, `/a0/webui/js/AGENTS.md`
10 - Frontend extension loading: `/a0/webui/js/extensions.js`
11
12 ## HTTP API Contract
13
14 HTTP API handlers derive from `helpers.api.ApiHandler`:
15
16 ```python
17 from flask import Request, Response
18 from helpers.api import ApiHandler
19
20 class MyEndpoint(ApiHandler):
21 @classmethod
22 def get_methods(cls) -> list[str]:
23 return ["POST"]
24
25 async def process(self, input: dict, request: Request) -> dict | Response:
26 return {"ok": True}
27 ```
28
29 Defaults from `ApiHandler`:
30
31 | Method | Default |
32 |---|---|
33 | `requires_loopback()` | `False` |
34 | `requires_api_key()` | `False` |
35 | `requires_auth()` | `True` |
36 | `get_methods()` | `["POST"]` |
37 | `requires_csrf()` | `requires_auth()` |
38
39 Override these only when the endpoint contract requires it. Keep auth and CSRF protection intact for browser-facing state changes.
40
41 ## API Routes
42
43 `helpers.api.register_api_route(...)` registers:
44
45 ```text
46 /api/<path:path>
47 ```
48
49 Resolution:
50
51 - Built-in endpoint `api/<name>.py` becomes `/api/<name>`.
52 - Plugin endpoint `plugins/<plugin>/api/<handler>.py` becomes `/api/plugins/<plugin>/<handler>`.
53
54 Return a Flask `Response` for files, redirects, custom status codes, and plain text. Return a dictionary for JSON success payloads.
55
56 Direct files under `api/*.py` require matching `api/*.py.dox.md`.
57
58 ## WebSocket Handlers
59
60 WebSocket handlers live in `api/ws_*.py` or plugin API folders and derive from `helpers.ws.WsHandler`:
61
62 ```python
63 from helpers.ws import WsHandler
64
65 class MyHandler(WsHandler):
66 async def process(self, event: str, data: dict, sid: str) -> dict | None:
67 return {"ok": True}
68 ```
69
70 `WsHandler` mirrors `ApiHandler` security flags: auth defaults to `True`, CSRF defaults to auth, API-key and loopback default to `False`. Handlers should validate event data before using it and avoid returning secrets or unfiltered exception details.
71
72 ## WebUI Work
73
74 Follow the nearest WebUI DOX before changing frontend files:
75
76 - `webui/AGENTS.md` for the shell, CSS, assets, vendor, and extension loader.
77 - `webui/js/AGENTS.md` for stores, modals, API helpers, and JS infrastructure.
78 - `webui/components/AGENTS.md` and child docs for Alpine components.
79
80 Patterns:
81
82 - Store-dependent content should be gated by a `template x-if` guard before using `$store.<name>`.
83 - Stores are registered with `createStore` from `/js/AlpineStore.js`.
84 - Modals use `openModal(path)` and `closeModal()` from `/js/modals.js`.
85 - Plugin settings UIs bind persisted plugin values to `config.*` and modal-only state/actions to `context.*`.
86 - Plugin UI should use the A0 notification system instead of inline success/error boxes.
87
88 ## Verification
89
90 - Run endpoint-specific tests or nearest API/WebSocket tests for handler behavior.
91 - For auth, CSRF, upload/download, tunnel, or file endpoints, run security-focused regressions.
92 - For WebUI changes, use targeted component/store tests or a browser smoke check when practical.
93 - Check file-level DOX coverage when touching direct `api/*.py` modules.