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.
Files changed (122) hide show
  1. appmanager_server-0.2.0/.env.example +42 -0
  2. appmanager_server-0.2.0/LICENSE +21 -0
  3. appmanager_server-0.2.0/MANIFEST.in +10 -0
  4. appmanager_server-0.2.0/PKG-INFO +320 -0
  5. appmanager_server-0.2.0/README.md +259 -0
  6. appmanager_server-0.2.0/SECURITY.md +40 -0
  7. appmanager_server-0.2.0/appmanager/__init__.py +52 -0
  8. appmanager_server-0.2.0/appmanager/admin/__init__.py +3 -0
  9. appmanager_server-0.2.0/appmanager/admin/app_installer.py +739 -0
  10. appmanager_server-0.2.0/appmanager/admin/members.py +95 -0
  11. appmanager_server-0.2.0/appmanager/admin/registry.py +372 -0
  12. appmanager_server-0.2.0/appmanager/admin/routes.py +900 -0
  13. appmanager_server-0.2.0/appmanager/api/__init__.py +5 -0
  14. appmanager_server-0.2.0/appmanager/api/routes.py +373 -0
  15. appmanager_server-0.2.0/appmanager/app_config.py +101 -0
  16. appmanager_server-0.2.0/appmanager/auth/__init__.py +3 -0
  17. appmanager_server-0.2.0/appmanager/auth/oauth.py +77 -0
  18. appmanager_server-0.2.0/appmanager/auth/routes.py +224 -0
  19. appmanager_server-0.2.0/appmanager/auth/utils.py +175 -0
  20. appmanager_server-0.2.0/appmanager/bridge.py +90 -0
  21. appmanager_server-0.2.0/appmanager/cli.py +1171 -0
  22. appmanager_server-0.2.0/appmanager/config.py +58 -0
  23. appmanager_server-0.2.0/appmanager/database.py +120 -0
  24. appmanager_server-0.2.0/appmanager/extension.py +198 -0
  25. appmanager_server-0.2.0/appmanager/extensions.py +225 -0
  26. appmanager_server-0.2.0/appmanager/health.py +133 -0
  27. appmanager_server-0.2.0/appmanager/hooks.py +187 -0
  28. appmanager_server-0.2.0/appmanager/middleware.py +256 -0
  29. appmanager_server-0.2.0/appmanager/models.py +307 -0
  30. appmanager_server-0.2.0/appmanager/py.typed +1 -0
  31. appmanager_server-0.2.0/appmanager/sdk.py +30 -0
  32. appmanager_server-0.2.0/appmanager/security.py +227 -0
  33. appmanager_server-0.2.0/appmanager/security_scanner.py +582 -0
  34. appmanager_server-0.2.0/appmanager/signals.py +21 -0
  35. appmanager_server-0.2.0/appmanager/static/css/app.css +808 -0
  36. appmanager_server-0.2.0/appmanager/static/vendor/fonts/fonts.css +288 -0
  37. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-0.woff2 +0 -0
  38. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-1.woff2 +0 -0
  39. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-10.woff2 +0 -0
  40. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-11.woff2 +0 -0
  41. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-12.woff2 +0 -0
  42. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-13.woff2 +0 -0
  43. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-14.woff2 +0 -0
  44. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-15.woff2 +0 -0
  45. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-16.woff2 +0 -0
  46. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-17.woff2 +0 -0
  47. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-18.woff2 +0 -0
  48. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-19.woff2 +0 -0
  49. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-2.woff2 +0 -0
  50. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-20.woff2 +0 -0
  51. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-21.woff2 +0 -0
  52. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-22.woff2 +0 -0
  53. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-23.woff2 +0 -0
  54. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-3.woff2 +0 -0
  55. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-4.woff2 +0 -0
  56. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-5.woff2 +0 -0
  57. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-6.woff2 +0 -0
  58. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-7.woff2 +0 -0
  59. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-8.woff2 +0 -0
  60. appmanager_server-0.2.0/appmanager/static/vendor/fonts/jetbrainsmono-9.woff2 +0 -0
  61. appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-0.woff2 +0 -0
  62. appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-1.woff2 +0 -0
  63. appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-10.woff2 +0 -0
  64. appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-11.woff2 +0 -0
  65. appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-2.woff2 +0 -0
  66. appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-3.woff2 +0 -0
  67. appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-4.woff2 +0 -0
  68. appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-5.woff2 +0 -0
  69. appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-6.woff2 +0 -0
  70. appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-7.woff2 +0 -0
  71. appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-8.woff2 +0 -0
  72. appmanager_server-0.2.0/appmanager/static/vendor/fonts/spacegrotesk-9.woff2 +0 -0
  73. appmanager_server-0.2.0/appmanager/static/vendor/htmx/htmx.min.js +1 -0
  74. appmanager_server-0.2.0/appmanager/templates/admin/_member_drawer.html +98 -0
  75. appmanager_server-0.2.0/appmanager/templates/admin/_members_table.html +108 -0
  76. appmanager_server-0.2.0/appmanager/templates/admin/app_detail.html +136 -0
  77. appmanager_server-0.2.0/appmanager/templates/admin/dashboard.html +902 -0
  78. appmanager_server-0.2.0/appmanager/templates/admin/flairs.html +90 -0
  79. appmanager_server-0.2.0/appmanager/templates/admin/permissions.html +88 -0
  80. appmanager_server-0.2.0/appmanager/templates/admin/roles.html +119 -0
  81. appmanager_server-0.2.0/appmanager/templates/admin/users.html +156 -0
  82. appmanager_server-0.2.0/appmanager/templates/auth/login.html +58 -0
  83. appmanager_server-0.2.0/appmanager/templates/auth/profile.html +44 -0
  84. appmanager_server-0.2.0/appmanager/templates/base.html +76 -0
  85. appmanager_server-0.2.0/appmanager/templates/errors/401.html +19 -0
  86. appmanager_server-0.2.0/appmanager/templates/errors/403.html +19 -0
  87. appmanager_server-0.2.0/appmanager/templates/errors/404.html +18 -0
  88. appmanager_server-0.2.0/appmanager/templates/errors/500.html +19 -0
  89. appmanager_server-0.2.0/appmanager/templates/index.html +54 -0
  90. appmanager_server-0.2.0/appmanager_server.egg-info/PKG-INFO +320 -0
  91. appmanager_server-0.2.0/appmanager_server.egg-info/SOURCES.txt +120 -0
  92. appmanager_server-0.2.0/appmanager_server.egg-info/dependency_links.txt +1 -0
  93. appmanager_server-0.2.0/appmanager_server.egg-info/entry_points.txt +5 -0
  94. appmanager_server-0.2.0/appmanager_server.egg-info/requires.txt +35 -0
  95. appmanager_server-0.2.0/appmanager_server.egg-info/top_level.txt +1 -0
  96. appmanager_server-0.2.0/pyproject.toml +128 -0
  97. appmanager_server-0.2.0/requirements.txt +9 -0
  98. appmanager_server-0.2.0/setup.cfg +4 -0
  99. appmanager_server-0.2.0/tests/test_api.py +117 -0
  100. appmanager_server-0.2.0/tests/test_app_settings.py +85 -0
  101. appmanager_server-0.2.0/tests/test_app_settings_config.py +77 -0
  102. appmanager_server-0.2.0/tests/test_auth.py +74 -0
  103. appmanager_server-0.2.0/tests/test_cli_dev_and_templates.py +48 -0
  104. appmanager_server-0.2.0/tests/test_cli_health.py +52 -0
  105. appmanager_server-0.2.0/tests/test_cli_scaffolding.py +68 -0
  106. appmanager_server-0.2.0/tests/test_error_pages.py +45 -0
  107. appmanager_server-0.2.0/tests/test_extension_apps.py +122 -0
  108. appmanager_server-0.2.0/tests/test_extension_pattern.py +64 -0
  109. appmanager_server-0.2.0/tests/test_hooks.py +76 -0
  110. appmanager_server-0.2.0/tests/test_installer.py +80 -0
  111. appmanager_server-0.2.0/tests/test_invalid_install_failures.py +209 -0
  112. appmanager_server-0.2.0/tests/test_manifest_sdk.py +136 -0
  113. appmanager_server-0.2.0/tests/test_middleware.py +128 -0
  114. appmanager_server-0.2.0/tests/test_packaging_and_cli.py +77 -0
  115. appmanager_server-0.2.0/tests/test_role_management.py +193 -0
  116. appmanager_server-0.2.0/tests/test_sdk.py +120 -0
  117. appmanager_server-0.2.0/tests/test_security_hardening.py +245 -0
  118. appmanager_server-0.2.0/tests/test_security_precheck_flow.py +238 -0
  119. appmanager_server-0.2.0/tests/test_security_scanner.py +116 -0
  120. appmanager_server-0.2.0/tests/test_signals.py +113 -0
  121. appmanager_server-0.2.0/tests/test_user_elevation_and_visibility.py +237 -0
  122. 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).