Add hybrid app version labels
This commit is contained in:
+6
-1
@@ -1,7 +1,12 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
ARG APP_VERSION=0.1.0
|
||||
ARG APP_BUILD_INFO=dev
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1
|
||||
PYTHONUNBUFFERED=1 \
|
||||
APP_VERSION=${APP_VERSION} \
|
||||
APP_BUILD_INFO=${APP_BUILD_INFO}
|
||||
|
||||
WORKDIR /app/backend
|
||||
|
||||
|
||||
+8
-1
@@ -71,7 +71,13 @@ SMTP_TIMEOUT=30
|
||||
|
||||
# Jellyfin, Jellyseerr, and SSH targets are now configured per machine in the app's Settings tab.
|
||||
# The backend seeds a local machine automatically, so no global Jellyfin or SSH env vars are required.
|
||||
#
|
||||
|
||||
# Versioning
|
||||
# The backend tries to auto-detect its version from installed package metadata.
|
||||
# If needed, you can override the displayed version/build markers with APP_VERSION and APP_BUILD_INFO.
|
||||
APP_VERSION=0.1.0
|
||||
APP_BUILD_INFO=dev
|
||||
|
||||
# Authentik / OIDC
|
||||
AUTH_ENABLED=true
|
||||
OIDC_ISSUER_URL=https://authentik.example/application/o/media-library-viewer/
|
||||
@@ -150,3 +156,4 @@ For local development, `docker compose -f docker-compose.dev.yml up --build` doe
|
||||
- `GET /api/jobs/templates` — Available jobs
|
||||
- `POST /api/jobs/run` — Execute a job
|
||||
- `GET /api/users` — Jellyfin users with optional Jellyseerr enrichment
|
||||
- `GET /api/version` — Backend version/build metadata for the UI
|
||||
|
||||
@@ -14,6 +14,7 @@ from media_library_viewer_api.auth import require_jwt_auth, validate_auth_settin
|
||||
from media_library_viewer_api.config import get_settings
|
||||
from media_library_viewer_api.logging_utils import configure_logging, describe_settings
|
||||
from media_library_viewer_api.routers import dashboard, monitoring, media, files, jobs, users, tasks
|
||||
from .version import get_backend_version, get_version_info
|
||||
from media_library_viewer_api.routers.settings import router as settings_router
|
||||
from media_library_viewer_api.dependencies import get_mail_queue, get_monitoring_poller, get_settings_store
|
||||
from media_library_viewer_api.services.known_hosts import ensure_known_hosts_for_machines
|
||||
@@ -46,7 +47,7 @@ async def lifespan(app: FastAPI):
|
||||
|
||||
app = FastAPI(
|
||||
title="Manage API",
|
||||
version="0.1.0",
|
||||
version=get_backend_version(),
|
||||
description="Manage API for Jellyfin media browsing, SSH file inspection, server monitoring, and JWT-protected access.",
|
||||
lifespan=lifespan,
|
||||
)
|
||||
@@ -67,6 +68,8 @@ app.add_middleware(
|
||||
|
||||
@app.middleware("http")
|
||||
async def enforce_jwt_auth(request: Request, call_next):
|
||||
if request.url.path in {"/api/health", "/api/version"}:
|
||||
return await call_next(request)
|
||||
return await require_jwt_auth(request, call_next)
|
||||
|
||||
@app.middleware("http")
|
||||
@@ -109,5 +112,12 @@ def health_check() -> dict[str, str]:
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
@app.get("/api/version")
|
||||
def version_info() -> dict[str, str]:
|
||||
"""Expose backend version/build metadata for the UI."""
|
||||
logger.debug("version requested")
|
||||
return get_version_info()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
"""Version helpers for the backend service."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from importlib.metadata import PackageNotFoundError, version as package_version
|
||||
|
||||
PACKAGE_NAME = "media-library-viewer-backend"
|
||||
DEFAULT_VERSION = "0.1.0"
|
||||
|
||||
|
||||
def get_backend_version() -> str:
|
||||
"""Return the packaged backend version or a stable fallback."""
|
||||
env_version = os.getenv("APP_VERSION", "").strip()
|
||||
if env_version:
|
||||
return env_version
|
||||
try:
|
||||
return package_version(PACKAGE_NAME)
|
||||
except PackageNotFoundError:
|
||||
return DEFAULT_VERSION
|
||||
|
||||
|
||||
def get_backend_build_info() -> str:
|
||||
"""Return a short build marker such as a git SHA or dev marker."""
|
||||
return (
|
||||
os.getenv("APP_BUILD_INFO", "").strip()
|
||||
or os.getenv("GIT_COMMIT", "").strip()
|
||||
or os.getenv("BUILD_COMMIT", "").strip()
|
||||
or "dev"
|
||||
)
|
||||
|
||||
|
||||
def format_version_label(version: str, build_info: str) -> str:
|
||||
"""Format a user-facing version label."""
|
||||
label = version.strip() or DEFAULT_VERSION
|
||||
build = build_info.strip()
|
||||
if build and build != "dev":
|
||||
return f"{label}+{build}"
|
||||
return label
|
||||
|
||||
|
||||
def get_version_info() -> dict[str, str]:
|
||||
version = get_backend_version()
|
||||
build_info = get_backend_build_info()
|
||||
return {
|
||||
"app": "Manage",
|
||||
"backend_version": version,
|
||||
"backend_build": build_info,
|
||||
"backend_label": format_version_label(version, build_info),
|
||||
}
|
||||
Reference in New Issue
Block a user