janction-render 0.3.2__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {janction_render-0.3.2 → janction_render-0.3.3}/PKG-INFO +6 -2
- {janction_render-0.3.2 → janction_render-0.3.3}/README.md +5 -1
- {janction_render-0.3.2 → janction_render-0.3.3}/janction_render/__init__.py +1 -1
- {janction_render-0.3.2 → janction_render-0.3.3}/janction_render/mcp_server.py +36 -8
- {janction_render-0.3.2 → janction_render-0.3.3}/janction_render.egg-info/PKG-INFO +6 -2
- {janction_render-0.3.2 → janction_render-0.3.3}/pyproject.toml +1 -1
- {janction_render-0.3.2 → janction_render-0.3.3}/LICENSE +0 -0
- {janction_render-0.3.2 → janction_render-0.3.3}/janction_render/brief.py +0 -0
- {janction_render-0.3.2 → janction_render-0.3.3}/janction_render/cli.py +0 -0
- {janction_render-0.3.2 → janction_render-0.3.3}/janction_render/client.py +0 -0
- {janction_render-0.3.2 → janction_render-0.3.3}/janction_render.egg-info/SOURCES.txt +0 -0
- {janction_render-0.3.2 → janction_render-0.3.3}/janction_render.egg-info/dependency_links.txt +0 -0
- {janction_render-0.3.2 → janction_render-0.3.3}/janction_render.egg-info/entry_points.txt +0 -0
- {janction_render-0.3.2 → janction_render-0.3.3}/janction_render.egg-info/requires.txt +0 -0
- {janction_render-0.3.2 → janction_render-0.3.3}/janction_render.egg-info/top_level.txt +0 -0
- {janction_render-0.3.2 → janction_render-0.3.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: janction-render
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Cloud GPU render farm for Blender, for AI agents: MCP server (remote + stdio) and CLI. Render Blender without a GPU from Claude, ChatGPT, Claude Code, Codex, Cursor.
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -29,8 +29,12 @@ without a GPU, or when rendering locally is slow.
|
|
|
29
29
|
`environment="compare"` previews the same frame under all four presets in one labelled image, so the agent can pick one.
|
|
30
30
|
- A `.gltf` or `.obj` brings its `.bin` / `.mtl` / textures along automatically (from the same folder or the same URL folder).
|
|
31
31
|
- `orbit=True` turns any scene or imported model into a turntable: an orbit camera circles it once (`orbit_frames`, default 24;
|
|
32
|
-
a preview shows 0/90/180/270 degrees, a final render without `frame_end` gives the whole turn as an MP4).
|
|
32
|
+
a preview shows 0/90/180/270 degrees, a final render without `frame_end` gives the whole turn as an MP4). Flat floors and
|
|
33
|
+
walls are ignored when framing; `orbit_target` (object name or `x,y,z`) and `orbit_distance` (multiplier) adjust the shot.
|
|
34
|
+
- While the GPU is lent to another workload, tools answer right away with the queued job and a note instead of waiting.
|
|
33
35
|
- While a job renders, `render_status` counts finished frames inside the running chunk, so the ETA updates every few seconds.
|
|
36
|
+
- In hosts that support MCP Apps (Claude web and desktop, among others), previews, progress and download links also appear
|
|
37
|
+
as an interactive panel in the chat: the image, a progress bar, "Open MP4", and preset buttons after an `environment="compare"` preview.
|
|
34
38
|
- `scene_info` reads the scene without rendering (cameras, frame range, missing files).
|
|
35
39
|
- `render_preview` returns 1-4 low-cost frames tiled in one image within seconds, so the agent can look, fix, and repeat.
|
|
36
40
|
- `render_estimate` says how long a render will take ("about 3 minutes") and whether it fits today's free quota.
|
|
@@ -12,8 +12,12 @@ without a GPU, or when rendering locally is slow.
|
|
|
12
12
|
`environment="compare"` previews the same frame under all four presets in one labelled image, so the agent can pick one.
|
|
13
13
|
- A `.gltf` or `.obj` brings its `.bin` / `.mtl` / textures along automatically (from the same folder or the same URL folder).
|
|
14
14
|
- `orbit=True` turns any scene or imported model into a turntable: an orbit camera circles it once (`orbit_frames`, default 24;
|
|
15
|
-
a preview shows 0/90/180/270 degrees, a final render without `frame_end` gives the whole turn as an MP4).
|
|
15
|
+
a preview shows 0/90/180/270 degrees, a final render without `frame_end` gives the whole turn as an MP4). Flat floors and
|
|
16
|
+
walls are ignored when framing; `orbit_target` (object name or `x,y,z`) and `orbit_distance` (multiplier) adjust the shot.
|
|
17
|
+
- While the GPU is lent to another workload, tools answer right away with the queued job and a note instead of waiting.
|
|
16
18
|
- While a job renders, `render_status` counts finished frames inside the running chunk, so the ETA updates every few seconds.
|
|
19
|
+
- In hosts that support MCP Apps (Claude web and desktop, among others), previews, progress and download links also appear
|
|
20
|
+
as an interactive panel in the chat: the image, a progress bar, "Open MP4", and preset buttons after an `environment="compare"` preview.
|
|
17
21
|
- `scene_info` reads the scene without rendering (cameras, frame range, missing files).
|
|
18
22
|
- `render_preview` returns 1-4 low-cost frames tiled in one image within seconds, so the agent can look, fix, and repeat.
|
|
19
23
|
- `render_estimate` says how long a render will take ("about 3 minutes") and whether it fits today's free quota.
|
|
@@ -52,8 +52,9 @@ mcp = MCPServer(
|
|
|
52
52
|
)
|
|
53
53
|
|
|
54
54
|
ORBIT_DOC = (" orbit=True: turntable; an orbit camera circles the scene once over orbit_frames frames (default 24, "
|
|
55
|
-
"elevation orbit_elevation deg, default 18).
|
|
56
|
-
"
|
|
55
|
+
"elevation orbit_elevation deg, default 18). Flat floors/walls are ignored when framing; orbit_target = an "
|
|
56
|
+
"object name or 'x,y,z' centres on that, orbit_distance scales the distance (1.0). A preview without frames "
|
|
57
|
+
"shows 0/90/180/270 deg; a final without frame_end renders the whole turn as an MP4. Best for imported models.")
|
|
57
58
|
ENV_DOC = ("environment: '' keeps the scene's own world; 'studio' | 'sunset' | 'overcast' | 'night' replaces it with a "
|
|
58
59
|
"bundled HDRI (good first render for scenes without lighting work); 'compare' (render_preview only) renders the "
|
|
59
60
|
"first frame under all four presets in one 2x2 image with labels, so you can pick one; environment_strength scales it (1.0); "
|
|
@@ -75,6 +76,27 @@ def _out_root() -> Path:
|
|
|
75
76
|
return Path(os.environ.get("JANCTION_RENDER_OUT") or (Path.home() / "janction-render"))
|
|
76
77
|
|
|
77
78
|
|
|
79
|
+
def _wait_unless_gated(c: Client, job: dict[str, Any], timeout: float) -> dict[str, Any]:
|
|
80
|
+
"""仕事を待つ。ただし仕事を取れるワーカーが無い(GPU が貸し出し中)なら待たずに返し、hint で伝える。"""
|
|
81
|
+
if job["status"] in ("done", "failed", "canceled"):
|
|
82
|
+
return job
|
|
83
|
+
try:
|
|
84
|
+
q = c.health().get("queue") or {}
|
|
85
|
+
if int(q.get("workers_available") or 0) == 0 and job["status"] == "queued":
|
|
86
|
+
job["gated"] = True
|
|
87
|
+
return job
|
|
88
|
+
except Exception: # noqa: BLE001
|
|
89
|
+
pass
|
|
90
|
+
return c.wait(job["job_id"], timeout=timeout)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _gated_hint(j: dict[str, Any], again: str) -> str:
|
|
94
|
+
if j.get("gated"):
|
|
95
|
+
return (f"the GPU is lent to another workload right now; the job stays queued and starts when the GPU returns. "
|
|
96
|
+
f"Tell the user and offer to check later with {again}; do not poll continuously")
|
|
97
|
+
return ""
|
|
98
|
+
|
|
99
|
+
|
|
78
100
|
def _j(obj: Any) -> str:
|
|
79
101
|
return json.dumps(obj, ensure_ascii=False, indent=2)
|
|
80
102
|
|
|
@@ -174,12 +196,12 @@ def scene_info(scene_path: str = "", scene_id: str = "", scene_script: str = "",
|
|
|
174
196
|
sid = _resolve_scene(c, scene_path, scene_id, scene_script, assets)
|
|
175
197
|
j = c.submit(sid, kind="info", **_job_params("", 1.0, True, blender))
|
|
176
198
|
if j["status"] != "done":
|
|
177
|
-
j = c
|
|
199
|
+
j = _wait_unless_gated(c, j, INFO_WAIT_S)
|
|
178
200
|
except (ClientError, ValueError, FileNotFoundError) as exc:
|
|
179
201
|
return _j({"ok": False, "error": str(exc)})
|
|
180
202
|
if j["status"] != "done":
|
|
181
203
|
b = _brief(j)
|
|
182
|
-
b["hint"] = "still queued (a GPU worker may be busy); call scene_info again in a moment" \
|
|
204
|
+
b["hint"] = (_gated_hint(j, "scene_info(scene_id)") or "still queued (a GPU worker may be busy); call scene_info again in a moment") \
|
|
183
205
|
if j["status"] in ("queued", "running") else "fix the scene and try again"
|
|
184
206
|
return _j(b)
|
|
185
207
|
info = dict(j.get("info") or {})
|
|
@@ -215,6 +237,8 @@ def render_preview(
|
|
|
215
237
|
orbit: bool = False,
|
|
216
238
|
orbit_frames: int = 24,
|
|
217
239
|
orbit_elevation: float = 18.0,
|
|
240
|
+
orbit_target: str = "",
|
|
241
|
+
orbit_distance: float = 1.0,
|
|
218
242
|
) -> list[Any]:
|
|
219
243
|
"""Render a fast, cheap preview of a Blender scene on a JANCTION GPU and show the image.
|
|
220
244
|
|
|
@@ -236,9 +260,10 @@ def render_preview(
|
|
|
236
260
|
j = c.submit(sid, kind="preview", frames=frame_list, camera=camera or None,
|
|
237
261
|
width=width, height=height, samples=samples,
|
|
238
262
|
**_job_params(environment, environment_strength, environment_visible, blender),
|
|
239
|
-
**({"orbit": True, "orbit_frames": orbit_frames, "orbit_elevation": orbit_elevation
|
|
263
|
+
**({"orbit": True, "orbit_frames": orbit_frames, "orbit_elevation": orbit_elevation,
|
|
264
|
+
"orbit_target": orbit_target, "orbit_distance": orbit_distance} if orbit else {}))
|
|
240
265
|
_log(f"preview job {j['job_id']} submitted frames={frame_list}")
|
|
241
|
-
j = c
|
|
266
|
+
j = _wait_unless_gated(c, j, PREVIEW_WAIT_S)
|
|
242
267
|
except ClientError as exc:
|
|
243
268
|
block = _payment_block(exc) or _quota_block(exc)
|
|
244
269
|
return [_j(block if block else {"ok": False, "error": str(exc)})]
|
|
@@ -246,7 +271,7 @@ def render_preview(
|
|
|
246
271
|
return [_j({"ok": False, "error": str(exc)})]
|
|
247
272
|
brief = _brief(j)
|
|
248
273
|
if j["status"] != "done":
|
|
249
|
-
brief["hint"] = ("still running: call render_status(job_id) and then render_download"
|
|
274
|
+
brief["hint"] = ((_gated_hint(j, "render_status(job_id)") or "still running: call render_status(job_id) and then render_download")
|
|
250
275
|
if j["status"] in ("queued", "running")
|
|
251
276
|
else "fix the scene and try again")
|
|
252
277
|
return [_j(brief)]
|
|
@@ -315,6 +340,8 @@ def render_final(
|
|
|
315
340
|
orbit: bool = False,
|
|
316
341
|
orbit_frames: int = 24,
|
|
317
342
|
orbit_elevation: float = 18.0,
|
|
343
|
+
orbit_target: str = "",
|
|
344
|
+
orbit_distance: float = 1.0,
|
|
318
345
|
) -> str:
|
|
319
346
|
"""Render the final frames (or a video) of a Blender scene on JANCTION GPUs.
|
|
320
347
|
|
|
@@ -330,7 +357,8 @@ def render_final(
|
|
|
330
357
|
sid = _resolve_scene(c, scene_path, scene_id, scene_script, assets)
|
|
331
358
|
extra: dict[str, Any] = {}
|
|
332
359
|
if orbit:
|
|
333
|
-
extra.update({"orbit": True, "orbit_frames": orbit_frames, "orbit_elevation": orbit_elevation
|
|
360
|
+
extra.update({"orbit": True, "orbit_frames": orbit_frames, "orbit_elevation": orbit_elevation,
|
|
361
|
+
"orbit_target": orbit_target, "orbit_distance": orbit_distance})
|
|
334
362
|
if frame_end <= frame_start:
|
|
335
363
|
frame_end = None # type: ignore[assignment] # 1 周ぶんは受付が決める
|
|
336
364
|
j = c.submit(sid, kind="final", frame_start=frame_start, frame_end=frame_end,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: janction-render
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Cloud GPU render farm for Blender, for AI agents: MCP server (remote + stdio) and CLI. Render Blender without a GPU from Claude, ChatGPT, Claude Code, Codex, Cursor.
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -29,8 +29,12 @@ without a GPU, or when rendering locally is slow.
|
|
|
29
29
|
`environment="compare"` previews the same frame under all four presets in one labelled image, so the agent can pick one.
|
|
30
30
|
- A `.gltf` or `.obj` brings its `.bin` / `.mtl` / textures along automatically (from the same folder or the same URL folder).
|
|
31
31
|
- `orbit=True` turns any scene or imported model into a turntable: an orbit camera circles it once (`orbit_frames`, default 24;
|
|
32
|
-
a preview shows 0/90/180/270 degrees, a final render without `frame_end` gives the whole turn as an MP4).
|
|
32
|
+
a preview shows 0/90/180/270 degrees, a final render without `frame_end` gives the whole turn as an MP4). Flat floors and
|
|
33
|
+
walls are ignored when framing; `orbit_target` (object name or `x,y,z`) and `orbit_distance` (multiplier) adjust the shot.
|
|
34
|
+
- While the GPU is lent to another workload, tools answer right away with the queued job and a note instead of waiting.
|
|
33
35
|
- While a job renders, `render_status` counts finished frames inside the running chunk, so the ETA updates every few seconds.
|
|
36
|
+
- In hosts that support MCP Apps (Claude web and desktop, among others), previews, progress and download links also appear
|
|
37
|
+
as an interactive panel in the chat: the image, a progress bar, "Open MP4", and preset buttons after an `environment="compare"` preview.
|
|
34
38
|
- `scene_info` reads the scene without rendering (cameras, frame range, missing files).
|
|
35
39
|
- `render_preview` returns 1-4 low-cost frames tiled in one image within seconds, so the agent can look, fix, and repeat.
|
|
36
40
|
- `render_estimate` says how long a render will take ("about 3 minutes") and whether it fits today's free quota.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "janction-render"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.3"
|
|
8
8
|
description = "Cloud GPU render farm for Blender, for AI agents: MCP server (remote + stdio) and CLI. Render Blender without a GPU from Claude, ChatGPT, Claude Code, Codex, Cursor."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{janction_render-0.3.2 → janction_render-0.3.3}/janction_render.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|