#!/bin/sh set -eu # ------------------------------------------------------------ # 0) Load env file shipped with repo (backend/env) # ------------------------------------------------------------ ENV_FILE="/app/backend/env" if [ -f "$ENV_FILE" ]; then echo "[BOOT] Loading env from $ENV_FILE" set -a . "$ENV_FILE" echo "[CHECK] SMTP_HOST set? ${SMTP_HOST:+yes}" echo "[CHECK] SMTP_PORT set? ${SMTP_PORT:+yes}" echo "[CHECK] SMTP_USER set? ${SMTP_USER:+yes}" echo "[CHECK] SMTP_PASS set? ${SMTP_PASS:+yes}" set +a else echo "[BOOT] No env file at $ENV_FILE (continuing without it)" fi DATA_ROOT="/app/inference-data" ERA5_SUBDIR="ERA5_Germany" ERA5_PATH="$DATA_ROOT/$ERA5_SUBDIR" MODEL_ROOT="/app/model-artifacts" # ------------------------------------------------------------ # 1) ERA5 Dataset laden (nur wenn fehlt/leer) # ------------------------------------------------------------ if [ ! -d "$ERA5_PATH" ] || [ -z "$(ls -A "$ERA5_PATH" 2>/dev/null)" ]; then echo "[BOOT] Downloading dataset dspunituebingen/era5 -> $DATA_ROOT (ERA5_Germany/**)" python - <<'PY' import os from huggingface_hub import snapshot_download token = os.getenv("HF_TOKEN") or os.getenv("HUGGINGFACEHUB_API_TOKEN") snapshot_download( repo_id="dspunituebingen/era5", repo_type="dataset", local_dir="/app/inference-data", allow_patterns=["ERA5_Germany/**"], token=token, ) print("[BOOT] ERA5 ready at /app/inference-data/ERA5_Germany") PY fi # ------------------------------------------------------------ # 2) Modell-Repo laden (nur wenn fehlt/leer) # ------------------------------------------------------------ if [ ! -d "$MODEL_ROOT" ] || [ -z "$(ls -A "$MODEL_ROOT" 2>/dev/null)" ]; then echo "[BOOT] Downloading model dspunituebingen/windproject-model -> $MODEL_ROOT" python - <<'PY' import os from huggingface_hub import snapshot_download token = os.getenv("HF_TOKEN") or os.getenv("HUGGINGFACEHUB_API_TOKEN") snapshot_download( repo_id="dspunituebingen/windproject-model", repo_type="model", local_dir="/app/model-artifacts", token=token, ) print("[BOOT] Model ready at /app/model-artifacts") PY fi # ------------------------------------------------------------ # 3) Env Vars für backend/app/main.py # ------------------------------------------------------------ export APP_ENV="server" export SERVER_HOST="0.0.0.0" export SERVER_PORT="${PORT:-7860}" export ERA5_DIR="$ERA5_PATH" export FORECAST_MODEL_DIR="$MODEL_ROOT" # Kompatibilitäts-Aliase (falls andere Module das erwarten) export MODEL_DIR="$MODEL_ROOT" # Turbine curves (liegen im Repo) if [ -f "/app/backend/wind-power-climate-ml/data/turbine_power_curves.json" ]; then export TURBINE_CURVES_JSON="/app/backend/wind-power-climate-ml/data/turbine_power_curves.json" elif [ -f "/app/backend/wind-power-climate-ml/Data/turbine_power_curves.json" ]; then export TURBINE_CURVES_JSON="/app/backend/wind-power-climate-ml/Data/turbine_power_curves.json" else echo "[FATAL] turbine_power_curves.json not found in expected repo paths." exit 1 fi echo "[CONFIG] ERA5_DIR=$ERA5_DIR" echo "[CONFIG] FORECAST_MODEL_DIR=$FORECAST_MODEL_DIR" echo "[CONFIG] TURBINE_CURVES_JSON=$TURBINE_CURVES_JSON" # ------------------------------------------------------------ # 4) Start Uvicorn (robust: import app.main) # ------------------------------------------------------------ export PYTHONPATH="/app/backend:/app/backend/model:/app/backend/wind-power-climate-ml/src:${PYTHONPATH:-}" echo "[CHECK] /app/backend/app listing:" ls -lah /app/backend/app || true python - <<'PY' import importlib, traceback try: m = importlib.import_module("app.main") print("[BOOT] app.main imported OK. Has app?", hasattr(m, "app")) print("[BOOT] app =", getattr(m, "app", None)) except Exception: print("[FATAL] Import of app.main failed. Full traceback:") traceback.print_exc() raise SystemExit(1) PY # Uvicorn: lade app.main:app (entspricht /app/backend/app/main.py) exec python -m uvicorn app.main:app --host 0.0.0.0 --port "${PORT:-7860}" --log-level info