Spaces:
Running
Running
Upload folder using huggingface_hub
Browse files- server/app.py +73 -13
server/app.py
CHANGED
|
@@ -4,7 +4,7 @@ import os
|
|
| 4 |
from pathlib import Path
|
| 5 |
|
| 6 |
import uvicorn
|
| 7 |
-
from fastapi.responses import HTMLResponse
|
| 8 |
from fastapi.staticfiles import StaticFiles
|
| 9 |
|
| 10 |
try:
|
|
@@ -27,9 +27,9 @@ except Exception:
|
|
| 27 |
from models import DesignGymAction, DesignGymObservation
|
| 28 |
|
| 29 |
try:
|
| 30 |
-
from .DesignGym_environment import DesignGymEnvironment
|
| 31 |
except Exception:
|
| 32 |
-
from server.DesignGym_environment import DesignGymEnvironment
|
| 33 |
|
| 34 |
|
| 35 |
app = create_fastapi_app(
|
|
@@ -45,6 +45,34 @@ if ASSETS_DIR.exists():
|
|
| 45 |
app.mount("/assets", StaticFiles(directory=str(ASSETS_DIR)), name="assets")
|
| 46 |
|
| 47 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
@app.get("/", response_class=HTMLResponse)
|
| 49 |
def home() -> str:
|
| 50 |
image_block = ""
|
|
@@ -165,9 +193,6 @@ def home() -> str:
|
|
| 165 |
color: var(--muted);
|
| 166 |
line-height: 1.85;
|
| 167 |
}}
|
| 168 |
-
li + li {{
|
| 169 |
-
margin-top: 4px;
|
| 170 |
-
}}
|
| 171 |
.links {{
|
| 172 |
display: grid;
|
| 173 |
gap: 12px;
|
|
@@ -233,7 +258,6 @@ def home() -> str:
|
|
| 233 |
editorial covers, and dense flyers. The agent improves alignment, hierarchy, spacing,
|
| 234 |
reading order, occupancy, and semantic placement through structured actions.
|
| 235 |
</p>
|
| 236 |
-
<br>
|
| 237 |
|
| 238 |
{image_block}
|
| 239 |
|
|
@@ -243,14 +267,15 @@ def home() -> str:
|
|
| 243 |
<h2>What this Space serves</h2>
|
| 244 |
<p>
|
| 245 |
This Hugging Face Space hosts the live OpenEnv-compatible DesignGym environment.
|
| 246 |
-
It is designed for evaluation, inference, and deployment testing.
|
| 247 |
</p>
|
| 248 |
<ul>
|
| 249 |
-
<li><code>POST /reset</code>
|
| 250 |
-
<li><code>POST /step</code>
|
| 251 |
-
<li><code>GET /state</code>
|
| 252 |
-
<li><code>GET /health</code>
|
| 253 |
-
<li><code>/
|
|
|
|
|
|
|
| 254 |
</ul>
|
| 255 |
</div>
|
| 256 |
</div>
|
|
@@ -263,6 +288,14 @@ def home() -> str:
|
|
| 263 |
<span class="link-title">API Docs</span>
|
| 264 |
<span class="link-sub">Inspect endpoints and schemas</span>
|
| 265 |
</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 266 |
<a class="link-card" href="/health">
|
| 267 |
<span class="link-title">Health Check</span>
|
| 268 |
<span class="link-sub">Simple runtime status endpoint</span>
|
|
@@ -285,6 +318,33 @@ def home() -> str:
|
|
| 285 |
"""
|
| 286 |
|
| 287 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 288 |
def main() -> None:
|
| 289 |
host = os.getenv("HOST", "0.0.0.0")
|
| 290 |
port = int(os.getenv("PORT", "8000"))
|
|
|
|
| 4 |
from pathlib import Path
|
| 5 |
|
| 6 |
import uvicorn
|
| 7 |
+
from fastapi.responses import HTMLResponse, JSONResponse
|
| 8 |
from fastapi.staticfiles import StaticFiles
|
| 9 |
|
| 10 |
try:
|
|
|
|
| 27 |
from models import DesignGymAction, DesignGymObservation
|
| 28 |
|
| 29 |
try:
|
| 30 |
+
from .DesignGym_environment import DesignGymEnvironment, TASKS
|
| 31 |
except Exception:
|
| 32 |
+
from server.DesignGym_environment import DesignGymEnvironment, TASKS
|
| 33 |
|
| 34 |
|
| 35 |
app = create_fastapi_app(
|
|
|
|
| 45 |
app.mount("/assets", StaticFiles(directory=str(ASSETS_DIR)), name="assets")
|
| 46 |
|
| 47 |
|
| 48 |
+
def _task_description(task_id: str) -> str:
|
| 49 |
+
if task_id == "poster_basic_v1":
|
| 50 |
+
return "Poster layout optimization with hero image, title hierarchy, CTA placement, and alignment."
|
| 51 |
+
if task_id == "editorial_cover_v1":
|
| 52 |
+
return "Editorial cover optimization with masthead preservation, headline stack, and reading order."
|
| 53 |
+
if task_id == "dense_flyer_v1":
|
| 54 |
+
return "Dense flyer optimization with support-group reflow, spacing, occupancy, and caption alignment."
|
| 55 |
+
return "Design layout optimization task."
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def _task_catalog():
|
| 59 |
+
catalog = []
|
| 60 |
+
for task_id, spec in TASKS.items():
|
| 61 |
+
catalog.append(
|
| 62 |
+
{
|
| 63 |
+
"task_id": task_id,
|
| 64 |
+
"graded": True,
|
| 65 |
+
"grader": "deterministic_layout_utility",
|
| 66 |
+
"description": _task_description(task_id),
|
| 67 |
+
"max_steps": int(spec.get("max_steps", 0)),
|
| 68 |
+
"instance_id": spec.get("instance_id"),
|
| 69 |
+
"reward_range": [0.0, 1.0],
|
| 70 |
+
"score_range": [0.0, 1.0],
|
| 71 |
+
}
|
| 72 |
+
)
|
| 73 |
+
return catalog
|
| 74 |
+
|
| 75 |
+
|
| 76 |
@app.get("/", response_class=HTMLResponse)
|
| 77 |
def home() -> str:
|
| 78 |
image_block = ""
|
|
|
|
| 193 |
color: var(--muted);
|
| 194 |
line-height: 1.85;
|
| 195 |
}}
|
|
|
|
|
|
|
|
|
|
| 196 |
.links {{
|
| 197 |
display: grid;
|
| 198 |
gap: 12px;
|
|
|
|
| 258 |
editorial covers, and dense flyers. The agent improves alignment, hierarchy, spacing,
|
| 259 |
reading order, occupancy, and semantic placement through structured actions.
|
| 260 |
</p>
|
|
|
|
| 261 |
|
| 262 |
{image_block}
|
| 263 |
|
|
|
|
| 267 |
<h2>What this Space serves</h2>
|
| 268 |
<p>
|
| 269 |
This Hugging Face Space hosts the live OpenEnv-compatible DesignGym environment.
|
|
|
|
| 270 |
</p>
|
| 271 |
<ul>
|
| 272 |
+
<li><code>POST /reset</code></li>
|
| 273 |
+
<li><code>POST /step</code></li>
|
| 274 |
+
<li><code>GET /state</code></li>
|
| 275 |
+
<li><code>GET /health</code></li>
|
| 276 |
+
<li><code>GET /info</code></li>
|
| 277 |
+
<li><code>GET /tasks</code></li>
|
| 278 |
+
<li><a href="/docs">/docs</a></li>
|
| 279 |
</ul>
|
| 280 |
</div>
|
| 281 |
</div>
|
|
|
|
| 288 |
<span class="link-title">API Docs</span>
|
| 289 |
<span class="link-sub">Inspect endpoints and schemas</span>
|
| 290 |
</a>
|
| 291 |
+
<a class="link-card" href="/info">
|
| 292 |
+
<span class="link-title">Environment Info</span>
|
| 293 |
+
<span class="link-sub">Task and grader metadata</span>
|
| 294 |
+
</a>
|
| 295 |
+
<a class="link-card" href="/tasks">
|
| 296 |
+
<span class="link-title">Task List</span>
|
| 297 |
+
<span class="link-sub">Discover all available tasks</span>
|
| 298 |
+
</a>
|
| 299 |
<a class="link-card" href="/health">
|
| 300 |
<span class="link-title">Health Check</span>
|
| 301 |
<span class="link-sub">Simple runtime status endpoint</span>
|
|
|
|
| 318 |
"""
|
| 319 |
|
| 320 |
|
| 321 |
+
@app.get("/info")
|
| 322 |
+
def info():
|
| 323 |
+
tasks = _task_catalog()
|
| 324 |
+
return JSONResponse(
|
| 325 |
+
{
|
| 326 |
+
"name": "DesignGym",
|
| 327 |
+
"description": "OpenEnv-compatible reinforcement learning environment for design layout optimization.",
|
| 328 |
+
"task_count": len(tasks),
|
| 329 |
+
"default_task_id": "poster_basic_v1",
|
| 330 |
+
"tasks": tasks,
|
| 331 |
+
"reward_range": [0.0, 1.0],
|
| 332 |
+
"score_range": [0.0, 1.0],
|
| 333 |
+
"supports_seeded_reset": True,
|
| 334 |
+
"supports_task_id_reset": True,
|
| 335 |
+
}
|
| 336 |
+
)
|
| 337 |
+
|
| 338 |
+
|
| 339 |
+
@app.get("/tasks")
|
| 340 |
+
def tasks():
|
| 341 |
+
return JSONResponse(
|
| 342 |
+
{
|
| 343 |
+
"tasks": _task_catalog()
|
| 344 |
+
}
|
| 345 |
+
)
|
| 346 |
+
|
| 347 |
+
|
| 348 |
def main() -> None:
|
| 349 |
host = os.getenv("HOST", "0.0.0.0")
|
| 350 |
port = int(os.getenv("PORT", "8000"))
|