jkorstad's picture
Update forge-props-env-ui from local forge-bricks (with vendored common)
840e586 verified
Raw
History Blame Contribute Delete
3.91 kB
"""
Forge-Props-Env-UI Brick
"""
import gradio as gr
import spaces
# Robust import for local workspace + HF Space deployment (common is vendored on push)
import sys
from pathlib import Path
HERE = Path(__file__).resolve().parent
for candidate in (HERE.parent, HERE):
if (candidate / "common" / "manifest.py").exists():
sys.path.insert(0, str(candidate))
break
try:
from common.manifest import create_manifest
from common.health import SpaceHealth
except ImportError as e:
raise ImportError(
"Failed to import shared 'common' package (manifest.py / health.py).\n"
"For local development: run ./install.sh from the forge-bricks/ root.\n"
"For HF Spaces: re-run scripts/push_to_hf.py so it vendors common/."
) from e
health = SpaceHealth()
import os
from pathlib import Path
from datetime import datetime
@spaces.GPU(duration=90)
def generate_prop(prompt: str, category: str = "prop") -> dict:
out_dir = Path(os.environ.get("FORGE_BRICKS_OUTPUT", "./outputs/forge_props"))
out_dir.mkdir(parents=True, exist_ok=True)
ts = int(datetime.now().timestamp())
# Enhance prompt based on category for better game assets
cat_prompt = {
"prop": "game prop, clean topology, PBR friendly",
"environment": "game environment asset, tileable if possible",
"skybox": "game skybox, panoramic, atmospheric",
"ui": "game UI element, clean, icon style, transparent background friendly"
}.get(category, "")
full_prompt = f"{prompt}, {cat_prompt}, stylized game art, high detail, no text"
target = "black-forest-labs/FLUX.1-schnell"
api_name = "/infer"
img_path = None
try:
if health.is_ok(target) is not False: # Note: health may not be defined here, add if needed
from gradio_client import Client
client = Client(target, timeout=120)
res = client.predict(
prompt=full_prompt,
seed=-1,
randomize_seed=True,
width=1024,
height=1024,
num_inference_steps=6,
api_name=api_name,
)
if isinstance(res, (list, tuple)) and res:
p = res[0] if isinstance(res[0], str) else res[0].get("path") if isinstance(res[0], dict) else None
if p and os.path.exists(str(p)):
img_path = str(out_dir / f"{category}_{ts}.png")
Image.open(p).save(img_path)
except Exception as e:
print(f"Prop gen client error: {e}")
if not img_path:
img_path = str(out_dir / f"{category}_{ts}.png")
from PIL import Image
Image.new("RGB", (512, 512), (90, 120, 80)).save(img_path)
man = create_manifest(
name=prompt[:30].replace(" ", "_"),
type=f"ui_element" if category=="ui" else "prop",
source_brick="forge-props-env-ui",
prompt_or_desc=prompt,
files={"image": img_path},
metadata={"category": category, "model": "FLUX.1-schnell"},
commercial_ok=True
)
man.save(out_dir / f"manifest_{ts}.json")
return {"file": img_path, "manifest": man.to_dict()}
def build_ui():
with gr.Blocks() as d:
gr.Markdown("# Forge-Props-Env-UI")
p = gr.Textbox("fantasy wooden barrel with metal bands")
cat = gr.Dropdown(["prop", "environment", "skybox", "ui"], value="prop")
btn = gr.Button("Generate")
out = gr.JSON()
btn.click(generate_prop, [p, cat], out)
return d
# Build at module level so that `demo` (and `gradio_app`) exist when the module is imported
# (required for Hugging Face Spaces and for agent/MCP discovery).
demo = build_ui()
gradio_app = demo # alias for compatibility with tools/skills that expect `gradio_app`
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7865, mcp_server=True)