67 lines
2.0 KiB
Python
67 lines
2.0 KiB
Python
"""Run the build API with Uvicorn."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
import uvicorn
|
|
|
|
from .app import create_application
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
|
|
|
|
def _load_env_file(path: Path) -> None:
|
|
"""Load KEY=VALUE lines into os.environ.
|
|
|
|
Existing non-empty process env wins. Empty/missing keys are filled from the
|
|
file so panel "load from file" stubs cannot block a real project .env.
|
|
"""
|
|
if not path.is_file():
|
|
return
|
|
for raw in path.read_text(encoding="utf-8").splitlines():
|
|
line = raw.strip()
|
|
if not line or line.startswith("#"):
|
|
continue
|
|
if line.startswith("export "):
|
|
line = line[7:].strip()
|
|
if "=" not in line:
|
|
continue
|
|
key, _, value = line.partition("=")
|
|
key = key.strip()
|
|
if not key:
|
|
continue
|
|
value = value.strip()
|
|
if len(value) >= 2 and value[0] == value[-1] and value[0] in {'"', "'"}:
|
|
value = value[1:-1]
|
|
current = os.environ.get(key)
|
|
if current is not None and current.strip():
|
|
continue
|
|
os.environ[key] = value
|
|
|
|
|
|
def main() -> None:
|
|
# Always read project .env; also honor an explicit path from the panel.
|
|
_load_env_file(REPO_ROOT / ".env")
|
|
env_file = os.environ.get("BUILD_API_ENV_FILE", "").strip()
|
|
if env_file:
|
|
_load_env_file(Path(env_file))
|
|
|
|
token = os.environ.get("BUILD_API_TOKEN", "").strip()
|
|
if not token:
|
|
raise SystemExit(
|
|
"BUILD_API_TOKEN is missing or empty. "
|
|
f"Put it in {REPO_ROOT / '.env'} (KEY=value, no spaces around =)."
|
|
)
|
|
|
|
host = os.environ.get("BUILD_API_HOST", "127.0.0.1")
|
|
port = int(os.environ.get("BUILD_API_PORT", "8081"))
|
|
application = create_application()
|
|
print(f"build API listening on http://{host}:{port}", flush=True)
|
|
uvicorn.run(application, host=host, port=port, log_level="info")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|