Build Action Example
This example demonstrates how to use ActraRuntime.build_action() and runtime.buildAction() when evaluating actions outside decorators or wrapped functions.
This is one of the most important integration patterns for real production systems where the application does not directly call a protected function.
Perfect for:
- API frameworks
- message queues
- MCP servers
- background workers
- AI agents
- webhook processors
Core Mental Model
External payload -> build action -> evaluate -> enforce decision
Instead of relying on decorator interception, you manually construct the Actra action payload from external request data.
Example
- Python
- JavaScript
"""
Build Action Example
This example demonstrates how to use ActraRuntime.build_action
when evaluating actions outside decorators.
"""
from actra import Actra, ActraRuntime
schema_yaml = """
version: 1
actions:
refund:
fields:
amount: number
actor:
fields:
role: string
snapshot:
fields:
fraud_flag: boolean
"""
policy_yaml = """
version: 1
rules:
- id: block_large_refund
scope:
action: refund
when:
subject:
domain: action
field: amount
operator: greater_than
value:
literal: 1000
effect: block
"""
policy = Actra.from_strings(schema_yaml, policy_yaml)
runtime = ActraRuntime(policy)
runtime.set_actor_resolver(lambda ctx: {"role": "support"})
runtime.set_snapshot_resolver(lambda ctx: {"fraud_flag": False})
request_data = {
"amount": 200
}
def fake_handler(amount):
pass
action = runtime.build_action(
func=fake_handler,
action_type="refund",
args=(),
kwargs=request_data,
ctx=None,
)
decision = runtime.evaluate(action)
print("Decision:", decision)
import { Actra, ActraRuntime } from "@getactra/actra";
const schemaYaml = `
version: 1
actions:
refund:
fields:
amount: number
actor:
fields:
role: string
snapshot:
fields:
fraud_flag: boolean
`;
const policyYaml = `
version: 1
rules:
- id: block_large_refund
scope:
action: refund
when:
subject:
domain: action
field: amount
operator: greater_than
value:
literal: 1000
effect: block
`;
const policy = await Actra.fromStrings(schemaYaml, policyYaml);
const runtime = new ActraRuntime(policy);
runtime.setActorResolver(() => ({ role: "support" }));
runtime.setSnapshotResolver(() => ({ fraud_flag: false }));
const requestData = {
amount: 200,
};
const action = runtime.buildAction("refund", requestData);
const decision = runtime.evaluate(action);
console.log("Decision:", decision);
Why This Example Matters
This is the canonical integration pattern for non-decorator systems.
It is especially powerful for:
- FastAPI request handlers
- Celery workers
- Kafka consumers
- MCP tool servers
- LLM tool routing
- queue processors
because these systems often receive external payloads instead of direct Python or JavaScript function calls.
Python-Specific Advantage
The Python version demonstrates a major SDK strength:
function signature introspection
build_action() can inspect a handler signature and safely include only valid schema fields.
This prevents:
- request objects
- framework metadata
- transport wrappers
- hidden context objects
from leaking into policy evaluation.
JavaScript-Specific Advantage
The JavaScript version demonstrates the payload-first integration style, which is ideal for:
- Express / Fastify
- edge functions
- webhook handlers
- tool execution frameworks
Expected Output
Decision: { effect: "allow" }