Skip to content

Backend (Python)

In Blobit, backend nodes must inherit from node_utils.BaseNode. This base class handles data normalization (ensuring everything is a list of frames), progress reporting, and output packing.

from node_utils import BaseNode
class MyCustomNode(BaseNode):
def execute(self, data: dict, context=None) -> dict:
# 1. Get Inputs (Using Standard Helper)
# CRITICAL: Use self.get_input() - it checks Inputs > Widgets > Properties
input_image = self.get_input(data, "InputImage")
strength = self.get_input(data, "Strength", 1.0)
if not input_image:
return {"success": False, "log": "No input provided"}
# 2. Normalize to frames (The Production Batch Pattern)
# Even if you expect 1 item, always normalize.
tl_image = self.normalize_to_frames(input_image)
# 3. Sync Timelines
# Ensures all inputs match the "master" length (usually the image count)
(s_image, total_frames) = self.sync_to_master(tl_image)
outputs = []
# 4. Iterate (Safe Batch Processing)
for i in range(total_frames):
self.report_progress((i / total_frames) * 100, f"Processing frame {i+1}/{total_frames}")
# Access safe frame data (handle potential None inputs in batch)
img_path = s_image[i][0] if s_image[i] else None
if not img_path:
outputs.append(None)
continue
try:
# 5. Logic
# Load Image (handles URL/Path/Tensor automatically)
pil_img = self.load_image(img_path)
# ... Do processing ...
processed_img = self.do_something(pil_img, strength)
# 6. Save
# Saves to temp and returns the HTTP path string
saved_path = self.save_image(processed_img, prefix="output")
outputs.append(saved_path)
except Exception as e:
# Handle individual frame errors without crashing the whole batch
print(f"Error frame {i}: {e}")
outputs.append(None)
# 7. Pack and Return
# Dictionary with "output": [list_of_paths]
return self.pack_outputs(outputs)
# Factory function needed for dynamic loading
def process(data, context=None):
return MyCustomNode().process(data, context)

The data argument contains all inputs sent from the frontend.

  • Widgets: Values from sliders, text boxes.
  • Inputs: Data from connected nodes.

Safely retrieves an input by name. Checks Connections -> Widgets -> Properties -> Root.

threshold = self.get_input(data, "threshold", 0.5)

CRITICAL: Converts any input (single string, None, list) into a standard [[item], [item]] batch format.

  • If input is None -> returns [[]].
  • If input is "path/img.png" -> returns [["path/img.png"]].
  • If input is ["A", "B"] -> returns [["A"], ["B"]].

Blobit relies on frame synchronization to handle inputs of varying lengths (e.g., 1 image vs 10 prompts).

Synchronizes multiple lists to match the length of the master list.

  • Use Case: One primary input (e.g., Image) determines the frame count. Other inputs cycle to match.
(s_img, s_prompts, count) = self.sync_to_master(images, prompts)

Synchronizes all inputs to the maximum length found.

  • Use Case: All inputs are equal peers. The result length is the maximum length of any input.
(s_img, s_mask, count) = self.sync_frames(images, masks)

Formats the result for the frontend.

  • output_list should be a list where each element corresponds to an output slot.
  • Example: self.pack_outputs(image_results, mask_results) for a node with two outputs.

Blobit provides a suite of helper functions for data retrieval, file management, and synchronization.

View Python Helper Reference