Spaces:
Sleeping
Sleeping
File size: 3,688 Bytes
75123b0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | """Own all development child processes, including npm and uvicorn descendants."""
import argparse
import os
import signal
import subprocess
import sys
import time
import urllib.request
import webbrowser
from pathlib import Path
root = Path(__file__).resolve().parents[1]
parser = argparse.ArgumentParser()
parser.add_argument("--port", type=int, default=8010)
parser.add_argument("--no-open", action="store_true")
args = parser.parse_args()
url = f"http://127.0.0.1:{args.port}"
stop = False
def request_stop(*_):
global stop
stop = True
signal.signal(signal.SIGINT, request_stop)
signal.signal(signal.SIGTERM, request_stop)
processes = []
logs = []
try:
for cmd, cwd, logname in [
(["npm", "run", "watch"], root / "frontend", "frontend.log"),
(
[
sys.executable,
"-m",
"uvicorn",
"app.main:app",
"--app-dir",
"backend",
"--host",
"127.0.0.1",
"--port",
str(args.port),
"--reload",
"--reload-dir",
"backend/app",
],
root,
"backend.log",
),
]:
log = (root / ".runtime" / logname).open("w")
logs.append(log)
processes.append(
subprocess.Popen(
cmd,
cwd=cwd,
stdout=log,
stderr=subprocess.STDOUT,
start_new_session=True,
)
)
ready = False
for _ in range(60):
if stop:
break
if any(p.poll() is not None for p in processes):
raise RuntimeError(
"Um processo encerrou. Consulte .runtime/backend.log e frontend.log."
)
try:
with urllib.request.urlopen(url + "/api/health", timeout=1) as r:
ready = r.status == 200
except Exception:
pass
if ready:
break
time.sleep(1)
if not ready and not stop:
raise RuntimeError(
"A aplicação não respondeu em 60 segundos. Consulte .runtime/backend.log."
)
if ready:
from dotenv import dotenv_values
settings = dotenv_values(root / ".env")
identity = (
"Login: mesmos usuários e senhas da MESA (matrícula sem dígito)."
if os.getenv("AUTH_PROVIDER", settings.get("AUTH_PROVIDER", "mesa"))
== "mesa"
else f'Acesso inicial: {root / ".runtime/dev-access.txt"}'
)
print(
f"\nCARLA em desenvolvimento: {url}\nPorta de entrada: carla\n{identity}\nFrontend: recompila ao salvar; atualize a página para ver as mudanças.\nBackend: recarrega automaticamente. Logs em .runtime/.\nCtrl+C encerra todos os processos.\n",
flush=True,
)
if not args.no_open:
webbrowser.open(url)
while not stop:
if any(p.poll() is not None for p in processes):
raise RuntimeError("Um processo encerrou; consulte os logs em .runtime/.")
time.sleep(0.5)
except Exception as exc:
print(str(exc), file=sys.stderr)
sys.exit(1)
finally:
for process in processes:
try:
os.killpg(process.pid, signal.SIGTERM)
except ProcessLookupError:
pass
for process in processes:
try:
process.wait(timeout=7)
except subprocess.TimeoutExpired:
try:
os.killpg(process.pid, signal.SIGKILL)
except ProcessLookupError:
pass
for log in logs:
log.close()
|