Files
home-automation/UI_API_CONFIG.md

4.3 KiB

UI API Configuration

Übersicht

Die UI-Anwendung verwendet keine hart codierten API-URLs mehr. Stattdessen wird die API-Basis-URL über die Umgebungsvariable API_BASE konfiguriert.

Konfiguration

Umgebungsvariable

  • Name: API_BASE

  • Standard: http://localhost:8001

  • Beispiele:

    • Lokal: http://localhost:8001
    • Docker: http://api:8001
    • Kubernetes: http://api-service:8001
  • Name: BASE_PATH

  • Standard: "" (leer)

  • Beschreibung: Pfad-Präfix für Reverse Proxy (z.B. /ui)

  • Beispiele:

    • Ohne Proxy: "" (leer)
    • Hinter Proxy: /ui
    • Traefik/nginx: /home-automation

Startup-Ausgabe

Beim Start zeigt die UI die verwendete API-URL an:

UI using API_BASE: http://localhost:8001

API-Funktionen

api_url(path: str) -> str

Hilfsfunktion zum Erstellen vollständiger API-URLs:

from apps.ui.main import api_url

# Beispiel
url = api_url("/devices")  # → "http://localhost:8001/devices"

Health Endpoint

Für Kubernetes Liveness/Readiness Probes:

GET /health

Antwort:

{
  "status": "ok",
  "service": "ui",
  "api_base": "http://localhost:8001"
}

Verwendung

Lokal (Entwicklung)

# Standard (verwendet http://localhost:8001)
poetry run uvicorn apps.ui.main:app --host 0.0.0.0 --port 8002

# Mit anderer API
API_BASE=http://192.168.1.100:8001 poetry run uvicorn apps.ui.main:app --port 8002

# Mit BASE_PATH (Reverse Proxy)
BASE_PATH=/ui poetry run uvicorn apps.ui.main:app --port 8002
# Zugriff: http://localhost:8002/ui/

Docker Compose

services:
  ui:
    build: .
    ports:
      - "8002:8002"
    environment:
      - API_BASE=http://api:8001
      - BASE_PATH=""  # Leer für direkten Zugriff
    depends_on:
      - api

Docker Compose mit Reverse Proxy

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
  
  ui:
    build: .
    environment:
      - API_BASE=http://api:8001
      - BASE_PATH=/ui  # Pfad-Präfix für nginx
    expose:
      - "8002"

Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ui
spec:
  replicas: 2
  selector:
    matchLabels:
      app: ui
  template:
    metadata:
      labels:
        app: ui
    spec:
      containers:
      - name: ui
        image: home-automation-ui:latest
        env:
          - name: API_BASE
            value: "http://api-service:8001"
          - name: BASE_PATH
            value: "/ui"  # Für Ingress
        ports:
          - containerPort: 8002
        livenessProbe:
          httpGet:
            path: /ui/health  # Mit BASE_PATH!
            port: 8002
          initialDelaySeconds: 5
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ui/health  # Mit BASE_PATH!
            port: 8002
          initialDelaySeconds: 5
          periodSeconds: 5
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "500m"
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ui-ingress
spec:
  rules:
  - host: home.example.com
    http:
      paths:
      - path: /ui
        pathType: Prefix
        backend:
          service:
            name: ui-service
            port:
              number: 8002

Geänderte Dateien

  1. apps/ui/main.py

    • API_BASE aus Umgebung lesen
    • api_url() Hilfsfunktion
    • /health Endpoint
    • API_BASE an Template übergeben
  2. apps/ui/api_client.py

    • fetch_devices(api_base) benötigt Parameter
    • fetch_layout(api_base) benötigt Parameter
  3. apps/ui/templates/dashboard.html

    • JavaScript verwendet {{ api_base }} aus Backend

Akzeptanz-Kriterien ✓

  • print(API_BASE) zeigt korrekten Wert beim Start
  • UI funktioniert lokal ohne Codeänderung
  • Mit API_BASE=http://api:8001 ruft UI korrekt den API-Service an
  • Health-Endpoint für Kubernetes verfügbar
  • Keine hart codierten URLs mehr

Vorteile

  1. Flexibilität: API-URL per ENV konfigurierbar
  2. Docker/K8s Ready: Service Discovery unterstützt
  3. Health Checks: Monitoring-Integration möglich
  4. Abwärtskompatibel: Bestehende Deployments funktionieren weiter
  5. Clean Code: Zentrale Konfiguration statt verteilte Hardcodes