Skip to main content

Simplified component builder for the Koios platform

Project description

Koios Component Builder

SDK and CLI for building component libraries for the Koios platform. Components are reusable logic blocks with typed inputs and outputs that get wired together and executed by the Koios Component Engine at configurable scan rates.

Installation

pip install koios-component-builder

Requires Python 3.12+.

Quick Start

1. Write a component

# my_library/math_ops.py
from koios_component_builder import (
    Component,
    ComponentCategory,
    ComponentIcon,
    Input,
    Output,
)


class SimpleAdder(Component):
    """A component that adds two numbers."""

    class Meta:
        icon = ComponentIcon.SUM
        category = ComponentCategory.MATH

    a: Input[float] = Input(default=0.0, description="First number")
    b: Input[float] = Input(default=0.0, description="Second number")
    result: Output[float] = Output(default=0.0, description="Sum of a and b")

    def execute(self) -> None:
        self.result = self.a + self.b

2. Define a library

# my_library/__init__.py
from koios_component_builder import ComponentLibrary
from .math_ops import SimpleAdder, Multiplier


class MyLibrary(ComponentLibrary):
    """My custom component library."""

    name = "my-library"
    major = 1
    minor = 0
    patch = 0
    description = "Custom math components"

    components = [SimpleAdder, Multiplier]


__all__ = ["MyLibrary", "SimpleAdder", "Multiplier"]

3. Export

koios-component-builder export my_library/

This creates a .kcl (Koios Component Library) package in dist/ that can be uploaded to Koios.

Component Lifecycle

When deployed to Koios, each execution cycle:

  1. Field Injection — Input and config values are set on the component
  2. Setupsetup() runs once before the first execute() (if overridden)
  3. Executeexecute() runs with current input values
  4. Output Propagation — Output values are sent to wired destinations

Your component implements setup() (optional) and execute() — the engine handles all wiring and data flow.

setup() — One-Time Initialization

Override setup() for expensive work that should only happen once, such as loading models, creating registries, or parsing configuration. All field values are available when setup() runs.

If setup() raises an exception, the component is marked FAILED and retried on the next cycle.

class UnitConverter(Component):
    """Converts Fahrenheit to Celsius using pint."""

    class Meta:
        icon = ComponentIcon.TRANSFORM
        category = ComponentCategory.TRANSFORM

    value: Input[float] = Input(default=0.0, description="Temperature in °F")
    decimals: NumberConfig = NumberConfig(
        default=2, min_value=0, max_value=6, description="Decimal places"
    )
    result: Output[float] = Output(default=0.0, description="Temperature in °C")

    def setup(self) -> None:
        from pint import UnitRegistry
        self._ureg = UnitRegistry()  # ~80ms — only runs once

    def execute(self) -> None:
        temp = self._ureg.Quantity(self.value, self._ureg.degF)
        self.result = round(temp.to(self._ureg.degC).magnitude, int(self.decimals))

For resources shared across all instances of the same component class, use a class-level guard instead:

class MyComponent(Component):
    def execute(self) -> None:
        if not hasattr(MyComponent, "_shared_model"):
            MyComponent._shared_model = load_model()
        self.result = MyComponent._shared_model.predict(self.input)

Field Types

Input / Output

from koios_component_builder import Component, Input, Output

class ExampleComponent(Component):
    # Supported types: float, int, bool, str, list, dict
    temperature: Input[float] = Input(default=0.0, description="Temperature in Celsius")
    count: Input[int] = Input(default=0, description="Item count")
    enabled: Input[bool] = Input(default=True, description="Enable processing")
    mode: Input[str] = Input(default="auto", description="Operating mode")

    alarm: Output[bool] = Output(default=False, description="High temperature alarm")
    status: Output[str] = Output(default="ok", description="Current status")

    def execute(self) -> None:
        if self.enabled and self.temperature > 100:
            self.alarm = True
            self.status = "overtemp"
        else:
            self.alarm = False
            self.status = "ok"

Config Fields

Config fields are set when the component instance is created in the Koios UI and remain constant during execution. They appear as configuration controls on the component node.

from koios_component_builder import (
    Component, Input, Output,
    NumberConfig, StringConfig, ChoiceConfig, BoolConfig,
)

class ConfigurableComponent(Component):
    # Numeric with min/max validation
    threshold: NumberConfig = NumberConfig(
        default=75.0, min_value=0.0, max_value=100.0,
        description="Alert threshold"
    )

    # Dropdown with predefined options
    mode: ChoiceConfig = ChoiceConfig(
        default="average", choices=["average", "median", "max"],
        description="Calculation mode"
    )

    # Text with optional regex validation
    label: StringConfig = StringConfig(
        default="Sensor", description="Display label"
    )

    # Boolean toggle
    verbose: BoolConfig = BoolConfig(
        default=False, description="Enable verbose output"
    )

    value: Input[float] = Input(default=0.0)
    alert: Output[bool] = Output(default=False)

    def execute(self) -> None:
        self.alert = self.value > self.threshold

HistoryInput

HistoryInput fields provide access to historical tag data via InfluxDB. They must be wired to a HISTORY connector on the environment canvas.

from koios_component_builder import Component, HistoryInput, Output

class TrendAnalyzer(Component):
    """Calculates trend from historical data."""

    sensor_history: HistoryInput = HistoryInput(
        description="Historical sensor readings"
    )
    trend: Output[float] = Output(default=0.0, description="Trend slope")

    def execute(self) -> None:
        if self.sensor_history is None:
            return  # Not wired to a history connector

        # Fetch last hour of data, max 200 samples
        df = self.sensor_history.get_history(
            period_seconds=3600,
            num_samples=200,
        )
        # df has columns: timestamp, value
        if not df.empty:
            values = df["value"].tolist()
            self.trend = values[-1] - values[0]

Component Metadata

Customize how components appear in the Koios UI:

class MyComponent(Component):
    """Component description shown in the UI."""

    class Meta:
        icon = ComponentIcon.CHART_LINE       # Tabler icon name
        category = ComponentCategory.ANALYSIS  # UI grouping
        canvas_width = 8                       # Node width (4–15 grid units, default: 6)
        canvas_minimal = False                 # Compact mode (no header/footer)

        # Optional: component-specific version (overrides library version)
        major = 2
        minor = 1
        patch = 0
        prerelease = "beta"

Icons — Any Tabler icon name in kebab-case. Common constants: SUM, CALCULATOR, CHART_LINE, GAUGE, THERMOMETER, FILTER, WAVE_SINE, TOGGLE_LEFT, ALERT_TRIANGLE, TRANSFORM.

Categories — Standard constants: MATH, STATISTICS, LOGIC, ANALYSIS, TRANSFORM, FILTER, CONTROL, MONITORING. Custom strings are also accepted.

Dependencies

Libraries can declare third-party Python package dependencies. The builder resolves them against the Koios platform manifest to determine what's pre-installed in the container vs. what needs bundling.

class MyProtocolLibrary(ComponentLibrary):
    name = "my-protocol-library"
    major = 1
    minor = 0
    dependencies = ["crcmod", "minimalmodbus>=2.0"]
    components = [MyDevice]

Three tiers:

Tier Description Example
Platform Pre-installed in the Koios container numpy, pandas, scipy
Bundled Downloaded and included in the .kcl crcmod, pint
SDK Always available (koios-component-builder itself) pydantic, click
# Export without bundling (warns about non-platform deps)
koios-component-builder export my_library/

# Bundle non-platform dependencies into the .kcl
koios-component-builder export my_library/ --include-deps

# Target specific platforms
koios-component-builder export my_library/ --include-deps \
    --platform manylinux2014_x86_64 --platform manylinux2014_aarch64

# List available platform packages
koios-component-builder platform-packages

Package Format

The export command creates a .kcl (Koios Component Library) package — a ZIP archive:

my-library-1.0.0.kcl
├── manifest.json                              # Library metadata
├── my_library-1.0.0-py3-none-any.whl         # Python wheel
└── deps/                                      # Bundled dependency wheels (if any)
    ├── crcmod-1.7-cp312-...-x86_64.whl
    └── crcmod-1.7-cp312-...-aarch64.whl

Security Audit

Every .kcl export automatically runs a static security analysis on your source code. The audit classifies patterns into three tiers:

Tier Meaning Effect
✅ ALLOW Safe — no friction Not reported
⚠️ REVIEW Flagged for attention, but build continues Logged as warning, yellow badge in Koios UI
❌ DENY Blocked Export fails unless --allow-unsafe is used

What gets flagged

DENY — patterns that have no legitimate use in a component:

  • Dangerous imports: os, subprocess, socket, threading, pickle, ctypes, sys, etc.
  • Unsafe builtins: eval(), exec(), compile(), __import__()
  • Sandbox escape patterns: __subclasses__, __builtins__, __code__, __globals__

REVIEW — patterns that are often legitimate but worth being aware of:

  • Filesystem imports: pathlib, io, csv (common for loading AI model files in setup())
  • open() calls (useful for reading model weights or config files)
  • Unknown third-party packages not in the platform allow-list

Audit command

Run the audit without building a .kcl:

# Audit and print results
koios-component-builder audit my_library/

# Output as JSON (for CI integration)
koios-component-builder audit my_library/ --json

# Audit with a custom policy
koios-component-builder audit my_library/ --policy security_policy.yaml

Exit code is 1 if any DENY findings are present, 0 otherwise — suitable for CI pipelines.

Custom policies

Override the defaults by providing a YAML policy file:

# security_policy.yaml
policy_version: "1.0"

imports:
  allow:
    - my_internal_sdk      # Trust your own internal package
    - requests             # Allow HTTP if your components genuinely need it
  deny:
    - pandas               # Tighten if you want to forbid heavy deps

builtins:
  review:
    - open                 # Already REVIEW by default; shown here for reference

attributes:
  deny:
    - __dict__             # Add to deny if you want stricter introspection rules

Policy overrides work bidirectionally — you can move items to a less restrictive tier (e.g. DENY → ALLOW) or a more restrictive one (e.g. ALLOW → DENY). Items are removed from conflicting tiers automatically.

koios-component-builder export my_library/ --policy security_policy.yaml

Overriding for power users

If your library has a legitimate reason for a flagged pattern (e.g. loading an ONNX model from disk in setup()), the recommended approach is to use pathlib / io which are REVIEW-tier rather than DENY. For edge cases that genuinely need a denied import:

koios-component-builder export my_library/ --allow-unsafe

The .kcl is still created, but the security_audit in manifest.json records passed: false — the Koios UI will display a warning badge when the library is uploaded.

CLI Reference

# Export a library to a .kcl package
koios-component-builder export <source_path> [OPTIONS]

Options:
  -o, --output PATH        Output directory (default: dist/)
  --include-deps           Bundle non-platform dependencies
  --platform TEXT          Target platform tag (repeatable)
  --allow-unsafe           Create .kcl even with DENY findings
  --policy PATH            Custom security policy YAML file

# Audit a library without building
koios-component-builder audit <source_path> [OPTIONS]

Options:
  --policy PATH            Custom security policy YAML file
  --json                   Output results as JSON

# List pre-installed platform packages
koios-component-builder platform-packages

Local Testing

Test components locally before deploying:

from my_library.math_ops import SimpleAdder

adder = SimpleAdder("test-instance")
adder.a = 5.0
adder.b = 3.0
adder.execute()

print(f"Result: {adder.result}")  # Result: 8.0

License

Copyright Ai-OPs, Inc. All rights reserved.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

koios_component_builder-1.0.0.tar.gz (89.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

koios_component_builder-1.0.0-py3-none-any.whl (52.2 kB view details)

Uploaded Python 3

File details

Details for the file koios_component_builder-1.0.0.tar.gz.

File metadata

  • Download URL: koios_component_builder-1.0.0.tar.gz
  • Upload date:
  • Size: 89.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for koios_component_builder-1.0.0.tar.gz
Algorithm Hash digest
SHA256 fbf429f243320fe60b926079b025b822ea781f6418ed2c640cb4e1a7d413901d
MD5 8b0429e6dc939dee2ef62a22a8e4130e
BLAKE2b-256 6912cb63399d73a96fd2aeb922a0fe997f5eb75b1819996afa8d8583b45f8fb1

See more details on using hashes here.

Provenance

The following attestation bundles were made for koios_component_builder-1.0.0.tar.gz:

Publisher: release.yml on Ai-Ops-Inc/koios-component-builder

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file koios_component_builder-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for koios_component_builder-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5cae3c94a2f5dd00e976e2bfe2df96ac01d730f866726b915b7c3f54f6a623ca
MD5 faceaa9f7107f0f48acb3deeda545a5f
BLAKE2b-256 ea4373a66e29b76a89cb67ecbb5079d2a7dadd8ac9252b9698542e5eabfc3300

See more details on using hashes here.

Provenance

The following attestation bundles were made for koios_component_builder-1.0.0-py3-none-any.whl:

Publisher: release.yml on Ai-Ops-Inc/koios-component-builder

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page