Skip to main content
What this builds. A transformation with a mix of typed inputs and outputs, run twice. You’ll end up with. A successful run whose outputs come back as native Python values, plus a demonstration of the client-side input-key validation that fires before any request.
"""
Typed I/O + running.

`inputs` / `outputs` map each name to an IOType (optionally via IOConfig for a
description). The run result's `outputs` are unwrapped to native Python values;
unknown input keys are rejected client-side before the call.
"""

from vectorshift.transformation import (
    IOConfig,
    IOType,
    Transformation,
    TransformationInvalidSchema,
    TransformationStatus,
)

# Mixed-type schema: string + list in, string + int out.
t = Transformation.new(
    name="summarize_words",
    function_name="summarize_words",
    inputs={
        "title": IOConfig(io_type=IOType.STRING, description="heading"),
        "words": IOType.LIST,   # bare IOType also works
    },
    outputs={
        "heading": IOType.STRING,
        "count": IOType.INT,
    },
    function=(
        "def summarize_words(title, words):\n"
        "    return {'heading': title.upper(), 'count': len(words)}"
    ),
)

# 1. Run — outputs come back as native Python types.
res = t.run(inputs={"title": "fruits", "words": ["apple", "pear", "plum"]})
print(f"1. status: {res['status']}")
print(f"   outputs: {res['outputs']}")
print(f"   success? {res['status'] == TransformationStatus.SUCCESS}")

# 2. Unknown input key → TransformationInvalidSchema (raised before any request).
try:
    t.run(inputs={"title": "x", "typo": 1})
except TransformationInvalidSchema as e:
    print(f"2. rejected unknown key: {e}")

t.delete()
print("\nDone.")

Expected output

1. status: success
   outputs: {'heading': 'FRUITS', 'count': 3}
   success? True
2. rejected unknown key: Unknown input keys ['typo']; expected a subset of ['title', 'words']
Done.
IOType maps Python types to the wire vocabulary (strstring, intint32, listvec<any>, vectorshift.Filefile, …). The run result’s outputs are unwrapped from the engine’s DataType envelope, so you get plain dict / list / scalar values back.

See also

From a function

Let annotations drive the schema instead of declaring it.

Async API

arun and the other async siblings.

Reference

IOType, IOConfig, TransformationRunResult.