$ cat node-template.py

G

Get Artifact

// Read an existing Artifact's content and metadata from Drive by its id.

Input
Storage
#artifact#document#read
template.py
1"""get-artifact — read an existing Artifact's content and metadata by id.23Takes ONLY an artifact id. The gais SDK (Gais.artifact.get) resolves the4artifact's parent Drive item server-side and fetches the content through the5permissioned www-emblema Artifact API with the per-execution USER_TOKEN — this6node imports no HTTP client. The id is UUID-validated here (defense in depth)7so an id wired from an upstream node can't rewrite the request route.89If the artifact is still generating (``content`` null), this returns an empty10``content`` plus the current ``status`` instead of failing, so a graph that11reads slightly early degrades gracefully rather than crashing.12"""1314from __future__ import annotations1516import json17import re18import sys19import traceback20from typing import Any2122from gais import Gais2324_UUID_RE = re.compile(25    r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",26    re.IGNORECASE,27)282930def _normalize_uuid(value: Any, field: str) -> str:31    """Accept a bare UUID or a ``mention://.../<uuid>`` URI; validate as UUID."""32    if not isinstance(value, str):33        raise ValueError(f"{field} must be a string, got {type(value).__name__}")34    s = value.strip()35    if "://" in s:36        s = s.rsplit("/", 1)[-1]37    if not _UUID_RE.match(s):38        raise ValueError(f"{field} is not a valid UUID: {value!r}")39    return s404142def process(inputs: dict[str, Any]) -> dict[str, Any]:43    artifact_id = _normalize_uuid(inputs.get("artifactId"), "artifactId")4445    print(f"[get-artifact] artifact={artifact_id}", file=sys.stderr)4647    result = Gais.artifact.get(artifact_id=artifact_id)48    meta = result.metadata4950    print(51        f"[get-artifact] status={meta.get('status')} chars={len(result.text or '')}",52        file=sys.stderr,53    )5455    return {56        "content": result.text or "",57        "name": meta.get("name", ""),58        "status": meta.get("status", ""),59        "format": meta.get("format", "markdown"),60    }616263def main() -> None:64    try:65        envelope = json.loads(sys.stdin.read() or "{}")66        if not isinstance(envelope, dict):67            envelope = {}68        inputs = envelope.get("inputs", {}) or {}69        json.dump(process(inputs), sys.stdout)70    except Exception as e:71        print(72            json.dumps({73                "error": str(e),74                "errorType": type(e).__name__,75                "traceback": traceback.format_exc(),76            }),77            file=sys.stderr,78        )79        sys.exit(1)808182if __name__ == "__main__":83    main()84

$ git log --oneline

v2.0.0
HEAD
2026-06-12
v1.0.02026-06-12