feat: seed all flow types (v2, procedural, maintenance) on deploy
Runs seed_trees, seed_trees_v2, seed_procedural_flows, and seed_maintenance_flows sequentially as background tasks when SEED_ON_DEPLOY=true. Each script failure is non-fatal. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -20,8 +20,15 @@ setup_logging()
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _configure_seed_module(mod: object, api_url: str, email: str, password: str) -> None:
|
||||||
|
"""Set globals on a seed script module."""
|
||||||
|
mod.API_BASE_URL = api_url # type: ignore[attr-defined]
|
||||||
|
mod.ADMIN_EMAIL = email # type: ignore[attr-defined]
|
||||||
|
mod.ADMIN_PASSWORD = password # type: ignore[attr-defined]
|
||||||
|
|
||||||
|
|
||||||
async def _seed_trees_background() -> None:
|
async def _seed_trees_background() -> None:
|
||||||
"""Background task: seed trees via HTTP API after server is ready."""
|
"""Background task: seed all flows via HTTP API after server is ready."""
|
||||||
await asyncio.sleep(5) # Wait for server to be fully ready
|
await asyncio.sleep(5) # Wait for server to be fully ready
|
||||||
port = os.environ.get("PORT", "8000")
|
port = os.environ.get("PORT", "8000")
|
||||||
api_url = f"http://127.0.0.1:{port}/api/v1"
|
api_url = f"http://127.0.0.1:{port}/api/v1"
|
||||||
@@ -30,30 +37,43 @@ async def _seed_trees_background() -> None:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
import httpx
|
import httpx
|
||||||
# Login to get token
|
# Login to verify admin user exists
|
||||||
async with httpx.AsyncClient(base_url=api_url, timeout=30) as client:
|
async with httpx.AsyncClient(base_url=api_url, timeout=30) as client:
|
||||||
login_resp = await client.post("/auth/login/json", json={"email": email, "password": password})
|
login_resp = await client.post("/auth/login/json", json={"email": email, "password": password})
|
||||||
if login_resp.status_code != 200:
|
if login_resp.status_code != 200:
|
||||||
logger.warning("[seed] Could not login as admin — skipping tree seeding")
|
logger.warning("[seed] Could not login as admin — skipping flow seeding")
|
||||||
return
|
return
|
||||||
|
|
||||||
token = login_resp.json()["access_token"]
|
token = login_resp.json()["access_token"]
|
||||||
# Check if trees already exist
|
# Check if trees already exist
|
||||||
trees_resp = await client.get("/trees", headers={"Authorization": f"Bearer {token}"})
|
trees_resp = await client.get("/trees", headers={"Authorization": f"Bearer {token}"})
|
||||||
if trees_resp.status_code == 200 and len(trees_resp.json()) > 0:
|
if trees_resp.status_code == 200 and len(trees_resp.json()) > 0:
|
||||||
logger.info(f"[seed] {len(trees_resp.json())} trees already exist — skipping tree seeding")
|
logger.info(f"[seed] {len(trees_resp.json())} flows already exist — skipping flow seeding")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Trees don't exist yet — run the full seed script
|
# No flows yet — run all seed scripts
|
||||||
logger.info("[seed] No trees found — running seed_trees...")
|
seed_scripts = [
|
||||||
import scripts.seed_trees as seed_trees_mod
|
("seed_trees (Tier 1)", "scripts.seed_trees", "seed_database"),
|
||||||
seed_trees_mod.API_BASE_URL = api_url
|
("seed_trees_v2 (AD/M365/Networking)", "scripts.seed_trees_v2", "seed_database"),
|
||||||
seed_trees_mod.ADMIN_EMAIL = email
|
("seed_procedural_flows", "scripts.seed_procedural_flows", "seed_procedural_flows"),
|
||||||
seed_trees_mod.ADMIN_PASSWORD = password
|
("seed_maintenance_flows", "scripts.seed_maintenance_flows", "seed_maintenance_flows"),
|
||||||
await seed_trees_mod.seed_database()
|
]
|
||||||
logger.info("[seed] Tree seeding complete!")
|
|
||||||
|
for label, module_path, func_name in seed_scripts:
|
||||||
|
try:
|
||||||
|
import importlib
|
||||||
|
mod = importlib.import_module(module_path)
|
||||||
|
_configure_seed_module(mod, api_url, email, password)
|
||||||
|
seed_fn = getattr(mod, func_name)
|
||||||
|
logger.info(f"[seed] Running {label}...")
|
||||||
|
await seed_fn()
|
||||||
|
logger.info(f"[seed] {label} complete!")
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"[seed] {label} failed (non-fatal): {e}")
|
||||||
|
|
||||||
|
logger.info("[seed] All flow seeding complete!")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"[seed] Tree seeding failed (non-fatal): {e}")
|
logger.warning(f"[seed] Flow seeding failed (non-fatal): {e}")
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
|
|||||||
Reference in New Issue
Block a user