Add standalone FastAPI server backend (Phase 3)
Some checks failed
Validate / Hassfest (push) Has been cancelled
Some checks failed
Validate / Hassfest (push) Has been cancelled
Build a complete standalone web server for Immich album change notifications, independent of Home Assistant. Uses the shared core library from Phase 1. Server features: - FastAPI with async SQLite (SQLModel + aiosqlite) - Multi-user auth with JWT (admin/user roles, setup wizard) - CRUD APIs: Immich servers, album trackers, message templates, notification targets (Telegram + webhook), user management - APScheduler background polling per tracker - Jinja2 template rendering with live preview - Album browser proxied from Immich API - Event logging and dashboard status endpoint - Docker deployment (single container, SQLite in volume) 39 API routes, 14 integration tests passing. Also adds Phase 6 (Claude AI Telegram bot enhancement) to the primary plan as an optional future phase. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
94
packages/server/src/immich_watcher_server/main.py
Normal file
94
packages/server/src/immich_watcher_server/main.py
Normal file
@@ -0,0 +1,94 @@
|
||||
"""FastAPI application entry point."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from contextlib import asynccontextmanager
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
from .config import settings
|
||||
from .database.engine import init_db
|
||||
from .services.scheduler import start_scheduler, stop_scheduler
|
||||
|
||||
from .auth.routes import router as auth_router
|
||||
from .api.servers import router as servers_router
|
||||
from .api.trackers import router as trackers_router
|
||||
from .api.templates import router as templates_router
|
||||
from .api.targets import router as targets_router
|
||||
from .api.users import router as users_router
|
||||
from .api.status import router as status_router
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG if settings.debug else logging.INFO,
|
||||
format="%(asctime)s %(levelname)s [%(name)s] %(message)s",
|
||||
)
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
"""Application lifespan: startup and shutdown."""
|
||||
# Startup
|
||||
settings.data_dir.mkdir(parents=True, exist_ok=True)
|
||||
await init_db()
|
||||
_LOGGER.info("Database initialized at %s", settings.effective_database_url)
|
||||
|
||||
await start_scheduler()
|
||||
|
||||
yield
|
||||
|
||||
# Shutdown
|
||||
await stop_scheduler()
|
||||
|
||||
|
||||
app = FastAPI(
|
||||
title="Immich Watcher",
|
||||
description="Standalone Immich album change notification server",
|
||||
version="0.1.0",
|
||||
lifespan=lifespan,
|
||||
)
|
||||
|
||||
# CORS for frontend dev server
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"],
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
# API routes
|
||||
app.include_router(auth_router)
|
||||
app.include_router(servers_router)
|
||||
app.include_router(trackers_router)
|
||||
app.include_router(templates_router)
|
||||
app.include_router(targets_router)
|
||||
app.include_router(users_router)
|
||||
app.include_router(status_router)
|
||||
|
||||
# Serve frontend static files if available
|
||||
_frontend_dist = Path(__file__).parent / "frontend"
|
||||
if _frontend_dist.is_dir():
|
||||
app.mount("/", StaticFiles(directory=_frontend_dist, html=True), name="frontend")
|
||||
|
||||
|
||||
@app.get("/api/health")
|
||||
async def health():
|
||||
"""Health check endpoint."""
|
||||
return {"status": "ok", "version": "0.1.0"}
|
||||
|
||||
|
||||
def run():
|
||||
"""Run the server (entry point for `immich-watcher` CLI command)."""
|
||||
import uvicorn
|
||||
|
||||
uvicorn.run(
|
||||
"immich_watcher_server.main:app",
|
||||
host=settings.host,
|
||||
port=settings.port,
|
||||
reload=settings.debug,
|
||||
)
|
||||
Reference in New Issue
Block a user