janction-render 0.4.4__tar.gz → 0.4.5__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: janction-render
3
- Version: 0.4.4
3
+ Version: 0.4.5
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
@@ -49,7 +49,8 @@ without a GPU, or when rendering locally is slow.
49
49
  - `render_final` renders the frames on GPUs and joins them into an MP4; `render_status` reports the remaining time.
50
50
  - Free beta: no charges. Each key gets 10 GPU-minutes per day; a final render is up to 240 frames at 1080p.
51
51
  Paid plans (per GPU second, prepaid credit) will be announced on the service page before they start.
52
- - Inputs and results are deleted 24 hours after last use and are never used for training.
52
+ - Inputs and results are deleted 24 hours after last use and are never used for training. A render you choose to
53
+ share (`render_share`) gets a public page (`/r/<id>`, OGP for X and Discord) that stays until you unshare it.
53
54
 
54
55
  ## Status
55
56
 
@@ -125,6 +126,7 @@ Then, in Claude Code:
125
126
  | `render_final(scene_id, frame_start, frame_end, width, height, samples, fps, output, environment?, blender?, engine?, transparent?, notify_url?)` | frames (png / exr) or video (mp4 / webm / prores / gif / webp); `transparent=True` keeps an alpha background (png / exr / webm / gif / webp); `notify_url` gets one JSON POST when the job finishes; returns job_id + estimate |
126
127
  | `render_status(job_id)` | progress and ETA (`eta.human`); `render_download(job_id, only="mp4" / "frames" / "all")` files or links; `render_cancel(job_id)` |
127
128
  | `billing()` | free-beta quota (used today, daily limit, reset time); later balance and top-up link |
129
+ | `render_share(job_id, title?, note?, include_script?, listed?)` | a public page `/r/<id>` with the image or video, the conditions and (optionally) the script; survives the 24-hour expiry until `render_unshare`; listed pages appear in `/gallery` |
128
130
  | `asset_search(query, kind)` | CC0 models / textures / HDRIs on Poly Haven by words; results carry `polyhaven:<id>` and the entry file |
129
131
  | `render_info()` | workers online or gated (GPU lent to another workload), queue, expected wait, supported inputs, environment presets, Blender versions |
130
132
 
@@ -134,7 +136,7 @@ Options on `render_preview` / `render_final`: `environment` (`studio`, `sunset`,
134
136
  sent with the scene, found in the script through `os.environ["JR_ASSETS_DIR"]`; a `.blend`'s external files are collected
135
137
  automatically with `pip install janction-render[blend]`) or `asset_urls` (remote).
136
138
 
137
- CLI: `janction-render inspect|preview|render|status|download|cancel|jobs|balance|topup|info`.
139
+ CLI: `janction-render inspect|preview|render|status|download|share|unshare|cancel|jobs|balance|topup|info`.
138
140
 
139
141
  ## Writing a scene script
140
142
 
@@ -166,6 +168,8 @@ POST /v1/jobs {scene_id, kind: info|preview|final, frames|frame_start/frame_en
166
168
  environment, environment_strength, environment_visible, blender, orbit, orbit_frames, orbit_elevation}
167
169
  GET /v1/jobs/{id} status, progress, eta, artifacts[], cost, warnings, info DELETE /v1/jobs/{id} cancel
168
170
  GET /v1/jobs/{id}/artifacts/{name} PNG / MP4
171
+ POST /v1/jobs/{id}/share {title?, note?, include_script?, listed?} -> {share_id, url} DELETE /v1/jobs/{id}/share GET /v1/shares
172
+ GET /r/{share_id} public page (no key) GET /gallery
169
173
  GET /v1/assets/search?q=&kind=models|textures|hdris CC0 assets (Poly Haven) -> spec polyhaven:<id>
170
174
  POST /v1/files/{id}/assets/urls {urls: ["https://...", "polyhaven:<id>"]} fetch assets server-side
171
175
  POST /mcp remote MCP (Streamable HTTP; Bearer api key or OAuth)
@@ -32,7 +32,8 @@ without a GPU, or when rendering locally is slow.
32
32
  - `render_final` renders the frames on GPUs and joins them into an MP4; `render_status` reports the remaining time.
33
33
  - Free beta: no charges. Each key gets 10 GPU-minutes per day; a final render is up to 240 frames at 1080p.
34
34
  Paid plans (per GPU second, prepaid credit) will be announced on the service page before they start.
35
- - Inputs and results are deleted 24 hours after last use and are never used for training.
35
+ - Inputs and results are deleted 24 hours after last use and are never used for training. A render you choose to
36
+ share (`render_share`) gets a public page (`/r/<id>`, OGP for X and Discord) that stays until you unshare it.
36
37
 
37
38
  ## Status
38
39
 
@@ -108,6 +109,7 @@ Then, in Claude Code:
108
109
  | `render_final(scene_id, frame_start, frame_end, width, height, samples, fps, output, environment?, blender?, engine?, transparent?, notify_url?)` | frames (png / exr) or video (mp4 / webm / prores / gif / webp); `transparent=True` keeps an alpha background (png / exr / webm / gif / webp); `notify_url` gets one JSON POST when the job finishes; returns job_id + estimate |
109
110
  | `render_status(job_id)` | progress and ETA (`eta.human`); `render_download(job_id, only="mp4" / "frames" / "all")` files or links; `render_cancel(job_id)` |
110
111
  | `billing()` | free-beta quota (used today, daily limit, reset time); later balance and top-up link |
112
+ | `render_share(job_id, title?, note?, include_script?, listed?)` | a public page `/r/<id>` with the image or video, the conditions and (optionally) the script; survives the 24-hour expiry until `render_unshare`; listed pages appear in `/gallery` |
111
113
  | `asset_search(query, kind)` | CC0 models / textures / HDRIs on Poly Haven by words; results carry `polyhaven:<id>` and the entry file |
112
114
  | `render_info()` | workers online or gated (GPU lent to another workload), queue, expected wait, supported inputs, environment presets, Blender versions |
113
115
 
@@ -117,7 +119,7 @@ Options on `render_preview` / `render_final`: `environment` (`studio`, `sunset`,
117
119
  sent with the scene, found in the script through `os.environ["JR_ASSETS_DIR"]`; a `.blend`'s external files are collected
118
120
  automatically with `pip install janction-render[blend]`) or `asset_urls` (remote).
119
121
 
120
- CLI: `janction-render inspect|preview|render|status|download|cancel|jobs|balance|topup|info`.
122
+ CLI: `janction-render inspect|preview|render|status|download|share|unshare|cancel|jobs|balance|topup|info`.
121
123
 
122
124
  ## Writing a scene script
123
125
 
@@ -149,6 +151,8 @@ POST /v1/jobs {scene_id, kind: info|preview|final, frames|frame_start/frame_en
149
151
  environment, environment_strength, environment_visible, blender, orbit, orbit_frames, orbit_elevation}
150
152
  GET /v1/jobs/{id} status, progress, eta, artifacts[], cost, warnings, info DELETE /v1/jobs/{id} cancel
151
153
  GET /v1/jobs/{id}/artifacts/{name} PNG / MP4
154
+ POST /v1/jobs/{id}/share {title?, note?, include_script?, listed?} -> {share_id, url} DELETE /v1/jobs/{id}/share GET /v1/shares
155
+ GET /r/{share_id} public page (no key) GET /gallery
152
156
  GET /v1/assets/search?q=&kind=models|textures|hdris CC0 assets (Poly Haven) -> spec polyhaven:<id>
153
157
  POST /v1/files/{id}/assets/urls {urls: ["https://...", "polyhaven:<id>"]} fetch assets server-side
154
158
  POST /mcp remote MCP (Streamable HTTP; Bearer api key or OAuth)
@@ -1,3 +1,3 @@
1
1
  """JANCTION Render — ターミナルの AI エージェントから GPU で 3DCG を描く。"""
2
2
 
3
- __version__ = "0.4.4"
3
+ __version__ = "0.4.5"
@@ -136,6 +136,17 @@ def cmd_cancel(c: Client, args: argparse.Namespace) -> int:
136
136
  return 0
137
137
 
138
138
 
139
+ def cmd_share(c: Client, args: argparse.Namespace) -> int:
140
+ v = c.share(args.job, title=args.title or "", note=args.note or "", include_script=bool(args.script), listed=not args.unlisted)
141
+ print(v["url"])
142
+ return 0
143
+
144
+
145
+ def cmd_unshare(c: Client, args: argparse.Namespace) -> int:
146
+ print(_j(c.unshare(args.job)))
147
+ return 0
148
+
149
+
139
150
  def cmd_jobs(c: Client, args: argparse.Namespace) -> int:
140
151
  rows = c.jobs(args.limit)
141
152
  for j in rows:
@@ -221,6 +232,16 @@ def build_parser() -> argparse.ArgumentParser:
221
232
  s.add_argument("--wait", type=float, default=0, help="seconds to wait for the job first")
222
233
  s.set_defaults(fn=cmd_download)
223
234
 
235
+ s = sub.add_parser("share", help="publish a finished job as a public page (/r/<id>)")
236
+ s.add_argument("job")
237
+ s.add_argument("--title", default=None)
238
+ s.add_argument("--note", default=None)
239
+ s.add_argument("--script", action="store_true", help="include the bpy script on the page")
240
+ s.add_argument("--unlisted", action="store_true", help="do not list the page in the gallery")
241
+ s.set_defaults(fn=cmd_share)
242
+ s = sub.add_parser("unshare", help="remove the public page of a job")
243
+ s.add_argument("job")
244
+ s.set_defaults(fn=cmd_unshare)
224
245
  s = sub.add_parser("cancel")
225
246
  s.add_argument("job")
226
247
  s.set_defaults(fn=cmd_cancel)
@@ -361,6 +361,23 @@ class Client:
361
361
  self._raise(r)
362
362
  return r.json()
363
363
 
364
+ def share(self, job_id: str, title: str = "", note: str = "", include_script: bool = False, listed: bool = True) -> dict[str, Any]:
365
+ """描けた結果を公開ページにする(/r/<id>)。"""
366
+ r = self.s.post(f"{self.server}/v1/jobs/{job_id}/share", headers=self._headers(),
367
+ json={"title": title, "note": note, "include_script": include_script, "listed": listed}, timeout=120)
368
+ self._raise(r)
369
+ return r.json()
370
+
371
+ def unshare(self, job_id: str) -> dict[str, Any]:
372
+ r = self.s.delete(f"{self.server}/v1/jobs/{job_id}/share", headers=self._headers(), timeout=60)
373
+ self._raise(r)
374
+ return r.json()
375
+
376
+ def shares(self) -> dict[str, Any]:
377
+ r = self.s.get(f"{self.server}/v1/shares", headers=self._headers(), timeout=30)
378
+ self._raise(r)
379
+ return r.json()
380
+
364
381
  def fetch_asset_urls(self, scene_id: str, urls: list[str]) -> dict[str, Any]:
365
382
  """URL か polyhaven:<id> の素材を受付に取らせてシーンに足す(受付が取るので手元には要らない)。"""
366
383
  r = self.s.post(f"{self.server}/v1/files/{scene_id}/assets/urls", headers=self._headers(),
@@ -517,6 +517,27 @@ def render_cancel(job_id: str) -> str:
517
517
  return _j({"ok": False, "error": str(exc)})
518
518
 
519
519
 
520
+ @mcp.tool()
521
+ def render_share(job_id: str, title: str = "", note: str = "", include_script: bool = False, listed: bool = True) -> str:
522
+ """Publish a finished render as a public page the user can send to anyone (X, Discord, a client): the image or
523
+ video, the render conditions, an optional title and note, and the bpy script if include_script=True. The page
524
+ keeps a copy of the result after the job's 24-hour expiry, until render_unshare. listed=True also puts it in the
525
+ public gallery. Ask the user before sharing; return the url to them."""
526
+ try:
527
+ return _j(_client().share(job_id, title=title, note=note, include_script=include_script, listed=listed))
528
+ except ClientError as exc:
529
+ return _j({"ok": False, "error": str(exc)})
530
+
531
+
532
+ @mcp.tool()
533
+ def render_unshare(job_id: str) -> str:
534
+ """Remove the public share page of a job (the copy of the result is deleted)."""
535
+ try:
536
+ return _j(_client().unshare(job_id))
537
+ except ClientError as exc:
538
+ return _j({"ok": False, "error": str(exc)})
539
+
540
+
520
541
  @mcp.tool()
521
542
  def billing(topup_yen: int = 0) -> str:
522
543
  """Check the account's quota or credit. During the free beta it returns today's GPU-time usage,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: janction-render
3
- Version: 0.4.4
3
+ Version: 0.4.5
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
@@ -49,7 +49,8 @@ without a GPU, or when rendering locally is slow.
49
49
  - `render_final` renders the frames on GPUs and joins them into an MP4; `render_status` reports the remaining time.
50
50
  - Free beta: no charges. Each key gets 10 GPU-minutes per day; a final render is up to 240 frames at 1080p.
51
51
  Paid plans (per GPU second, prepaid credit) will be announced on the service page before they start.
52
- - Inputs and results are deleted 24 hours after last use and are never used for training.
52
+ - Inputs and results are deleted 24 hours after last use and are never used for training. A render you choose to
53
+ share (`render_share`) gets a public page (`/r/<id>`, OGP for X and Discord) that stays until you unshare it.
53
54
 
54
55
  ## Status
55
56
 
@@ -125,6 +126,7 @@ Then, in Claude Code:
125
126
  | `render_final(scene_id, frame_start, frame_end, width, height, samples, fps, output, environment?, blender?, engine?, transparent?, notify_url?)` | frames (png / exr) or video (mp4 / webm / prores / gif / webp); `transparent=True` keeps an alpha background (png / exr / webm / gif / webp); `notify_url` gets one JSON POST when the job finishes; returns job_id + estimate |
126
127
  | `render_status(job_id)` | progress and ETA (`eta.human`); `render_download(job_id, only="mp4" / "frames" / "all")` files or links; `render_cancel(job_id)` |
127
128
  | `billing()` | free-beta quota (used today, daily limit, reset time); later balance and top-up link |
129
+ | `render_share(job_id, title?, note?, include_script?, listed?)` | a public page `/r/<id>` with the image or video, the conditions and (optionally) the script; survives the 24-hour expiry until `render_unshare`; listed pages appear in `/gallery` |
128
130
  | `asset_search(query, kind)` | CC0 models / textures / HDRIs on Poly Haven by words; results carry `polyhaven:<id>` and the entry file |
129
131
  | `render_info()` | workers online or gated (GPU lent to another workload), queue, expected wait, supported inputs, environment presets, Blender versions |
130
132
 
@@ -134,7 +136,7 @@ Options on `render_preview` / `render_final`: `environment` (`studio`, `sunset`,
134
136
  sent with the scene, found in the script through `os.environ["JR_ASSETS_DIR"]`; a `.blend`'s external files are collected
135
137
  automatically with `pip install janction-render[blend]`) or `asset_urls` (remote).
136
138
 
137
- CLI: `janction-render inspect|preview|render|status|download|cancel|jobs|balance|topup|info`.
139
+ CLI: `janction-render inspect|preview|render|status|download|share|unshare|cancel|jobs|balance|topup|info`.
138
140
 
139
141
  ## Writing a scene script
140
142
 
@@ -166,6 +168,8 @@ POST /v1/jobs {scene_id, kind: info|preview|final, frames|frame_start/frame_en
166
168
  environment, environment_strength, environment_visible, blender, orbit, orbit_frames, orbit_elevation}
167
169
  GET /v1/jobs/{id} status, progress, eta, artifacts[], cost, warnings, info DELETE /v1/jobs/{id} cancel
168
170
  GET /v1/jobs/{id}/artifacts/{name} PNG / MP4
171
+ POST /v1/jobs/{id}/share {title?, note?, include_script?, listed?} -> {share_id, url} DELETE /v1/jobs/{id}/share GET /v1/shares
172
+ GET /r/{share_id} public page (no key) GET /gallery
169
173
  GET /v1/assets/search?q=&kind=models|textures|hdris CC0 assets (Poly Haven) -> spec polyhaven:<id>
170
174
  POST /v1/files/{id}/assets/urls {urls: ["https://...", "polyhaven:<id>"]} fetch assets server-side
171
175
  POST /mcp remote MCP (Streamable HTTP; Bearer api key or OAuth)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "janction-render"
7
- version = "0.4.4"
7
+ version = "0.4.5"
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