Initial commit: Python Example Pack for Attune

Includes:
- 3 Python actions (hello, http_example, read_counter)
- 1 counter trigger type
- 1 counter sensor (Python, keystore-backed, per-rule state)
- 1 example rule (count_and_log)
- requirements.txt with requests and pika
- README with full usage documentation
This commit is contained in:
2026-02-11 08:18:43 -06:00
commit f3c159913e
15 changed files with 1306 additions and 0 deletions

21
actions/hello.py Normal file
View File

@@ -0,0 +1,21 @@
#!/usr/bin/env python3
"""
Hello Action - Python Example Pack
A minimal Python action that returns "Hello, Python".
Demonstrates the basic structure of a Python action in Attune.
"""
import json
import sys
def run(**kwargs):
"""Return a simple greeting message."""
return {"message": "Hello, Python"}
if __name__ == "__main__":
result = run()
print(json.dumps({"result": result, "status": "success"}))
sys.exit(0)

45
actions/hello.yaml Normal file
View File

@@ -0,0 +1,45 @@
# Hello Action
# Simple Python action that returns "Hello, Python"
ref: python_example.hello
label: "Hello Python"
description: "A simple Python action that returns a greeting message"
enabled: true
# Runner type determines how the action is executed
runner_type: python
# Entry point is the Python script to execute
entry_point: hello.py
# Parameter delivery: stdin for secure parameter passing
parameter_delivery: stdin
parameter_format: json
# Output format: json (structured data parsing enabled)
output_format: json
# Action parameters schema (standard JSON Schema format)
parameters:
type: object
properties:
name:
type: string
description: "Optional name to include in greeting"
default: "Python"
# Output schema
output_schema:
type: object
properties:
message:
type: string
description: "The greeting message"
required:
- message
# Tags for categorization
tags:
- python
- example
- greeting

22
actions/http_example.py Normal file
View File

@@ -0,0 +1,22 @@
#!/usr/bin/env python3
"""
HTTP Example Action - Python Example Pack
Demonstrates using the `requests` library to make an HTTP call to example.com.
Receives parameters via stdin JSON (through the Python wrapper).
"""
import requests
def run(url="https://example.com", **kwargs):
"""Fetch a URL and return status and a snippet of the response body."""
response = requests.get(url, timeout=10)
return {
"status_code": response.status_code,
"url": response.url,
"content_length": len(response.text),
"snippet": response.text[:500],
"success": response.ok,
}

68
actions/http_example.yaml Normal file
View File

@@ -0,0 +1,68 @@
# HTTP Example Action
# Demonstrates using the requests library to make HTTP calls
ref: python_example.http_example
label: "HTTP Example"
description: "Makes an HTTP GET request to example.com using the requests library"
enabled: true
# Runner type
runner_type: python
# Entry point
entry_point: http_example.py
# Parameter delivery: stdin for secure parameter passing
parameter_delivery: stdin
parameter_format: json
# Output format: json (structured data)
output_format: json
# Action parameters schema
parameters:
type: object
properties:
url:
type: string
description: "URL to request (defaults to https://example.com)"
default: "https://example.com"
method:
type: string
description: "HTTP method"
default: "GET"
enum:
- GET
- POST
- PUT
- DELETE
# Output schema
output_schema:
type: object
properties:
status_code:
type: integer
description: "HTTP response status code"
url:
type: string
description: "URL that was requested"
content_length:
type: integer
description: "Length of the response body in bytes"
content_type:
type: string
description: "Content-Type header from the response"
title:
type: string
description: "Extracted page title (if HTML response)"
success:
type: boolean
description: "Whether the request succeeded (2xx status)"
# Tags for categorization
tags:
- http
- python
- example
- requests

51
actions/read_counter.py Normal file
View File

@@ -0,0 +1,51 @@
#!/usr/bin/env python3
"""
Read Counter Action - Python Example Pack
Consumes a counter value (typically from the counter sensor trigger payload)
and returns a formatted message containing the counter value.
Parameters are delivered via stdin as JSON from the Python wrapper.
"""
import json
import sys
def run(counter=0, rule_ref="unknown", **kwargs):
"""Return a message containing the counter value.
Args:
counter: The counter value from the trigger payload.
rule_ref: The rule reference that produced this counter.
**kwargs: Additional parameters (ignored).
Returns:
dict with a formatted message and the raw counter value.
"""
return {
"message": f"Counter value is {counter} (from rule: {rule_ref})",
"counter": counter,
"rule_ref": rule_ref,
}
def main():
"""Entry point when run directly (without the Python wrapper)."""
try:
content = sys.stdin.read().strip()
if content:
parts = content.split("---ATTUNE_PARAMS_END---")
params = json.loads(parts[0].strip()) if parts[0].strip() else {}
else:
params = {}
except (json.JSONDecodeError, IndexError):
params = {}
result = run(**params)
print(json.dumps(result, indent=2))
sys.exit(0)
if __name__ == "__main__":
main()

58
actions/read_counter.yaml Normal file
View File

@@ -0,0 +1,58 @@
# Read Counter Action
# Consumes a counter value and returns a formatted message
ref: python_example.read_counter
label: "Read Counter"
description: "Receives a counter value (typically from the counter trigger) and returns a formatted message containing it"
enabled: true
# Runner type
runner_type: python
# Entry point
entry_point: read_counter.py
# Parameter delivery: stdin for secure parameter passing
parameter_delivery: stdin
parameter_format: json
# Output format: json (structured data)
output_format: json
# Action parameters schema
parameters:
type: object
properties:
counter:
type: integer
description: "The counter value to consume"
rule_ref:
type: string
description: "The rule reference the counter is scoped to"
default: ""
required:
- counter
# Output schema
output_schema:
type: object
properties:
message:
type: string
description: "Formatted message containing the counter value"
counter:
type: integer
description: "The counter value that was consumed"
rule_ref:
type: string
description: "The rule reference the counter is scoped to"
required:
- message
- counter
# Tags for categorization
tags:
- counter
- example
- python
- consumer