π§± How to Create Your Own Component
You can create a custom component from scratch locally and then upload it to the PipeLogic workspace. This gives you complete control over the structure, logic, and configuration.
You can use the PPL Tool to initialize and create advanced components.
π οΈ What Weβre Building
A PipeLogic component that takes an input of type Image and returns a grayscale image using OpenCV. The input and output types are both Image.
Step-by-Step Instructions to Create your own Component
π STEP 1: Create the component folder
Open your WSL terminal and run:
mkdir convert_image_grayscale
cd convert_image_grayscale
π STEP 2: Create folders and files
Run these commands to create the needed subfolders and files:
mkdir src
touch component.yml
touch .pipecomponent
touch src/requirements.txt
touch src/main.py
π¦ STEP 3: Add Dependencies to requirements.txt
Open src/requirements.txt
in your preferred text editor and add:
pipelogic
numpy
opencv-python-headless
π STEP 4: Edit component.yml
Open component.yml
in your preferred text editor and update its contents with:
Convert Image to Grayscale
language: py
platform: linux/amd64
build_system: 2
worker:
input_type: "Image"
output_type: "Image"
π STEP 5: Add the source code to main.py
Open src/main.py
in your preferred text editor and update its contents with:
from pipelogic.worker import run, config
import pipelogic
import numpy as np
import cppipe
import cv2
Image_BGR = cppipe.create_named('Image.BGR', cppipe.create_tuple([]))
Image_RGB = cppipe.create_named('Image.RGB', cppipe.create_tuple([]))
Image_GRAY = cppipe.create_named('Image.GRAY', cppipe.create_tuple([]))
Image_RGBA = cppipe.create_named('Image.RGBA', cppipe.create_tuple([]))
Image_BGRA = cppipe.create_named('Image.BGRA', cppipe.create_tuple([]))
# converts all possible image formats into gray image
def gray_conversion(Image):
image_data = np.array(Image.data, dtype='uint8')
if Image.format == Image_BGR:
image = np.reshape(image_data, (Image.height, Image.width, 3))
return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
elif Image.format == Image_RGB:
image = np.reshape(image_data, (Image.height, Image.width, 3))
return cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
elif Image.format == Image_RGBA:
image = np.reshape(image_data, (Image.height, Image.width, 4))
return cv2.cvtColor(image, cv2.COLOR_RGBA2GRAY)
elif Image.format == Image_BGRA:
image = np.reshape(image_data, (Image.height, Image.width, 4))
return cv2.cvtColor(image, cv2.COLOR_BGRA2GRAY)
else:
image = np.reshape(image_data, (Image.height, Image.width, 1))
return image
def convert_gray(Image):
gray_image = gray_conversion(Image)
return {
"height": Image.height,
"width": Image.width,
"data": gray_image.flatten().tobytes(),
"format": pipelogic.types.Named(pipelogic.types.Tuple(()), Image_GRAY)
}
run(convert_gray)
π§± Component Folder Structure
After you create a component, this is what the folder structure look like:
πΉ General Structure
.
βββ component.yml
βββ .pipecomponent
βββ src
β βββ requirements.txt
β βββ main.py
To learn more about how this structure is generated and what each file means, visit the Component Guide page.
Example: Structure of a Custom Component Like Dot Product
Note: This is a custom example that shows what a complete component might look like, including test folders for validating input/output behavior.The dot product is used as an example because it takes two inputs (vectors) and produces one output (a scalar), which is a common pattern in many data processing components.Each test folder (test_0
, test_1
, etc.) includes input and expected output files. These tests can help you validate the component logic during development.
.
βββ component.yml
βββ .pipecomponent
βββ src
β βββ requirements.txt
β βββ main.py
βββ tests
βββ test_0
β βββ input_0.txt
β βββ input_1.txt
β βββ output_0.txt
βββ test_1
βββ input_0.txt
βββ input_1.txt
βββ output_0.txt
Once your component structure looks like this and you've added your logic, you're ready to push it to the PipeLogic workspace.
- Make sure you're in the main folder:
cd convert_image_grayscale
- Login (only once):
ppl login
- Initialize the component:
ppl init
- Push your component:
ppl release
Add Parameters to Make Your Component Flexible
Now that you've successfully created your own component, you can make it dynamic by adding parameters. This allows users to customize its behavior directly from the UI without changing the code!
Why Add Parameters?
- Make your component reusable for different inputs
- Allow users to set values like
resize_shape
,crop coordinates
, etc. - Improve user control and flexibility
β
1. Define Parameters in component.yml
config_schema:
resize_shape:
type: (UInt64, UInt64)
description: "Resize image to (height, width)"
This tells PipeLogic to show a UI field for
resize_shape
.
β
2. Use the Parameter in Your Code (main.py
)
resize_shape = config.resize_shape # (height, width)
resized_image = cv2.resize(image, resize_shape)
β 3. Release Your Component Again
ppl release
Example config_schema
for multiple parameters
config_schema:
resize_shape:
type: (UInt64, UInt64)
apply_blur:
type: Bool
blur_radius:
type: UInt64
π Important Notes
- You can define as many parameters as needed
- Each parameter must have a
name
and atype
- Common types:
String
,UInt64
,Float64
,Bool
,Tuple