appmanager-server 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- appmanager_server-0.2.0/.env.example +42 -0
- appmanager_server-0.2.0/LICENSE +21 -0
- appmanager_server-0.2.0/MANIFEST.in +10 -0
- appmanager_server-0.2.0/PKG-INFO +320 -0
- appmanager_server-0.2.0/README.md +259 -0
- appmanager_server-0.2.0/SECURITY.md +40 -0
- appmanager_server-0.2.0/appmanager/__init__.py +52 -0
- appmanager_server-0.2.0/appmanager/admin/__init__.py +3 -0
- appmanager_server-0.2.0/appmanager/admin/app_installer.py +739 -0
- appmanager_server-0.2.0/appmanager/admin/members.py +95 -0
- appmanager_server-0.2.0/appmanager/admin/registry.py +372 -0
- appmanager_server-0.2.0/appmanager/admin/routes.py +900 -0
- appmanager_server-0.2.0/appmanager/api/__init__.py +5 -0
- appmanager_server-0.2.0/appmanager/api/routes.py +373 -0
- appmanager_server-0.2.0/appmanager/app_config.py +101 -0
- appmanager_server-0.2.0/appmanager/auth/__init__.py +3 -0
- appmanager_server-0.2.0/appmanager/auth/oauth.py +77 -0
- appmanager_server-0.2.0/appmanager/auth/routes.py +224 -0
- appmanager_server-0.2.0/appmanager/auth/utils.py +175 -0
- appmanager_server-0.2.0/appmanager/bridge.py +90 -0
- appmanager_server-0.2.0/appmanager/cli.py +1171 -0
- appmanager_server-0.2.0/appmanager/config.py +58 -0
- appmanager_server-0.2.0/appmanager/database.py +120 -0
- appmanager_server-0.2.0/appmanager/extension.py +198 -0
- appmanager_server-0.2.0/appmanager/extensions.py +225 -0
- appmanager_server-0.2.0/appmanager/health.py +133 -0
- appmanager_server-0.2.0/appmanager/hooks.py +187 -0
- appmanager_server-0.2.0/appmanager/middleware.py +256 -0
- appmanager_server-0.2.0/appmanager/models.py +307 -0
- appmanager_server-0.2.0/appmanager/py.typed +1 -0
- appmanager_server-0.2.0/appmanager/sdk.py +30 -0
- appmanager_server-0.2.0/appmanager/security.py +227 -0
- appmanager_server-0.2.0/appmanager/security_scanner.py +582 -0
- appmanager_server-0.2.0/appmanager/signals.py +21 -0
- appmanager_server-0.2.0/appmanager/static/css/app.css +808 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/fonts.css +288 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-0.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-1.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-10.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-11.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-12.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-13.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-14.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-15.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-16.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-17.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-18.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-19.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-2.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-20.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-21.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-22.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-23.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-3.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-4.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-5.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-6.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-7.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-8.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-9.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-0.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-1.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-10.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-11.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-2.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-3.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-4.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-5.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-6.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-7.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-8.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-9.woff2 +0 -0
- appmanager_server-0.2.0/appmanager/static/vendor/htmx/htmx.min.js +1 -0
- appmanager_server-0.2.0/appmanager/templates/admin/_member_drawer.html +98 -0
- appmanager_server-0.2.0/appmanager/templates/admin/_members_table.html +108 -0
- appmanager_server-0.2.0/appmanager/templates/admin/app_detail.html +136 -0
- appmanager_server-0.2.0/appmanager/templates/admin/dashboard.html +902 -0
- appmanager_server-0.2.0/appmanager/templates/admin/flairs.html +90 -0
- appmanager_server-0.2.0/appmanager/templates/admin/permissions.html +88 -0
- appmanager_server-0.2.0/appmanager/templates/admin/roles.html +119 -0
- appmanager_server-0.2.0/appmanager/templates/admin/users.html +156 -0
- appmanager_server-0.2.0/appmanager/templates/auth/login.html +58 -0
- appmanager_server-0.2.0/appmanager/templates/auth/profile.html +44 -0
- appmanager_server-0.2.0/appmanager/templates/base.html +76 -0
- appmanager_server-0.2.0/appmanager/templates/errors/401.html +19 -0
- appmanager_server-0.2.0/appmanager/templates/errors/403.html +19 -0
- appmanager_server-0.2.0/appmanager/templates/errors/404.html +18 -0
- appmanager_server-0.2.0/appmanager/templates/errors/500.html +19 -0
- appmanager_server-0.2.0/appmanager/templates/index.html +54 -0
- appmanager_server-0.2.0/appmanager_server.egg-info/PKG-INFO +320 -0
- appmanager_server-0.2.0/appmanager_server.egg-info/SOURCES.txt +120 -0
- appmanager_server-0.2.0/appmanager_server.egg-info/dependency_links.txt +1 -0
- appmanager_server-0.2.0/appmanager_server.egg-info/entry_points.txt +5 -0
- appmanager_server-0.2.0/appmanager_server.egg-info/requires.txt +35 -0
- appmanager_server-0.2.0/appmanager_server.egg-info/top_level.txt +1 -0
- appmanager_server-0.2.0/pyproject.toml +128 -0
- appmanager_server-0.2.0/requirements.txt +9 -0
- appmanager_server-0.2.0/setup.cfg +4 -0
- appmanager_server-0.2.0/tests/test_api.py +117 -0
- appmanager_server-0.2.0/tests/test_app_settings.py +85 -0
- appmanager_server-0.2.0/tests/test_app_settings_config.py +77 -0
- appmanager_server-0.2.0/tests/test_auth.py +74 -0
- appmanager_server-0.2.0/tests/test_cli_dev_and_templates.py +48 -0
- appmanager_server-0.2.0/tests/test_cli_health.py +52 -0
- appmanager_server-0.2.0/tests/test_cli_scaffolding.py +68 -0
- appmanager_server-0.2.0/tests/test_error_pages.py +45 -0
- appmanager_server-0.2.0/tests/test_extension_apps.py +122 -0
- appmanager_server-0.2.0/tests/test_extension_pattern.py +64 -0
- appmanager_server-0.2.0/tests/test_hooks.py +76 -0
- appmanager_server-0.2.0/tests/test_installer.py +80 -0
- appmanager_server-0.2.0/tests/test_invalid_install_failures.py +209 -0
- appmanager_server-0.2.0/tests/test_manifest_sdk.py +136 -0
- appmanager_server-0.2.0/tests/test_middleware.py +128 -0
- appmanager_server-0.2.0/tests/test_packaging_and_cli.py +77 -0
- appmanager_server-0.2.0/tests/test_role_management.py +193 -0
- appmanager_server-0.2.0/tests/test_sdk.py +120 -0
- appmanager_server-0.2.0/tests/test_security_hardening.py +245 -0
- appmanager_server-0.2.0/tests/test_security_precheck_flow.py +238 -0
- appmanager_server-0.2.0/tests/test_security_scanner.py +116 -0
- appmanager_server-0.2.0/tests/test_signals.py +113 -0
- appmanager_server-0.2.0/tests/test_user_elevation_and_visibility.py +237 -0
- appmanager_server-0.2.0/tests/test_user_tracking.py +71 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# AppManager Configuration
|
|
3
|
+
# Copy this file to .env and adjust the values as needed.
|
|
4
|
+
# ==============================================================================
|
|
5
|
+
|
|
6
|
+
# Core Application Security
|
|
7
|
+
# IMPORTANT: Generate strong random secrets for production!
|
|
8
|
+
SECRET_KEY=appmanager-change-this-to-a-secure-random-string-in-production-min-32-chars
|
|
9
|
+
JWT_SECRET=jwt-change-this-to-a-secure-random-string-in-production-min-32-chars
|
|
10
|
+
JWT_ACCESS_TOKEN_EXPIRES_DAYS=7
|
|
11
|
+
MAGIC_LINK_EXPIRES_MINUTES=15
|
|
12
|
+
|
|
13
|
+
# Server & Host URL
|
|
14
|
+
APP_BASE_URL=http://localhost:5000
|
|
15
|
+
PORT=5000
|
|
16
|
+
HOST=0.0.0.0
|
|
17
|
+
TEMPLATES_AUTO_RELOAD=true
|
|
18
|
+
SESSION_COOKIE_SAMESITE=Lax
|
|
19
|
+
SESSION_COOKIE_SECURE=false
|
|
20
|
+
|
|
21
|
+
# Database Configuration (SQLite default, PostgreSQL/MySQL supported)
|
|
22
|
+
# Examples:
|
|
23
|
+
# SQLite: sqlite:///instance/appmanager.db
|
|
24
|
+
# PostgreSQL: postgresql://user:password@localhost:5432/appmanager
|
|
25
|
+
# MySQL: mysql+pymysql://user:password@localhost:3306/appmanager
|
|
26
|
+
DATABASE_URL=sqlite:///instance/appmanager.db
|
|
27
|
+
|
|
28
|
+
# Storage Directories
|
|
29
|
+
# INSTALLED_APPS_DIR=./installed_apps
|
|
30
|
+
# TEMP_UPLOAD_DIR=./instance/uploads
|
|
31
|
+
|
|
32
|
+
# Google OAuth 2.0 (Optional - for Google Login)
|
|
33
|
+
GOOGLE_CLIENT_ID=
|
|
34
|
+
GOOGLE_CLIENT_SECRET=
|
|
35
|
+
GOOGLE_DISCOVERY_URL=https://accounts.google.com/.well-known/openid-configuration
|
|
36
|
+
|
|
37
|
+
# SMTP Email Configuration (Optional - logs to terminal console if left blank)
|
|
38
|
+
SMTP_SERVER=
|
|
39
|
+
SMTP_PORT=587
|
|
40
|
+
SMTP_USER=
|
|
41
|
+
SMTP_PASSWORD=
|
|
42
|
+
MAIL_DEFAULT_SENDER=noreply@appmanager.local
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AppManager Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
include LICENSE
|
|
2
|
+
include README.md
|
|
3
|
+
include SECURITY.md
|
|
4
|
+
include requirements.txt
|
|
5
|
+
include .env.example
|
|
6
|
+
include appmanager/py.typed
|
|
7
|
+
recursive-include appmanager/templates *
|
|
8
|
+
recursive-include appmanager/static *
|
|
9
|
+
recursive-exclude * __pycache__
|
|
10
|
+
recursive-exclude * *.py[co]
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: appmanager-server
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Multi-tenant Flask sub-application portal & dynamic WSGI dispatcher with in-process isolation, telemetry, and automated health checks.
|
|
5
|
+
Author: AppManager Contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/r3sbarra/appmanager-server
|
|
8
|
+
Project-URL: Documentation, https://github.com/r3sbarra/appmanager-server#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/r3sbarra/appmanager-server.git
|
|
10
|
+
Project-URL: Issues, https://github.com/r3sbarra/appmanager-server/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/r3sbarra/appmanager-server/blob/master/CHANGELOG.md
|
|
12
|
+
Keywords: flask,wsgi,multi-tenant,sub-apps,pythonanywhere,dispatcher,microfrontends,portal,appmanager
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Web Environment
|
|
15
|
+
Classifier: Framework :: Flask
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
25
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
|
|
26
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: Flask>=3.0.0
|
|
31
|
+
Requires-Dist: Flask-SQLAlchemy>=3.1.1
|
|
32
|
+
Requires-Dist: blinker>=1.6.0
|
|
33
|
+
Requires-Dist: PyJWT>=2.8.0
|
|
34
|
+
Requires-Dist: requests>=2.31.0
|
|
35
|
+
Requires-Dist: Authlib>=1.3.0
|
|
36
|
+
Requires-Dist: GitPython>=3.1.41
|
|
37
|
+
Requires-Dist: Werkzeug>=3.0.1
|
|
38
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
39
|
+
Requires-Dist: appmanager-sdk>=0.1.0
|
|
40
|
+
Provides-Extra: mysql
|
|
41
|
+
Requires-Dist: PyMySQL>=1.1.0; extra == "mysql"
|
|
42
|
+
Requires-Dist: cryptography>=41.0.0; extra == "mysql"
|
|
43
|
+
Provides-Extra: postgres
|
|
44
|
+
Requires-Dist: psycopg2-binary>=2.9.0; extra == "postgres"
|
|
45
|
+
Provides-Extra: all
|
|
46
|
+
Requires-Dist: PyMySQL>=1.1.0; extra == "all"
|
|
47
|
+
Requires-Dist: cryptography>=41.0.0; extra == "all"
|
|
48
|
+
Requires-Dist: psycopg2-binary>=2.9.0; extra == "all"
|
|
49
|
+
Provides-Extra: dev
|
|
50
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
51
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
|
|
52
|
+
Requires-Dist: ruff>=0.5.0; extra == "dev"
|
|
53
|
+
Requires-Dist: build>=1.1.0; extra == "dev"
|
|
54
|
+
Requires-Dist: twine>=5.0.0; extra == "dev"
|
|
55
|
+
Requires-Dist: PyMySQL>=1.1.0; extra == "dev"
|
|
56
|
+
Provides-Extra: docs
|
|
57
|
+
Requires-Dist: mkdocs-material>=9.5.0; extra == "docs"
|
|
58
|
+
Requires-Dist: mkdocstrings[python]>=0.25.0; extra == "docs"
|
|
59
|
+
Requires-Dist: pymdown-extensions>=10.7; extra == "docs"
|
|
60
|
+
Dynamic: license-file
|
|
61
|
+
|
|
62
|
+
<p align="center">
|
|
63
|
+
<img src="docs/assets/banner.svg" alt="AppManager Banner" width="100%">
|
|
64
|
+
</p>
|
|
65
|
+
|
|
66
|
+
<p align="center">
|
|
67
|
+
<a href="https://github.com/r3sbarra/appmanager-server/actions"><img src="https://github.com/r3sbarra/appmanager-server/actions/workflows/ci.yml/badge.svg" alt="CI Status"></a>
|
|
68
|
+
<a href="https://pypi.org/project/appmanager-server/"><img src="https://img.shields.io/pypi/v/appmanager-server.svg" alt="PyPI Version"></a>
|
|
69
|
+
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/pypi/pyversions/appmanager-server.svg" alt="Python Versions"></a>
|
|
70
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="License: MIT"></a>
|
|
71
|
+
</p>
|
|
72
|
+
|
|
73
|
+
# AppManager Server (`appmanager-server`)
|
|
74
|
+
|
|
75
|
+
**AppManager Server** is a high-performance Python/Flask application portal and extension framework designed to dynamically host, dispatch, and manage standalone WSGI sub-applications and modular extensions under a unified host server.
|
|
76
|
+
|
|
77
|
+
Optimized specifically for **PythonAnywhere**, cloud VMs, and multi-tenant hosting environments, AppManager provides scoped in-process module isolation, a pluggable UI slot & lifecycle hook system, automated health monitoring, telemetry reporting, live developer tooling, a headless REST API, and per-app settings configuration.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 🏛️ System Architecture
|
|
82
|
+
|
|
83
|
+
<p align="center">
|
|
84
|
+
<img src="docs/assets/appmanager-architecture.svg" alt="AppManager Architecture" width="100%">
|
|
85
|
+
</p>
|
|
86
|
+
|
|
87
|
+
```mermaid
|
|
88
|
+
graph LR
|
|
89
|
+
Client([🌐 Client / Browser]) --> Dispatcher[⚡ DynamicAppDispatcherMiddleware]
|
|
90
|
+
|
|
91
|
+
subgraph Host [AppManager Host Portal]
|
|
92
|
+
Dispatcher --> Auth[🔒 Authentication & Context Forwarder]
|
|
93
|
+
Auth --> DB[(🗄️ SQLite / MySQL Database)]
|
|
94
|
+
Auth --> Hooks[🧩 Hook & Slot Registry]
|
|
95
|
+
Auth --> Signals[🔔 Signal Hub & Telemetry]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
subgraph SubApps [Installed Sub-Apps & Extensions /apps/*]
|
|
99
|
+
Auth --> FlaskApp[🚀 Standalone Flask Sub-App]
|
|
100
|
+
Auth --> APIApp[🌐 RESTful API Sub-App]
|
|
101
|
+
Auth --> ExtPlugin[🧩 UI Slot Extension Plugin]
|
|
102
|
+
Auth --> HTMXApp[⚡ HTMX Reactive Dashboard]
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
FlaskApp -. SDK Telemetry & Settings .-> Host
|
|
106
|
+
ExtPlugin -. Injects Badges & Widgets .-> Hooks
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 🚀 Key Features
|
|
112
|
+
|
|
113
|
+
- 🔌 **Standard Flask Extension (`AppManager`)**: Seamlessly embeds into existing Flask applications (`AppManager(app)`) or runs as a standalone turnkey portal.
|
|
114
|
+
- 🔀 **Dynamic WSGI Sub-App Dispatcher**: Dynamically intercepts `/apps/<slug>/*` requests via `DynamicAppDispatcherMiddleware` and dispatches requests to installed sub-apps on-the-fly.
|
|
115
|
+
- 🧩 **Pluggable Hook & UI Slot System (`appmanager.hooks`)**: Mount custom HTML badges (`user_badge`), interactive cards (`dashboard_widget`), top navigation links (`nav_item`), and assets (`head_assets`) without altering host code.
|
|
116
|
+
- 🧰 **Developer SDK (`appmanager.sdk` / `appmanager-sdk`)**: Fluent `AppManagerClient` offering `@require_auth(role=...)`, typed user identity header parsing, telemetry metrics, and extension key-value data storage.
|
|
117
|
+
- ⚙️ **Per-App Settings Configuration**: Define customizable settings schemas in `manifest.json` with live configuration from the Admin Dashboard.
|
|
118
|
+
- 👤 **Verified Context & Header Forwarding**: Injects verified non-spoofed user identity (`X-AppManager-User-Id`, `X-AppManager-User-Email`, `X-AppManager-User-Role`, `X-Forwarded-Prefix`) directly into sub-app request headers.
|
|
119
|
+
- 🛠️ **Multi-Template Scaffolding & Dev Server**: Rapidly scaffold sub-apps (`appmanager new-subapp --template [basic|api|extension|htmx|full]`) and test locally in isolation with mock auth (`appmanager dev <slug>`).
|
|
120
|
+
- 🩺 **Automated Health Monitoring**: Sub-app health evaluation contract (`/health` endpoint or `get_health()` callable) tracked in `AppHealthLog` with one-click admin execution.
|
|
121
|
+
- 📊 **In-Process Telemetry Bridge**: High-performance telemetry reporting allowing sub-apps to record events and metrics directly to the host database with zero network overhead.
|
|
122
|
+
- 🔒 **Granular Role & Permissions Matrix**: Full RBAC role management and per-user permission matrix controlling access to every installed sub-app.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 📦 Quickstart & Installation
|
|
127
|
+
|
|
128
|
+
### 1. Install via pip
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
pip install appmanager-server
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
CLI commands available: `appmanager-server`, `appmgr-server`, `appmanager`, or `appmgr`.
|
|
135
|
+
|
|
136
|
+
### 2. Initialize and Seed
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
appmanager-server init
|
|
140
|
+
# or: appmgr-server init / appmanager init
|
|
141
|
+
appmanager seed
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 3. Run Development Server
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
appmanager run
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Navigate to `http://localhost:5000` to access the AppManager portal.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## 💻 Developer SDK & Sub-App Creation
|
|
155
|
+
|
|
156
|
+
### Scaffolding a New Sub-App or Extension
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Standalone Flask sub-app
|
|
160
|
+
appmanager new-subapp "Analytics Dashboard" --slug analytics --template basic
|
|
161
|
+
|
|
162
|
+
# RESTful JSON API sub-app
|
|
163
|
+
appmanager new-subapp "Payment Gateway" --slug payments --template api
|
|
164
|
+
|
|
165
|
+
# UI Slot Extension Plugin
|
|
166
|
+
appmanager new-subapp "User Badges" --slug user-badges --template extension
|
|
167
|
+
|
|
168
|
+
# Interactive HTMX sub-app
|
|
169
|
+
appmanager new-subapp "Live Monitor" --slug live-monitor --template htmx
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Local Sub-App Development Runner
|
|
173
|
+
|
|
174
|
+
Debug and test your sub-app locally with mock user authentication headers:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
appmanager dev analytics --port 5001 --email dev@example.com --role admin
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## 🛠️ Sub-App Specification (`manifest.json`)
|
|
183
|
+
|
|
184
|
+
To make an application deployable on AppManager, provide a `manifest.json` in the root:
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"name": "Analytics Dashboard",
|
|
189
|
+
"slug": "analytics",
|
|
190
|
+
"version": "1.0.0",
|
|
191
|
+
"description": "Standardized analytics sub-application.",
|
|
192
|
+
"entry_point": "app:app",
|
|
193
|
+
"health_check_path": "/health",
|
|
194
|
+
"app_type": "standalone",
|
|
195
|
+
"has_web_ui": true,
|
|
196
|
+
"settings": {
|
|
197
|
+
"api_key": {
|
|
198
|
+
"type": "string",
|
|
199
|
+
"default": "demo-key-12345",
|
|
200
|
+
"description": "API key for external data ingestion."
|
|
201
|
+
},
|
|
202
|
+
"refresh_interval_sec": {
|
|
203
|
+
"type": "number",
|
|
204
|
+
"default": 60,
|
|
205
|
+
"description": "Dashboard polling interval in seconds."
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"scheduled_tasks": [
|
|
209
|
+
{
|
|
210
|
+
"name": "daily_aggregation",
|
|
211
|
+
"entry_point": "tasks:run_aggregation",
|
|
212
|
+
"frequency": "daily"
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Sub-App Implementation with `appmanager.sdk`
|
|
219
|
+
|
|
220
|
+
```python
|
|
221
|
+
from flask import Flask, jsonify, request
|
|
222
|
+
from appmanager.sdk import AppManagerClient
|
|
223
|
+
|
|
224
|
+
app = Flask(__name__)
|
|
225
|
+
client = AppManagerClient("analytics")
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
@app.route("/")
|
|
229
|
+
@client.require_auth(role="user")
|
|
230
|
+
def index():
|
|
231
|
+
user = client.get_current_user(request.headers)
|
|
232
|
+
api_key = client.get_setting("api_key", default="demo-key")
|
|
233
|
+
client.report_event("dashboard_view", {"user_id": user["id"]})
|
|
234
|
+
|
|
235
|
+
return f"<h1>Welcome, {user['email']}</h1><p>Active API Key: {api_key}</p>"
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
@app.route("/health")
|
|
239
|
+
def health():
|
|
240
|
+
return jsonify({"status": "healthy", "app": "analytics"})
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
if __name__ == "__main__":
|
|
244
|
+
app.run(port=5001, debug=True)
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## 🧩 Pluggable UI Slots & Extension Hooks
|
|
250
|
+
|
|
251
|
+
Extensions can inject components into host slots:
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
from markupsafe import Markup
|
|
255
|
+
from appmanager.sdk import AppManagerClient
|
|
256
|
+
|
|
257
|
+
client = AppManagerClient("banner-extension")
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def render_dashboard_widget(user=None):
|
|
261
|
+
return Markup('<div class="card">✨ Custom analytics summary card</div>')
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
# Register to the host dashboard
|
|
265
|
+
client.register_slot("dashboard_widget", render_dashboard_widget, priority=5)
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Available UI slots:
|
|
269
|
+
- `user_badge`: Injected next to user names across profiles, tables, and headers.
|
|
270
|
+
- `dashboard_widget`: Mounted on the main `/dashboard` landing view.
|
|
271
|
+
- `nav_item`: Injected into the top navigation header bar.
|
|
272
|
+
- `head_assets`: Injected into the HTML `<head>` tag.
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## 🖥️ CLI Commands
|
|
277
|
+
|
|
278
|
+
| Command | Description |
|
|
279
|
+
| :--- | :--- |
|
|
280
|
+
| `appmanager init` | Bootstrap local directory with `installed_apps/` and `.env` template |
|
|
281
|
+
| `appmanager run` | Start the WSGI dynamic dispatcher host server |
|
|
282
|
+
| `appmanager dev <slug>` | Run standalone local test server with mock authentication |
|
|
283
|
+
| `appmanager seed` | Seed database with default starter apps, roles, and flairs |
|
|
284
|
+
| `appmanager new-subapp <name>` | Scaffold a sub-app with templates (`basic`, `api`, `extension`, `htmx`, `full`) |
|
|
285
|
+
| `appmanager validate-subapp <path>` | Validate a sub-app folder or ZIP package against manifest rules |
|
|
286
|
+
| `appmanager export-app <slug>` | Package an installed sub-app into a deployable ZIP archive |
|
|
287
|
+
| `appmanager reload-app <slug>` | Invalidate in-memory WSGI cache for zero-downtime updates |
|
|
288
|
+
| `appmanager hooks` | Inspect all registered UI slots, lifecycle hooks, and listeners |
|
|
289
|
+
| `appmanager check-health` | Run health evaluation checks across all active sub-apps |
|
|
290
|
+
| `appmanager run-scheduled-tasks` | Run background scheduled cron jobs and maintenance |
|
|
291
|
+
| `appmanager list-apps` | List all registered applications and their operational status |
|
|
292
|
+
| `appmanager list-users` | List all registered users and their assigned roles |
|
|
293
|
+
| `appmanager set-role <email>` | Elevate or update user role (`admin` or `user`) |
|
|
294
|
+
| `appmanager list-roles` | List all system and custom RBAC roles |
|
|
295
|
+
| `appmanager create-role <name>` | Create a new custom RBAC role |
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## 📖 Documentation
|
|
300
|
+
|
|
301
|
+
Full documentation is available at [https://appmanager.github.io/appmanager](https://appmanager.github.io/appmanager):
|
|
302
|
+
- [Getting Started](https://appmanager.github.io/appmanager/getting-started/)
|
|
303
|
+
- [Sub-App Development Guide](https://appmanager.github.io/appmanager/sub-apps/)
|
|
304
|
+
- [Hook & Slot Extension Guide](https://appmanager.github.io/appmanager/sub-apps/#ui-slots--extension-hooks)
|
|
305
|
+
- [Configuration & Settings Reference](https://appmanager.github.io/appmanager/configuration/)
|
|
306
|
+
- [PythonAnywhere & WSGI Deployment](https://appmanager.github.io/appmanager/deployment/)
|
|
307
|
+
- [CLI Reference](https://appmanager.github.io/appmanager/cli/)
|
|
308
|
+
- [Python API Reference](https://appmanager.github.io/appmanager/api/)
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## 🤝 Contributing
|
|
313
|
+
|
|
314
|
+
Contributions are welcome! Please check out [CONTRIBUTING.md](CONTRIBUTING.md) and our [Code of Conduct](CODE_OF_CONDUCT.md).
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## 📄 License
|
|
319
|
+
|
|
320
|
+
This project is licensed under the terms of the [MIT License](LICENSE).
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/assets/banner.svg" alt="AppManager Banner" width="100%">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://github.com/r3sbarra/appmanager-server/actions"><img src="https://github.com/r3sbarra/appmanager-server/actions/workflows/ci.yml/badge.svg" alt="CI Status"></a>
|
|
7
|
+
<a href="https://pypi.org/project/appmanager-server/"><img src="https://img.shields.io/pypi/v/appmanager-server.svg" alt="PyPI Version"></a>
|
|
8
|
+
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/pypi/pyversions/appmanager-server.svg" alt="Python Versions"></a>
|
|
9
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="License: MIT"></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
# AppManager Server (`appmanager-server`)
|
|
13
|
+
|
|
14
|
+
**AppManager Server** is a high-performance Python/Flask application portal and extension framework designed to dynamically host, dispatch, and manage standalone WSGI sub-applications and modular extensions under a unified host server.
|
|
15
|
+
|
|
16
|
+
Optimized specifically for **PythonAnywhere**, cloud VMs, and multi-tenant hosting environments, AppManager provides scoped in-process module isolation, a pluggable UI slot & lifecycle hook system, automated health monitoring, telemetry reporting, live developer tooling, a headless REST API, and per-app settings configuration.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 🏛️ System Architecture
|
|
21
|
+
|
|
22
|
+
<p align="center">
|
|
23
|
+
<img src="docs/assets/appmanager-architecture.svg" alt="AppManager Architecture" width="100%">
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
```mermaid
|
|
27
|
+
graph LR
|
|
28
|
+
Client([🌐 Client / Browser]) --> Dispatcher[⚡ DynamicAppDispatcherMiddleware]
|
|
29
|
+
|
|
30
|
+
subgraph Host [AppManager Host Portal]
|
|
31
|
+
Dispatcher --> Auth[🔒 Authentication & Context Forwarder]
|
|
32
|
+
Auth --> DB[(🗄️ SQLite / MySQL Database)]
|
|
33
|
+
Auth --> Hooks[🧩 Hook & Slot Registry]
|
|
34
|
+
Auth --> Signals[🔔 Signal Hub & Telemetry]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
subgraph SubApps [Installed Sub-Apps & Extensions /apps/*]
|
|
38
|
+
Auth --> FlaskApp[🚀 Standalone Flask Sub-App]
|
|
39
|
+
Auth --> APIApp[🌐 RESTful API Sub-App]
|
|
40
|
+
Auth --> ExtPlugin[🧩 UI Slot Extension Plugin]
|
|
41
|
+
Auth --> HTMXApp[⚡ HTMX Reactive Dashboard]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
FlaskApp -. SDK Telemetry & Settings .-> Host
|
|
45
|
+
ExtPlugin -. Injects Badges & Widgets .-> Hooks
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 🚀 Key Features
|
|
51
|
+
|
|
52
|
+
- 🔌 **Standard Flask Extension (`AppManager`)**: Seamlessly embeds into existing Flask applications (`AppManager(app)`) or runs as a standalone turnkey portal.
|
|
53
|
+
- 🔀 **Dynamic WSGI Sub-App Dispatcher**: Dynamically intercepts `/apps/<slug>/*` requests via `DynamicAppDispatcherMiddleware` and dispatches requests to installed sub-apps on-the-fly.
|
|
54
|
+
- 🧩 **Pluggable Hook & UI Slot System (`appmanager.hooks`)**: Mount custom HTML badges (`user_badge`), interactive cards (`dashboard_widget`), top navigation links (`nav_item`), and assets (`head_assets`) without altering host code.
|
|
55
|
+
- 🧰 **Developer SDK (`appmanager.sdk` / `appmanager-sdk`)**: Fluent `AppManagerClient` offering `@require_auth(role=...)`, typed user identity header parsing, telemetry metrics, and extension key-value data storage.
|
|
56
|
+
- ⚙️ **Per-App Settings Configuration**: Define customizable settings schemas in `manifest.json` with live configuration from the Admin Dashboard.
|
|
57
|
+
- 👤 **Verified Context & Header Forwarding**: Injects verified non-spoofed user identity (`X-AppManager-User-Id`, `X-AppManager-User-Email`, `X-AppManager-User-Role`, `X-Forwarded-Prefix`) directly into sub-app request headers.
|
|
58
|
+
- 🛠️ **Multi-Template Scaffolding & Dev Server**: Rapidly scaffold sub-apps (`appmanager new-subapp --template [basic|api|extension|htmx|full]`) and test locally in isolation with mock auth (`appmanager dev <slug>`).
|
|
59
|
+
- 🩺 **Automated Health Monitoring**: Sub-app health evaluation contract (`/health` endpoint or `get_health()` callable) tracked in `AppHealthLog` with one-click admin execution.
|
|
60
|
+
- 📊 **In-Process Telemetry Bridge**: High-performance telemetry reporting allowing sub-apps to record events and metrics directly to the host database with zero network overhead.
|
|
61
|
+
- 🔒 **Granular Role & Permissions Matrix**: Full RBAC role management and per-user permission matrix controlling access to every installed sub-app.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 📦 Quickstart & Installation
|
|
66
|
+
|
|
67
|
+
### 1. Install via pip
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pip install appmanager-server
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
CLI commands available: `appmanager-server`, `appmgr-server`, `appmanager`, or `appmgr`.
|
|
74
|
+
|
|
75
|
+
### 2. Initialize and Seed
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
appmanager-server init
|
|
79
|
+
# or: appmgr-server init / appmanager init
|
|
80
|
+
appmanager seed
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 3. Run Development Server
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
appmanager run
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Navigate to `http://localhost:5000` to access the AppManager portal.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 💻 Developer SDK & Sub-App Creation
|
|
94
|
+
|
|
95
|
+
### Scaffolding a New Sub-App or Extension
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Standalone Flask sub-app
|
|
99
|
+
appmanager new-subapp "Analytics Dashboard" --slug analytics --template basic
|
|
100
|
+
|
|
101
|
+
# RESTful JSON API sub-app
|
|
102
|
+
appmanager new-subapp "Payment Gateway" --slug payments --template api
|
|
103
|
+
|
|
104
|
+
# UI Slot Extension Plugin
|
|
105
|
+
appmanager new-subapp "User Badges" --slug user-badges --template extension
|
|
106
|
+
|
|
107
|
+
# Interactive HTMX sub-app
|
|
108
|
+
appmanager new-subapp "Live Monitor" --slug live-monitor --template htmx
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Local Sub-App Development Runner
|
|
112
|
+
|
|
113
|
+
Debug and test your sub-app locally with mock user authentication headers:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
appmanager dev analytics --port 5001 --email dev@example.com --role admin
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 🛠️ Sub-App Specification (`manifest.json`)
|
|
122
|
+
|
|
123
|
+
To make an application deployable on AppManager, provide a `manifest.json` in the root:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"name": "Analytics Dashboard",
|
|
128
|
+
"slug": "analytics",
|
|
129
|
+
"version": "1.0.0",
|
|
130
|
+
"description": "Standardized analytics sub-application.",
|
|
131
|
+
"entry_point": "app:app",
|
|
132
|
+
"health_check_path": "/health",
|
|
133
|
+
"app_type": "standalone",
|
|
134
|
+
"has_web_ui": true,
|
|
135
|
+
"settings": {
|
|
136
|
+
"api_key": {
|
|
137
|
+
"type": "string",
|
|
138
|
+
"default": "demo-key-12345",
|
|
139
|
+
"description": "API key for external data ingestion."
|
|
140
|
+
},
|
|
141
|
+
"refresh_interval_sec": {
|
|
142
|
+
"type": "number",
|
|
143
|
+
"default": 60,
|
|
144
|
+
"description": "Dashboard polling interval in seconds."
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
"scheduled_tasks": [
|
|
148
|
+
{
|
|
149
|
+
"name": "daily_aggregation",
|
|
150
|
+
"entry_point": "tasks:run_aggregation",
|
|
151
|
+
"frequency": "daily"
|
|
152
|
+
}
|
|
153
|
+
]
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Sub-App Implementation with `appmanager.sdk`
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
from flask import Flask, jsonify, request
|
|
161
|
+
from appmanager.sdk import AppManagerClient
|
|
162
|
+
|
|
163
|
+
app = Flask(__name__)
|
|
164
|
+
client = AppManagerClient("analytics")
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@app.route("/")
|
|
168
|
+
@client.require_auth(role="user")
|
|
169
|
+
def index():
|
|
170
|
+
user = client.get_current_user(request.headers)
|
|
171
|
+
api_key = client.get_setting("api_key", default="demo-key")
|
|
172
|
+
client.report_event("dashboard_view", {"user_id": user["id"]})
|
|
173
|
+
|
|
174
|
+
return f"<h1>Welcome, {user['email']}</h1><p>Active API Key: {api_key}</p>"
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@app.route("/health")
|
|
178
|
+
def health():
|
|
179
|
+
return jsonify({"status": "healthy", "app": "analytics"})
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
if __name__ == "__main__":
|
|
183
|
+
app.run(port=5001, debug=True)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 🧩 Pluggable UI Slots & Extension Hooks
|
|
189
|
+
|
|
190
|
+
Extensions can inject components into host slots:
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
from markupsafe import Markup
|
|
194
|
+
from appmanager.sdk import AppManagerClient
|
|
195
|
+
|
|
196
|
+
client = AppManagerClient("banner-extension")
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def render_dashboard_widget(user=None):
|
|
200
|
+
return Markup('<div class="card">✨ Custom analytics summary card</div>')
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
# Register to the host dashboard
|
|
204
|
+
client.register_slot("dashboard_widget", render_dashboard_widget, priority=5)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Available UI slots:
|
|
208
|
+
- `user_badge`: Injected next to user names across profiles, tables, and headers.
|
|
209
|
+
- `dashboard_widget`: Mounted on the main `/dashboard` landing view.
|
|
210
|
+
- `nav_item`: Injected into the top navigation header bar.
|
|
211
|
+
- `head_assets`: Injected into the HTML `<head>` tag.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 🖥️ CLI Commands
|
|
216
|
+
|
|
217
|
+
| Command | Description |
|
|
218
|
+
| :--- | :--- |
|
|
219
|
+
| `appmanager init` | Bootstrap local directory with `installed_apps/` and `.env` template |
|
|
220
|
+
| `appmanager run` | Start the WSGI dynamic dispatcher host server |
|
|
221
|
+
| `appmanager dev <slug>` | Run standalone local test server with mock authentication |
|
|
222
|
+
| `appmanager seed` | Seed database with default starter apps, roles, and flairs |
|
|
223
|
+
| `appmanager new-subapp <name>` | Scaffold a sub-app with templates (`basic`, `api`, `extension`, `htmx`, `full`) |
|
|
224
|
+
| `appmanager validate-subapp <path>` | Validate a sub-app folder or ZIP package against manifest rules |
|
|
225
|
+
| `appmanager export-app <slug>` | Package an installed sub-app into a deployable ZIP archive |
|
|
226
|
+
| `appmanager reload-app <slug>` | Invalidate in-memory WSGI cache for zero-downtime updates |
|
|
227
|
+
| `appmanager hooks` | Inspect all registered UI slots, lifecycle hooks, and listeners |
|
|
228
|
+
| `appmanager check-health` | Run health evaluation checks across all active sub-apps |
|
|
229
|
+
| `appmanager run-scheduled-tasks` | Run background scheduled cron jobs and maintenance |
|
|
230
|
+
| `appmanager list-apps` | List all registered applications and their operational status |
|
|
231
|
+
| `appmanager list-users` | List all registered users and their assigned roles |
|
|
232
|
+
| `appmanager set-role <email>` | Elevate or update user role (`admin` or `user`) |
|
|
233
|
+
| `appmanager list-roles` | List all system and custom RBAC roles |
|
|
234
|
+
| `appmanager create-role <name>` | Create a new custom RBAC role |
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## 📖 Documentation
|
|
239
|
+
|
|
240
|
+
Full documentation is available at [https://appmanager.github.io/appmanager](https://appmanager.github.io/appmanager):
|
|
241
|
+
- [Getting Started](https://appmanager.github.io/appmanager/getting-started/)
|
|
242
|
+
- [Sub-App Development Guide](https://appmanager.github.io/appmanager/sub-apps/)
|
|
243
|
+
- [Hook & Slot Extension Guide](https://appmanager.github.io/appmanager/sub-apps/#ui-slots--extension-hooks)
|
|
244
|
+
- [Configuration & Settings Reference](https://appmanager.github.io/appmanager/configuration/)
|
|
245
|
+
- [PythonAnywhere & WSGI Deployment](https://appmanager.github.io/appmanager/deployment/)
|
|
246
|
+
- [CLI Reference](https://appmanager.github.io/appmanager/cli/)
|
|
247
|
+
- [Python API Reference](https://appmanager.github.io/appmanager/api/)
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## 🤝 Contributing
|
|
252
|
+
|
|
253
|
+
Contributions are welcome! Please check out [CONTRIBUTING.md](CONTRIBUTING.md) and our [Code of Conduct](CODE_OF_CONDUCT.md).
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## 📄 License
|
|
258
|
+
|
|
259
|
+
This project is licensed under the terms of the [MIT License](LICENSE).
|