Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

iii-sdk

Python SDK for the iii engine.

PyPI Python License

Install

pip install iii-sdk

Hello World

from iii import register_worker

iii = register_worker("ws://localhost:49134")

def greet(data):
    return {"message": f"Hello, {data['name']}!"}

iii.register_function("hello::greet", greet)

result = iii.trigger({"function_id": "hello::greet", "payload": {"name": "world"}})
print(result)  # {"message": "Hello, world!"}

API

Operation Signature Description
Initialize register_worker(url, options?) Create an SDK instance and auto-connect
Register function iii.register_function(id, handler) Register a function that can be invoked by name
Invoke (await result) iii.trigger({"function_id": id, "payload": data}) Invoke a function and wait for the result
Invoke (fire-and-forget) iii.trigger({"function_id": id, ..., "action": TriggerAction.Void()}) Fire-and-forget
Invoke (enqueue) iii.trigger({"function_id": id, ..., "action": TriggerAction.Enqueue(queue="name")}) Route invocation through a named queue
Observe iii.observe({"function_id": ..., "args": ..., "filters": ...}, target, options?) Invoke target on every matching event of a function
Current invocation iii.current_invocation() The invocation the running handler serves
Shutdown iii.shutdown() Disconnect and stop background thread

register_worker() creates the SDK instance and auto-connects to the engine.

Registering Functions

def create_order(data):
    return {"status_code": 201, "body": {"id": "123", "item": data["body"]["item"]}}

iii.register_function("orders::create", create_order)

Invoking Functions

result = iii.trigger({"function_id": "orders::create", "payload": {"body": {"item": "widget"}}})

trigger() blocks the calling thread; await iii.trigger_async(...) works from any event loop. A call to a function this worker registered itself runs in-process once the engine confirmed it (no frames on the wire unless someone observes it): a sync handler on the calling thread, an async one on the calling loop. Pass "dispatch": "remote" to go through the engine anyway, or register the function with local_dispatch=False.

Observing Functions

Every function is observable. The target is a registered function; it receives the Observed envelope (input, output or error, caller, ...).

def big_order(envelope):
    notify(envelope["input"], envelope["output"])

iii.register_function("alerts::big-order", big_order)

observer = iii.observe(
    {"function_id": "orders::create", "filters": {"input.body.total": {"$gte": 500}}},
    "alerts::big-order",
    {"max_in_flight": 4},
)
observer.ready()            # or: await observer.ready_async()
# later
observer.dispose()

A function can hand its own events to the observers they belong to (owner delivery), and react when one is added or removed:

from iii import ObserveHooks, Observer

schedules: dict[str, set[Observer]] = {}  # expression -> observers

class CronHooks(ObserveHooks):
    delivery = "owner"
    args_format = {"type": "object", "required": ["expression"],
                   "properties": {"expression": {"type": "string"}}}

    def on_observer_added(self, obs):
        schedules.setdefault(obs.args["expression"], set()).add(obs)

    def on_observer_removed(self, obs):
        schedules[obs.args["expression"]].discard(obs)

def on_tick(tick):
    for obs in schedules.get(tick["expression"], ()):
        obs.emit(tick)  # the observer's filters are checked here

iii.register_function("cron::on-tick", on_tick, observe=CronHooks())

Inside any handler, iii.current_invocation() returns the running invocation (function_id, invocation_id, caller, activation, observe_depth). Sync handlers run on a thread of their own started in a copy of the caller's context, so the current invocation and the OpenTelemetry context follow them.

Trigger APIs (deprecated)

register_trigger and register_trigger_type keep working in 0.25 but are deprecated: they emit a DeprecationWarning and log a warning once per process. Use iii.observe(source, target) and register_function(id, handler, observe=ObserveHooks(...)) instead. See the migration guide.

Development

Install in development mode

pip install -e .

Type checking

mypy src

Linting

ruff check src

Resources

Metadata

Release files for iii-sdk 0.25.0rc4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for iii-sdk 0.25.0rc4
File Size Uploaded Provenance
iii_sdk-0.25.0rc4.tar.gz 304.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for iii-sdk 0.25.0rc4
File Interpreter ABI Platform
iii_sdk-0.25.0rc4-py3-none-any.whl Python 3 none any Details

Total release size: 405.3 kB

Release files / iii_sdk-0.25.0rc4.tar.gz

Download URL iii_sdk-0.25.0rc4.tar.gz
Size 304.8 kB
Tags Source
SHA-256 checksum
How to use checksums
4d745d5c5c2829b1c31cd7b9a9e994bd97c4b91a57e8a808f0776d4c32674c4c
BLAKE2b-256 checksum
How to use checksums
ab3edaa3a7e598b0e05f7cce135ee3f6a38244d9d579b8ed7d2ef8f86f70137a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / iii_sdk-0.25.0rc4-py3-none-any.whl

Download URL iii_sdk-0.25.0rc4-py3-none-any.whl
Size 100.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6b9b1e71ef77016ce34f568180a63e932a7fb519946e94273f7cf19e1bdbc25b
BLAKE2b-256 checksum
How to use checksums
e0d03aa59ba135c1ec3e1fd313acc9b9ecbc9351f85b2caccb9ca973e09f5cf7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for iii-sdk 0.25.0rc4

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page