nikolaife's picture
Update app.py
0d80aff verified
import os
import zipfile
import subprocess
import base64
import sys
import pathlib
import gradio as gr
ZIP_FILE = "newtons-cradle-simulation.zip"
APP_DIR = "app"
BUILD_DIR = os.path.join(APP_DIR, "dist") # vite default output
POSSIBLE_INDEXES = [
os.path.join(BUILD_DIR, "index.html"),
os.path.join(APP_DIR, "build", "index.html"),
os.path.join(APP_DIR, "public", "index.html"),
]
def run_cmd(cmd, cwd=None):
try:
res = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True, check=False)
print(f"CMD: {' '.join(cmd)} (cwd={cwd})")
print("returncode:", res.returncode)
if res.stdout:
print("--- stdout ---")
print(res.stdout)
if res.stderr:
print("--- stderr ---", file=sys.stderr)
print(res.stderr, file=sys.stderr)
return res.returncode == 0
except Exception as e:
print("Exception running command:", e, file=sys.stderr)
return False
# 1) Распаковка архива (если ещё не распаковано)
if not os.path.exists(APP_DIR):
if not os.path.exists(ZIP_FILE):
raise FileNotFoundError(f"Zip file not found in repo root: {ZIP_FILE}")
with zipfile.ZipFile(ZIP_FILE, "r") as z:
z.extractall(APP_DIR)
print(f"Archive extracted to '{APP_DIR}'")
else:
print(f"App dir '{APP_DIR}' already exists (runtime).")
# 2) npm install
if os.path.exists(APP_DIR):
run_cmd(["npm", "install"], cwd=APP_DIR)
else:
print("Skipping npm install: app dir missing")
# 3) npm run build
if os.path.exists(APP_DIR):
run_cmd(["npm", "run", "build"], cwd=APP_DIR)
else:
print("Skipping npm run build: app dir missing")
# 4) найти index.html
index_path = None
for p in POSSIBLE_INDEXES:
if os.path.exists(p):
index_path = p
break
if index_path is None:
# fallback: try to find any index.html under app dir
for p in pathlib.Path(APP_DIR).rglob("index.html"):
index_path = str(p)
break
if index_path is None:
raise RuntimeError("index.html not found after build. Проверь структуру сборки в логах.")
print("Using index:", index_path)
# 5) прочитать и встроить в iframe через data: URL
with open(index_path, "rb") as f:
html_bytes = f.read()
b64 = base64.b64encode(html_bytes).decode("ascii")
data_url = f"data:text/html;base64,{b64}"
with gr.Blocks() as demo:
gr.Markdown("### Newtons pendulum — встроенное приложение (build → dist/index.html)")
gr.HTML(f'<iframe src="{data_url}" width="100%" height="800" style="border:none;"></iframe>')
# 6) Запуск Gradio
demo.launch()