"""Launch the demo tier locally: FastAPI (uvicorn) + Streamlit together. Used by `make demo` and mirrors what the Docker image does. The API owns the embedded Qdrant; the UI (this same launcher) talks to it over HTTP. python app/dev.py """ from __future__ import annotations import os import subprocess import sys import time from pathlib import Path APP_DIR = Path(__file__).resolve().parent PORT_API = os.getenv("API_PORT", "8000") PORT_UI = os.getenv("UI_PORT", "8501") def main() -> None: env = dict(os.environ, APP_API_URL=f"http://localhost:{PORT_API}") api = subprocess.Popen( [sys.executable, "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", PORT_API], cwd=str(APP_DIR), env=env, ) time.sleep(2) # let the API bind before the UI starts polling /health try: subprocess.run( [sys.executable, "-m", "streamlit", "run", "ui.py", "--server.port", PORT_UI, "--server.address", "0.0.0.0"], cwd=str(APP_DIR), env=env, check=False, ) finally: api.terminate() if __name__ == "__main__": main()