From 7daf604a3298977763dd591f6d36a418b2ff9870 Mon Sep 17 00:00:00 2001 From: airano Date: Wed, 18 Feb 2026 02:41:28 +0330 Subject: [PATCH] fix(packaging): move templates into core/ for PyPI distribution Templates were at project root (templates/) which is outside the Python package, so `pip install mcphub-server` would not include them. Moved to core/templates/ and updated path references in server.py and core/dashboard/routes.py. Also added py-modules for server.py and server_multi.py to pyproject.toml. Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 4 ++-- core/dashboard/routes.py | 6 ++---- {templates => core/templates}/base.html | 0 .../templates}/dashboard/api-keys/list.html | 0 .../templates}/dashboard/audit-logs/list.html | 0 {templates => core/templates}/dashboard/base.html | 0 .../templates}/dashboard/health/index.html | 0 .../templates}/dashboard/health/projects-partial.html | 0 {templates => core/templates}/dashboard/index.html | 0 {templates => core/templates}/dashboard/login.html | 0 .../templates}/dashboard/oauth-clients/list.html | 0 .../templates}/dashboard/projects/detail.html | 0 .../templates}/dashboard/projects/list.html | 0 .../templates}/dashboard/settings/index.html | 0 {templates => core/templates}/oauth/authorize.html | 0 {templates => core/templates}/oauth/error.html | 2 +- pyproject.toml | 4 ++++ server.py | 9 +++++++-- 18 files changed, 16 insertions(+), 9 deletions(-) rename {templates => core/templates}/base.html (100%) rename {templates => core/templates}/dashboard/api-keys/list.html (100%) rename {templates => core/templates}/dashboard/audit-logs/list.html (100%) rename {templates => core/templates}/dashboard/base.html (100%) rename {templates => core/templates}/dashboard/health/index.html (100%) rename {templates => core/templates}/dashboard/health/projects-partial.html (100%) rename {templates => core/templates}/dashboard/index.html (100%) rename {templates => core/templates}/dashboard/login.html (100%) rename {templates => core/templates}/dashboard/oauth-clients/list.html (100%) rename {templates => core/templates}/dashboard/projects/detail.html (100%) rename {templates => core/templates}/dashboard/projects/list.html (100%) rename {templates => core/templates}/dashboard/settings/index.html (100%) rename {templates => core/templates}/oauth/authorize.html (100%) rename {templates => core/templates}/oauth/error.html (96%) diff --git a/CLAUDE.md b/CLAUDE.md index e1a59aa..d1b7dc2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -72,7 +72,7 @@ All configured in `pyproject.toml`: ├── server_multi.py # Alternative multi-endpoint server ├── core/ # Layer 1: Core system modules ├── plugins/ # Layer 2: Plugin system (9 plugins) -├── templates/ # Jinja2 templates (dashboard + OAuth) +├── core/templates/ # Jinja2 templates (dashboard + OAuth) ├── tests/ # Organized test suite ├── scripts/ # Setup & deployment scripts ├── wordpress-plugin/ # Companion WP plugins (PHP) @@ -181,7 +181,7 @@ Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore` - `server_multi.py` is the alternative multi-endpoint entry point; `server.py` is the primary - `wordpress-plugin/` contains companion WP plugins (openpanel, seo-api-bridge) — these are PHP, not Python - `env.example` has "FUTURE" labels for Supabase/Gitea but both are fully implemented -- Dashboard templates live in `templates/` (not inside `core/dashboard/`) +- Dashboard templates live in `core/templates/` (included in pip package as `package_data`) - `ruff` config uses top-level `select` key in pyproject.toml (not `[tool.ruff.lint]` nested format) - The `scripts/` directory has platform-specific setup scripts: `setup.sh` (Linux/Mac), `setup.ps1` (Windows) diff --git a/core/dashboard/routes.py b/core/dashboard/routes.py index 780bc34..90e85d1 100644 --- a/core/dashboard/routes.py +++ b/core/dashboard/routes.py @@ -16,10 +16,8 @@ from .auth import get_dashboard_auth logger = logging.getLogger(__name__) -# Templates directory -TEMPLATES_DIR = os.path.join( - os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "templates" -) +# Templates directory (core/templates/ — one level up from core/dashboard/) +TEMPLATES_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "templates") templates = Jinja2Templates(directory=TEMPLATES_DIR) # Plugin display names mapping (for special cases like n8n) diff --git a/templates/base.html b/core/templates/base.html similarity index 100% rename from templates/base.html rename to core/templates/base.html diff --git a/templates/dashboard/api-keys/list.html b/core/templates/dashboard/api-keys/list.html similarity index 100% rename from templates/dashboard/api-keys/list.html rename to core/templates/dashboard/api-keys/list.html diff --git a/templates/dashboard/audit-logs/list.html b/core/templates/dashboard/audit-logs/list.html similarity index 100% rename from templates/dashboard/audit-logs/list.html rename to core/templates/dashboard/audit-logs/list.html diff --git a/templates/dashboard/base.html b/core/templates/dashboard/base.html similarity index 100% rename from templates/dashboard/base.html rename to core/templates/dashboard/base.html diff --git a/templates/dashboard/health/index.html b/core/templates/dashboard/health/index.html similarity index 100% rename from templates/dashboard/health/index.html rename to core/templates/dashboard/health/index.html diff --git a/templates/dashboard/health/projects-partial.html b/core/templates/dashboard/health/projects-partial.html similarity index 100% rename from templates/dashboard/health/projects-partial.html rename to core/templates/dashboard/health/projects-partial.html diff --git a/templates/dashboard/index.html b/core/templates/dashboard/index.html similarity index 100% rename from templates/dashboard/index.html rename to core/templates/dashboard/index.html diff --git a/templates/dashboard/login.html b/core/templates/dashboard/login.html similarity index 100% rename from templates/dashboard/login.html rename to core/templates/dashboard/login.html diff --git a/templates/dashboard/oauth-clients/list.html b/core/templates/dashboard/oauth-clients/list.html similarity index 100% rename from templates/dashboard/oauth-clients/list.html rename to core/templates/dashboard/oauth-clients/list.html diff --git a/templates/dashboard/projects/detail.html b/core/templates/dashboard/projects/detail.html similarity index 100% rename from templates/dashboard/projects/detail.html rename to core/templates/dashboard/projects/detail.html diff --git a/templates/dashboard/projects/list.html b/core/templates/dashboard/projects/list.html similarity index 100% rename from templates/dashboard/projects/list.html rename to core/templates/dashboard/projects/list.html diff --git a/templates/dashboard/settings/index.html b/core/templates/dashboard/settings/index.html similarity index 100% rename from templates/dashboard/settings/index.html rename to core/templates/dashboard/settings/index.html diff --git a/templates/oauth/authorize.html b/core/templates/oauth/authorize.html similarity index 100% rename from templates/oauth/authorize.html rename to core/templates/oauth/authorize.html diff --git a/templates/oauth/error.html b/core/templates/oauth/error.html similarity index 96% rename from templates/oauth/error.html rename to core/templates/oauth/error.html index 8082fdb..4968441 100644 --- a/templates/oauth/error.html +++ b/core/templates/oauth/error.html @@ -79,7 +79,7 @@ diff --git a/pyproject.toml b/pyproject.toml index ffe749f..3e35376 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,11 +66,15 @@ Changelog = "https://github.com/airano-ir/mcphub/releases" requires = ["setuptools>=68.0", "wheel"] build-backend = "setuptools.build_meta" +[tool.setuptools] +py-modules = ["server", "server_multi"] + [tool.setuptools.packages.find] include = ["core*", "plugins*"] exclude = ["tests*", "data*", "logs*", "temp*", "scripts*", "docs*"] [tool.setuptools.package-data] +"core" = ["templates/**/*.html"] "*" = ["*.html", "*.css", "*.js", "*.json"] # ==================================== diff --git a/server.py b/server.py index 092828c..5cd20b4 100644 --- a/server.py +++ b/server.py @@ -230,8 +230,13 @@ if OAUTH_AUTH_MODE == "trusted_domains": # Initialize MCP server mcp = FastMCP("MCP Hub") -# Initialize Jinja2 templates (Phase E - OAuth Authorization Page) -templates = Jinja2Templates(directory="templates") +# Initialize Jinja2 templates +# Templates live in core/templates/ (included in pip package as package_data) +_TEMPLATES_DIR = os.path.join(os.path.dirname(__file__), "core", "templates") +if not os.path.isdir(_TEMPLATES_DIR): + # Fallback for pip-installed package: resolve relative to core package + _TEMPLATES_DIR = os.path.join(os.path.dirname(os.path.abspath(core.__file__)), "templates") +templates = Jinja2Templates(directory=_TEMPLATES_DIR) logger.info("Jinja2 template engine initialized") # Initialize managers