$ cat node-template.py

Public Share

// Publishes content or files to a public URL. Supports HTML, plain text, and file downloads. Optionally protects with a PIN. The URL is deterministic — re-running the node refreshes the content without changing the link.

Output
Utility
template.py
1import json2import sys3import os4import hashlib5import string6import secrets78ALPHABET = string.digits + string.ascii_letters91011def generate_slug(workspace_id, node_id):12    # Deterministic 8-char base62 slug from workspace_id + node_id13    # NOTE: duplicated in app/services/share_storage.py — keep in sync14    h = hashlib.sha256(f"{workspace_id}:{node_id}".encode()).digest()15    num = int.from_bytes(h[:8], "big")16    slug = ""17    for _ in range(8):18        slug += ALPHABET[num % 62]19        num //= 6220    return slug212223def main():24    try:25        raw = json.loads(sys.stdin.read())26        inputs = raw.get("inputs", {})2728        content = inputs.get("content", "")29        file_input = inputs.get("file", "")30        title = inputs.get("title", "Shared Content")31        share_type = inputs.get("share_type", "html")32        pin_protected = inputs.get("pin_protected", False)33        expiry_hours = int(inputs.get("expiry_hours", 72))34        expiry_hours = max(1, min(168, expiry_hours))3536        # Validate: at least one of content or file must be provided37        has_file = bool(file_input) and os.path.isfile(f"/data/input/{file_input}")38        has_content = bool(content)39        if not has_file and not has_content:40            raise ValueError("At least one of 'content' or 'file' must be provided")4142        workspace_id = os.environ.get("WORKSPACE_ID", "")43        node_id = os.environ.get("NODE_ID", "")4445        # Compute deterministic slug46        slug = generate_slug(workspace_id, node_id) if workspace_id and node_id else ""4748        # Generate PIN if protected49        pin = None50        if pin_protected:51            pin = f"{secrets.randbelow(900000) + 100000}"5253        # Build share request54        if has_file:55            share_request = {56                "type": "file",57                "title": title,58                "source_filename": file_input,59                "slug": slug,60                "workspace_id": workspace_id or None,61                "node_id": node_id or None,62                "expiry_hours": expiry_hours,63            }64        else:65            share_request = {66                "type": share_type,67                "title": title,68                "content": str(content),69                "slug": slug,70                "workspace_id": workspace_id or None,71                "node_id": node_id or None,72                "expiry_hours": expiry_hours,73            }7475        if pin:76            share_request["pin"] = pin7778        output = {79            "share_url": "",80            "slug": slug,81            "pin": pin or "",82            "_shareRequest": share_request,83        }84        print(json.dumps(output))8586    except Exception as e:87        print(json.dumps({88            "error": str(e),89            "errorType": type(e).__name__,90        }), file=sys.stderr)91        sys.exit(1)929394if __name__ == "__main__":95    main()