AppManager SDK (appmanager-sdk)
Lightweight developer SDK, manifest builder, and runtime client for AppManager sub-applications and extensions.
Features
- No Heavy Host Dependencies: Zero required external dependencies (pure Python standard library).
- Python-Native Manifest Definition: Declare sub-application metadata, settings schema, UI slots, and scheduled tasks directly in your Python entrypoint instead of writing JSON by hand.
- Automated Manifest Generation: Export
manifest.jsonvia CLI (appmanager-sdk generate), python scripts (manifest.save_manifest()), or on-demand execution (python app.py --generate-manifest). - Type-Safe Schema & Autocomplete: Modern dataclasses (
AppManifest,Setting,AdminSection,ScheduledTask) with full IDE auto-completion. - Runtime Client SDK: Lightweight
AppManagerClientwith@require_authview decorator, header-based user resolution, and host telemetry integration. - Flask Extension Integration: Clean
AppManager(app, manifest=...)integration that automatically handles health check routes and CLI commands.
Installation
pip install appmanager-sdk
Optional Flask integration:
pip install appmanager-sdk[flask]
Quick Start
1. Define your sub-app and manifest in Python (app.py)
from flask import Flask, jsonify, request
from appmanager_sdk import AppManifest, Setting, AdminSection, ScheduledTask, AppManagerClient
app = Flask(__name__)
client = AppManagerClient("analytics-dashboard")
# Define the sub-app manifest directly in Python
manifest = AppManifest(
name="Analytics Dashboard",
slug="analytics-dashboard",
version="1.0.0",
description="Real-time analytics and visualization sub-app.",
entry_point="app:app",
health_check_path="/health",
has_web_ui=True,
requires_auth=True,
settings=[
Setting(key="api_key", type="string", default="demo-key", description="Ingestion API key"),
Setting(key="refresh_interval", type="integer", default=60, label="Refresh Rate (s)"),
],
ui_slots=["dashboard_widget"],
scheduled_tasks=[
ScheduledTask(name="warm_cache", entry_point="tasks:warm_cache", frequency="hourly")
],
)
@app.route("/")
@client.require_auth(role="user")
def index():
user = client.get_current_user(request.headers)
api_key = client.get_setting("api_key", default="demo-key")
return f"<h1>Hello, {user['email'] if user else 'Guest'}</h1><p>API Key: {api_key}</p>"
@app.route("/health")
def health():
return jsonify({"status": "healthy", "slug": "analytics-dashboard", "version": "1.0.0"})
if __name__ == "__main__":
import sys
if "--generate-manifest" in sys.argv or "generate-manifest" in sys.argv:
manifest.cli()
else:
app.run(port=5001, debug=True)
2. Generating manifest.json
You have three convenient ways to generate the manifest.json:
Method A: Using the CLI Tool
# Point to your python entrypoint or module:variable
appmanager-sdk generate app:manifest
# Or generate directly from the python file
appmanager-sdk generate app.py --out manifest.json
Method B: Directly from your script
python app.py --generate-manifest
Method C: Programmatic Export
manifest.save_manifest("manifest.json")
3. CLI Reference
The appmanager-sdk CLI provides essential tools for sub-app developers:
| Command | Description | Example |
|---|---|---|
generate [target] |
Generates manifest.json from a Python module or file. |
appmanager-sdk generate app:manifest |
validate [file] |
Validates a manifest.json or Python manifest against the schema. |
appmanager-sdk validate manifest.json |
init |
Scaffolds a starter Python entrypoint with an AppManifest. |
appmanager-sdk init --name "My Service" |
4. Manifest Schema Specification
AppManifest Fields
| Field | Type | Default | Description |
|---|---|---|---|
name |
str |
required | Human-readable title of the application. |
slug |
str |
auto-slug | URL-safe slug used for routing (/apps/<slug>/). |
version |
str |
"1.0.0" |
Semantic version string. |
description |
str |
"" |
Short summary of the sub-app purpose. |
entry_point |
str |
"app:app" |
WSGI callable in module:callable format. |
health_check_path |
str |
"/health" |
Health monitoring route. |
app_type |
str |
"standalone" |
"standalone" (sub-app) or "extension" (host modifier). |
target_app |
str |
None |
Target app slug if app_type="extension". |
has_web_ui |
bool |
True |
Whether the application exposes a web UI. |
requires_auth |
bool |
True |
Whether AppManager enforces authentication before dispatching. |
settings |
List[Setting] |
[] |
List of configurable admin settings. |
admin_sections |
List[AdminSection] |
[] |
Custom admin panels mounted under /admin/apps/<slug>/<id>. |
ui_slots |
List[str] |
[] |
UI slots this app/extension mounts into (e.g. user_badge, dashboard_widget). |
scheduled_tasks |
List[ScheduledTask] |
[] |
Periodic background cron routines. |
Setting Types
"string": Single-line text input"textarea": Multi-line text area"integer": Number input"boolean": Checkbox toggle"color": HTML color picker (#38bdf8)"json": Raw JSON editor / data blob
5. Flask Extension Pattern
If you prefer the Flask extension pattern:
from flask import Flask
from appmanager_sdk import AppManager
app = Flask(__name__)
mgr = AppManager(
app,
name="Payment Service",
slug="payment-service",
version="1.0.0",
description="Processes customer checkouts",
settings=[{"key": "stripe_key", "type": "string", "label": "Stripe Publishable Key"}],
)
# Automatically adds /health endpoint, attaches app.manifest, and registers Flask CLI commands
6. Runtime Client API (AppManagerClient)
When your app runs inside AppManager, the host gateway forwards authenticated user context and config values through request headers:
from appmanager_sdk import AppManagerClient
client = AppManagerClient("my-app")
# User details from gateway headers
user = client.get_current_user(request.headers)
# {"id": 1, "email": "admin@example.com", "role": "admin", "is_admin": True}
# Route protection
@app.route("/admin-only")
@client.require_auth(role="admin")
def admin_route():
return "Admin area"
# Config / Setting retrieval
api_key = client.get_setting("api_key", default="fallback")
# Extension storage
client.set_data("user", user_id, {"flair": "VIP"})
data = client.get_data("user", user_id)
# Host telemetry
client.report_event("checkout_completed", {"amount": 49.99})
client.report_metric("response_time_ms", 12.4, unit="ms")
Security
Forwarded identity headers (trust model)
get_current_user() and @require_auth trust the X-AppManager-User-* headers
forwarded by the AppManager gateway. This is only safe behind a gateway that
strips incoming X-AppManager-* headers and injects its own. Never expose
endpoints protected by @require_auth directly to clients.
To defend against a misconfigured proxy that fails to strip forged headers, you can require a shared-secret HMAC signature on the identity context:
client = AppManagerClient("my-app", header_secret="<shared-secret>")
# or via env: APPMANAGER_HEADER_SECRET
When header_secret is set, the gateway must sign the identity context
(User-Id | User-Email | User-Role) with HMAC-SHA256 and send it in
X-AppManager-Signature. Requests without a valid signature are rejected.
Manifest generation executes code
appmanager-sdk generate and load_manifest_from_module() execute the target
Python file to discover the manifest declaration. Only run them on code you
trust — never on untrusted input (e.g. unvetted PRs in CI).
License
MIT License. See LICENSE for details.
Metadata
Release files for appmanager-sdk 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| appmanager_sdk-0.1.0.tar.gz | 32.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| appmanager_sdk-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 58.8 kB
Release files / appmanager_sdk-0.1.0.tar.gz
| Download URL | appmanager_sdk-0.1.0.tar.gz |
|---|---|
| Size | 32.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b559dc5711b7044ade5b6b143819ce9ad0752b2d1c21333465e0139e80af2972
|
|
BLAKE2b-256 checksum How to use checksums |
8810e01337c20d6ba371e2179781e160a536cdb2f704b9a5d1fed546fc8d3e9e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency logRelease files / appmanager_sdk-0.1.0-py3-none-any.whl
| Download URL | appmanager_sdk-0.1.0-py3-none-any.whl |
|---|---|
| Size | 26.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
89ec40d35f8305000db8fd653188addc3822b7804ea3ff00d1a9a9ac3666cc9f
|
|
BLAKE2b-256 checksum How to use checksums |
b98dd741d98bcadc27eaac03502336997faa0bcbf60e7ecdb057545833300bdf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency log