206 lines
5.9 KiB
PowerShell
206 lines
5.9 KiB
PowerShell
<#
|
||
AZA – Step 12 Fix: Start LOCAL backend with tokens from deploy\.env (no manual edits)
|
||
|
||
What it does:
|
||
- Loads deploy\.env
|
||
- Sets process env: MEDWORK_API_TOKENS / MEDWORK_API_TOKEN (as present in .env)
|
||
- Attempts to start uvicorn with common app module paths:
|
||
1) app:app
|
||
2) backend.main:app
|
||
3) main:app
|
||
- Binds to 127.0.0.1:8000
|
||
|
||
Run from project root:
|
||
powershell -ExecutionPolicy Bypass -File .\deploy\run_backend_local_with_env.ps1
|
||
|
||
Then re-run authorized test:
|
||
cd .\deploy
|
||
powershell -ExecutionPolicy Bypass -File .\authorized_test.ps1
|
||
#>
|
||
|
||
[CmdletBinding()]
|
||
param(
|
||
[string]$EnvFile = ".\deploy\.env",
|
||
[string]$BindHost = "127.0.0.1",
|
||
[int]$Port = 8000
|
||
)
|
||
|
||
function Load-DotEnv([string]$Path) {
|
||
if (-not (Test-Path -LiteralPath $Path)) {
|
||
throw "Missing .env file at: $Path"
|
||
}
|
||
$map = @{}
|
||
Get-Content -LiteralPath $Path | ForEach-Object {
|
||
$line = $_.Trim()
|
||
if ($line.Length -eq 0) { return }
|
||
if ($line.StartsWith("#")) { return }
|
||
$idx = $line.IndexOf("=")
|
||
if ($idx -lt 1) { return }
|
||
$k = $line.Substring(0, $idx).Trim()
|
||
$v = $line.Substring($idx + 1).Trim()
|
||
if (($v.StartsWith('"') -and $v.EndsWith('"')) -or ($v.StartsWith("'") -and $v.EndsWith("'"))) {
|
||
$v = $v.Substring(1, $v.Length - 2)
|
||
}
|
||
$map[$k] = $v
|
||
}
|
||
return $map
|
||
}
|
||
|
||
Write-Host "[AZA] Start local backend with env from $EnvFile"
|
||
|
||
try {
|
||
$envMap = Load-DotEnv $EnvFile
|
||
} catch {
|
||
Write-Host "❌ $($_.Exception.Message)"
|
||
exit 1
|
||
}
|
||
|
||
if ($envMap.ContainsKey("MEDWORK_API_TOKENS")) {
|
||
$env:MEDWORK_API_TOKENS = $envMap["MEDWORK_API_TOKENS"]
|
||
Write-Host " MEDWORK_API_TOKENS: set"
|
||
} elseif ($envMap.ContainsKey("MEDWORK_API_TOKEN")) {
|
||
$env:MEDWORK_API_TOKEN = $envMap["MEDWORK_API_TOKEN"]
|
||
Write-Host " MEDWORK_API_TOKEN: set"
|
||
} else {
|
||
Write-Host "❌ No MEDWORK_API_TOKENS or MEDWORK_API_TOKEN found in $EnvFile"
|
||
exit 1
|
||
}
|
||
|
||
# AZA secret key requirement:
|
||
# Prefer AZA_SECRET_KEY from .env; otherwise enable dev-mode auto-generated key.
|
||
if ($envMap.ContainsKey("AZA_SECRET_KEY") -and $envMap["AZA_SECRET_KEY"].Trim().Length -ge 32) {
|
||
$env:AZA_SECRET_KEY = $envMap["AZA_SECRET_KEY"]
|
||
Write-Host " AZA_SECRET_KEY: set (from .env)"
|
||
} else {
|
||
$env:AZA_ENV = "dev"
|
||
Write-Host " AZA_ENV: dev (AZA_SECRET_KEY not present/too short in .env)"
|
||
}
|
||
|
||
# Optional: keep build leak-free if your backend uses AZA_BUILD
|
||
if ($envMap.ContainsKey("AZA_BUILD")) {
|
||
$env:AZA_BUILD = $envMap["AZA_BUILD"]
|
||
}
|
||
|
||
Write-Host " Binding: http://$BindHost`:$Port"
|
||
Write-Host ""
|
||
|
||
$preferredTarget = "workforce_planner.api.app:app"
|
||
$candidates = @($preferredTarget, "app:app", "backend.main:app", "main:app")
|
||
|
||
function Try-Start([string]$target) {
|
||
Write-Host "Trying: uvicorn $target --host $BindHost --port $Port"
|
||
# Use python -m uvicorn to avoid PATH issues
|
||
& python -m uvicorn $target --host $BindHost --port $Port
|
||
if ($LASTEXITCODE -eq 0) { return $true }
|
||
return $false
|
||
}
|
||
|
||
Write-Host "NOTE: This will run the server in the foreground. Leave this window open while testing."
|
||
Write-Host ""
|
||
|
||
function Try-StartFile([string]$filePath) {
|
||
Write-Host "Trying: python $filePath"
|
||
& python $filePath
|
||
if ($LASTEXITCODE -eq 0) { return $true }
|
||
return $false
|
||
}
|
||
|
||
function To-ModulePath([string]$filePath) {
|
||
$p = $filePath.Replace("\", "/")
|
||
if ($p.StartsWith("./")) { $p = $p.Substring(2) }
|
||
if ($p.EndsWith(".py")) { $p = $p.Substring(0, $p.Length - 3) }
|
||
return ($p -replace "/", ".")
|
||
}
|
||
|
||
function Repo-FastApiCandidates {
|
||
$paths = @(
|
||
"main.py",
|
||
"backend\main.py",
|
||
"backend\app.py",
|
||
"server.py",
|
||
"api.py",
|
||
"asgi.py",
|
||
"app.py",
|
||
"app\main.py",
|
||
"src\main.py",
|
||
"src\backend\main.py",
|
||
"aza_backend\main.py",
|
||
"aza\main.py"
|
||
)
|
||
$found = @()
|
||
foreach ($p in $paths) {
|
||
if (Test-Path -LiteralPath $p) { $found += $p }
|
||
}
|
||
# If nothing found, do a shallow-ish search (PS5.1 compatible) for common entry filenames
|
||
if ($found.Count -eq 0) {
|
||
$filters = @("main.py","app.py","server.py","api.py","asgi.py")
|
||
try {
|
||
$root = (Resolve-Path .).Path
|
||
$all = Get-ChildItem -Path . -Recurse -File -ErrorAction SilentlyContinue |
|
||
Where-Object { $filters -contains $_.Name }
|
||
|
||
foreach ($fi in $all) {
|
||
# approximate depth by counting separators in relative path
|
||
$rel = Resolve-Path $fi.FullName -Relative
|
||
$sepCount = ($rel.ToString().Split(@("\","/")) | Where-Object { $_ -ne "." -and $_ -ne "" }).Count - 1
|
||
if ($sepCount -le 3) {
|
||
$found += $rel
|
||
}
|
||
}
|
||
} catch { }
|
||
}
|
||
# de-dup
|
||
return ($found | Select-Object -Unique)
|
||
}
|
||
|
||
# 1) Try preferred known target first (your repo)
|
||
Write-Host "Preferred target: $preferredTarget"
|
||
Write-Host ""
|
||
|
||
foreach ($t in $candidates) {
|
||
$ok = Try-Start $t
|
||
if ($ok) { exit 0 }
|
||
Write-Host " (failed) $t"
|
||
Write-Host ""
|
||
}
|
||
|
||
# 2) Try repo-discovered file candidates
|
||
$files = Repo-FastApiCandidates
|
||
Write-Host "Discovered candidate backend files: $($files.Count)"
|
||
if ($files.Count -gt 0) {
|
||
$files | ForEach-Object { Write-Host " - $_" }
|
||
} else {
|
||
Write-Host " (none found within ~3 levels for: main.py/app.py/server.py/api.py/asgi.py)"
|
||
}
|
||
Write-Host ""
|
||
|
||
if ($files.Count -gt 0) {
|
||
foreach ($f in $files) {
|
||
# First: try running the file directly (in case it self-starts uvicorn)
|
||
$okFile = Try-StartFile $f
|
||
if ($okFile) { exit 0 }
|
||
Write-Host " (failed) python $f"
|
||
Write-Host ""
|
||
|
||
# Second: try uvicorn with module:app
|
||
$mod = To-ModulePath $f
|
||
$target = "$mod`:app"
|
||
$ok = Try-Start $target
|
||
if ($ok) { exit 0 }
|
||
Write-Host " (failed) $target"
|
||
Write-Host ""
|
||
}
|
||
}
|
||
|
||
Write-Host "FAIL Could not start uvicorn with known module targets."
|
||
Write-Host "Checked module candidates:"
|
||
$candidates | ForEach-Object { Write-Host " - $_" }
|
||
if ($files -and $files.Count -gt 0) {
|
||
Write-Host "Checked discovered files:"
|
||
$files | ForEach-Object { Write-Host " - $_" }
|
||
}
|
||
Write-Host ""
|
||
Write-Host "Next patch will hard-wire the correct module path once you paste the existing local start command/log line."
|
||
exit 1
|
||
|