Skip to main content

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

"""
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)

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" }