Airalogy protocol execute sandbox
Project description
airalogy-engine (Python)
Airalogy protocol execution sandbox for Python. Run protocol packages (parse, assign, validate) inside a secure BoxLite sandbox, and execute AIMD workflow transition assignments across protocol Records.
Installation
pip install airalogy-engine
Sandbox Image
The engine runs protocol code in a BoxLite sandbox. You can use either a remote Docker image or a local OCI rootfs directory.
Remote Image
from airalogy_engine import AiralogyEngine
engine = AiralogyEngine(
protocol_path="/path/to/your/protocol",
image="numbcoder/airalogy-engine:latest",
)
result = await engine.parse_protocol()
Local OCI Rootfs (Recommended)
Build and export the image locally for faster, offline execution:
cd packages/runtime/airalogy-engine-image
docker build -t airalogy-engine:latest .
docker save airalogy-engine:latest -o airalogy-engine-image.tar
mkdir airalogy-engine-image
tar -xf airalogy-engine-image.tar -C airalogy-engine-image
Then use rootfs_path:
from airalogy_engine import AiralogyEngine
engine = AiralogyEngine(
protocol_path="/path/to/your/protocol",
rootfs_path="./airalogy-engine-image",
)
result = await engine.parse_protocol()
If neither
imagenorrootfs_pathis provided, the engine falls back to the default remote imagenumbcoder/airalogy-engine:latest.
Usage
import asyncio
from airalogy_engine import AiralogyEngine
async def main():
protocol_path = "/path/to/your/protocol"
rootfs_path = "/path/to/airalogy-engine-image" # or use image="..." instead
engine = AiralogyEngine(
protocol_path=protocol_path,
rootfs_path=rootfs_path,
boxlite_home="/tmp/airalogy-engine-worker-1",
)
# 1. Parse the protocol
result = await engine.parse_protocol(env_vars={"API_KEY": "xxx"})
print(result["data"]["meta_data"])
print(result["data"]["json_schema"])
# 2. Assign a variable
result = await engine.assign_variable(
var_name="duration",
dependent_data={"seconds": 3600},
env_vars={"API_KEY": "xxx"},
)
print(result["data"])
# 3. Validate variables
result = await engine.validate_variables(
variables={"seconds": 60, "duration": "PT1M"},
)
print(result["data"])
# 4. Import records from a file inside the protocol directory
result = await engine.import_records(input_filename="records.json")
print(result["data"]["records"])
await engine.close()
asyncio.run(main())
You can also use the engine as an async context manager:
async with AiralogyEngine(
protocol_path=protocol_path,
rootfs_path=rootfs_path,
boxlite_home="/tmp/worker-1",
) as engine:
result = await engine.parse_protocol()
Workflow Usage
AiralogyWorkflowEngine executes fenced workflow definitions from a workflow.aimd file. It resolves transition.inputs, runs workflow-level Python assigners, exposes outputs under ${transition_id.outputs.key}, and applies transition.assign into target Record drafts. It does not persist Records or create Record versions; callers should save returned Record drafts through their platform or database layer.
import asyncio
from airalogy_engine import AiralogyWorkflowEngine
async def main():
engine = AiralogyWorkflowEngine(
workflow_path="/path/to/workflow.aimd",
rootfs_path="/path/to/airalogy-engine-image",
)
result = await engine.run(
records={
"measurement": {"data": {"var": {"raw_data": [1, 2, 3]}}},
"literature_review": {"data": {"var": {"summary": "known background"}}},
},
)
print(result["data"]["records"]["analysis"])
print(result["data"]["transition_outputs"])
await engine.close()
asyncio.run(main())
For local tests or trusted scripts, pass assigner_runtime="local" to execute workflow assigners in the host Python process instead of BoxLite.
API
| API | Description |
|---|---|
AiralogyEngine(protocol_path, boxlite_home=None, image=None, rootfs_path=None, timeout=300, memory_mib=512, cpus=1, auto_stop=True) |
Create an engine bound to one protocol path, BoxLite runtime home, and sandbox configuration |
AiralogyWorkflowEngine(workflow_path, workflow_id=None, assigner_runtime="sandbox", boxlite_home=None, image=None, rootfs_path=None, timeout=300, memory_mib=512, cpus=1, auto_stop=True) |
Create an engine bound to one workflow.aimd file or directory and sandbox configuration for workflow-level assigners |
engine.parse_protocol(env_vars=None, timeout=None, debug=False, log_file="protocol_debug.log") |
Parse the engine protocol and return schema, metadata, fields |
engine.assign_variable(var_name, dependent_data, env_vars=None, timeout=None, debug=False, log_file="protocol_debug.log") |
Assign a variable using assigner functions |
engine.validate_variables(variables, env_vars=None, timeout=None, debug=False, log_file="protocol_debug.log") |
Validate variable values against the protocol model |
engine.import_records(input_filename, input_format="auto", allow_extra_var_fields=False, require_complete_quiz=False, include_template_defaults=True, validate_model_sync=True, env_vars=None, timeout=None, debug=False, log_file="protocol_debug.log") |
Import a protocol-local JSON/JSONL/CSV/TSV file into Airalogy record JSON objects |
workflow_engine.run(records, transition_ids=None, transition_outputs=None, node_iterations=None, max_passes=1, env_vars=None, timeout=None, debug=False, log_file="workflow_debug.log") |
Execute workflow transitions in declaration order and return Record drafts, transition outputs, skipped transitions, attempts, and node iteration counters |
workflow_engine.run_transition(transition_id, records, transition_outputs=None, node_iterations=None, env_vars=None, timeout=None, debug=False, log_file="workflow_debug.log") |
Execute one workflow transition and return updated Record drafts |
engine.box_status() |
Return the current BoxLite BoxStateInfo, or None when the engine has no current box |
await engine.stop() |
Stop this engine's current box without closing the engine |
await engine.close() |
Stop this engine's current box and release its BoxLite runtime reference |
All engine methods are async and return a dict with success, message, and data keys.
Engine parameters:
protocol_path: Protocol package directory. It must containprotocol.aimdand is mounted writable at/home/airalogy/protocols/protocolinside the sandbox.boxlite_home: BoxLite runtime home directory. Use a distinct value for each OS process when running multiple workers.image: Remote Docker image name (e.g.,"numbcoder/airalogy-engine:0.1").rootfs_path: Path to a local OCI rootfs directory (overridesimage).timeout: Execution timeout in seconds (default: 300). The sandboxed process will be killed once it times out.memory_mib: Memory limit in MiB (default: 512).cpus: CPU limit (default: 1).auto_stop: Stop the box after each command whenTrue(default). Set toFalseto keep one running box untilstop()orclose().
Concurrency
Use one AiralogyEngine instance per protocol and worker process. Concurrent async operations through one engine run on its current box:
engine = AiralogyEngine(
protocol_path=protocol_path,
rootfs_path=rootfs_path,
boxlite_home="/tmp/worker-1",
auto_stop=False,
)
results = await asyncio.gather(
engine.parse_protocol(),
engine.validate_variables({"seconds": 60, "duration": "PT1M"}),
)
await engine.stop()
BoxLite locks each runtime home per OS process. Two independent processes must not share the same boxlite_home or default ~/.boxlite; give each process a distinct directory, for example /tmp/airalogy-worker-1 and /tmp/airalogy-worker-2.
Testing
cd python
uv sync
# Default: local OCI rootfs mode
uv run pytest tests/ -v
# Custom rootfs path
uv run pytest tests/ -v --sandbox-mode=rootfs --rootfs-path=../../runtime/airalogy-engine-image/airalogy-engine-image
# Remote image mode
uv run pytest tests/ -v --sandbox-mode=image --sandbox-image=numbcoder/airalogy-engine:latest
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file airalogy_engine-0.0.6.tar.gz.
File metadata
- Download URL: airalogy_engine-0.0.6.tar.gz
- Upload date:
- Size: 18.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06ec6dce88de5a627316736d88deec08ab22987abaf0e1df000a6874dd9c8d04
|
|
| MD5 |
28203e5f0807e538f0655618320489d6
|
|
| BLAKE2b-256 |
406c3a8c501fcab0296d42d00cf557848fc64a31a32e6a04e254ca395f66f7cc
|
Provenance
The following attestation bundles were made for airalogy_engine-0.0.6.tar.gz:
Publisher:
release.yml on airalogy/airalogy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airalogy_engine-0.0.6.tar.gz -
Subject digest:
06ec6dce88de5a627316736d88deec08ab22987abaf0e1df000a6874dd9c8d04 - Sigstore transparency entry: 2036373475
- Sigstore integration time:
-
Permalink:
airalogy/airalogy@fe3edbc41a9b2a00b915fd5940e6a69d78238239 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/airalogy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fe3edbc41a9b2a00b915fd5940e6a69d78238239 -
Trigger Event:
push
-
Statement type:
File details
Details for the file airalogy_engine-0.0.6-py3-none-any.whl.
File metadata
- Download URL: airalogy_engine-0.0.6-py3-none-any.whl
- Upload date:
- Size: 21.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8397b73524f2fb2d3c42afee46afa0d57e20b13e9342f105cde8708dee72c87d
|
|
| MD5 |
bb4b3d3d1bc20399b53d14f68cb4900a
|
|
| BLAKE2b-256 |
0a406ecc9098912cee83cf186e0d5d285a8cd66d60037e3ec0913f06b6eceb7e
|
Provenance
The following attestation bundles were made for airalogy_engine-0.0.6-py3-none-any.whl:
Publisher:
release.yml on airalogy/airalogy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airalogy_engine-0.0.6-py3-none-any.whl -
Subject digest:
8397b73524f2fb2d3c42afee46afa0d57e20b13e9342f105cde8708dee72c87d - Sigstore transparency entry: 2036373744
- Sigstore integration time:
-
Permalink:
airalogy/airalogy@fe3edbc41a9b2a00b915fd5940e6a69d78238239 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/airalogy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fe3edbc41a9b2a00b915fd5940e6a69d78238239 -
Trigger Event:
push
-
Statement type: