> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreflux.org/llms.txt
> Use this file to discover all available pages before exploring further.

# ACTION Python Integration

> Extend LoT actions with Python functions for complex calculations and data processing

## Overview

While LoT handles most IoT automation elegantly, some tasks need the full power of a programming language. Python integration lets you call Python functions directly from your LoT actions—no external services, no network calls, no containers. Your Python code runs inside the broker alongside your actions.

<Tip>
  **Think of Python as a specialist you can call for help.** Your LoT action handles the routine work (reading sensors, routing messages, checking thresholds), but when it encounters something complex—statistical analysis, regex parsing, or calling an external library—it hands the task to Python and gets the result back instantly.
</Tip>

***

## When to Use Python vs. LoT

Before diving into syntax, understand when Python makes sense:

| Use Python For                         | Use LoT For                          |
| -------------------------------------- | ------------------------------------ |
| Complex calculations (statistics, ML)  | Simple math (+, -, \*, /)            |
| Regex and advanced string parsing      | String concatenation                 |
| Data validation with complex rules     | Basic conditionals (IF/THEN)         |
| External library calls (numpy, pandas) | MQTT operations (PUBLISH, GET TOPIC) |
| JSON transformation and restructuring  | Field extraction (GET JSON)          |

<Info>
  If you can do it in LoT, do it in LoT. Python adds overhead—use it when LoT's built-in operations aren't enough.
</Info>

***

## Writing Python Scripts

Every Python script in LoT must declare its name on the **first line** using a `# Script Name:` comment. That name is what you use in `CALL PYTHON "ScriptName.function_name"`—the part before the dot must match the header exactly.

```python wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
# Script Name: Calculator

def add(a, b):
    return a + b

def multiply(a, b):
    return a * b
```

<Warning>
  The first line must be `# Script Name: YourScriptName`. Without this header, the broker does not register the script and `CALL PYTHON` cannot find it.
</Warning>

| Header                         | LoT call                                        |
| ------------------------------ | ----------------------------------------------- |
| `# Script Name: Calculator`    | `CALL PYTHON "Calculator.add"`                  |
| `# Script Name: DataProcessor` | `CALL PYTHON "DataProcessor.calculate_average"` |

Define one or more functions below the header. Each function is callable from LoT by name.

***

## CALL PYTHON Syntax

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
CALL PYTHON "ScriptName.function_name"
    WITH (parameter1, parameter2, ...)
    RETURN AS {variable_name}
```

## Parameter Passing

### Single Parameter

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
CALL PYTHON "Processor.validate" 
    WITH (PAYLOAD) 
    RETURN AS {result}
```

### Multiple Parameters

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
SET "min_val" WITH (GET TOPIC "config/min")
SET "max_val" WITH (GET TOPIC "config/max")

CALL PYTHON "Validator.check_range" 
    WITH (PAYLOAD, {min_val}, {max_val}) 
    RETURN AS {result}
```

## Return Value Handling

Python functions can return simple values or complex JSON objects. The `RETURN AS` clause captures the result into a LoT variable.

### Simple Values

For basic calculations, return a single value:

**Python script:**

```python wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
# Script Name: Calculator

def add_numbers(a, b):
    return float(a) + float(b)
```

**LoT action calling the function:**

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
CALL PYTHON "Calculator.add_numbers" WITH (5, 3) RETURN AS {result}
PUBLISH TOPIC "math/result" WITH {result}
```

### JSON Objects

For richer data, return a dictionary—it becomes JSON that LoT can parse:

**Python script returning a dictionary:**

```python wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
# Script Name: Analyzer

def analyze_data(value):
    return {
        "original": float(value),
        "doubled": float(value) * 2,
        "squared": float(value) ** 2
    }
```

**LoT action extracting fields from the result:**

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
CALL PYTHON "Analyzer.analyze_data" WITH (5) RETURN AS {result}

PUBLISH TOPIC "analysis/full" WITH {result}
PUBLISH TOPIC "analysis/doubled" WITH (GET JSON "doubled" IN {result} AS DOUBLE)
```

## Error Handling

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
CALL PYTHON "Calculator.safe_division" WITH (10, 2) RETURN AS {result}

SET "success" WITH (GET JSON "success" IN {result} AS BOOL)

IF {success} EQUALS TRUE THEN
    PUBLISH TOPIC "calculation/result" WITH (GET JSON "result" IN {result} AS DOUBLE)
ELSE
    PUBLISH TOPIC "calculation/error" WITH (GET JSON "error" IN {result} AS STRING)
```

## Best Practices

<AccordionGroup>
  <Accordion title="Always Set the Script Name Header" icon="file-code">
    Put `# Script Name: YourScriptName` on line 1 of every Python script. The name must match the script name in `CALL PYTHON "YourScriptName.function_name"`. If calls fail with an unknown script, check spelling and that the header is the very first line.
  </Accordion>

  <Accordion title="Keep Functions Fast" icon="bolt">
    Target execution times under 100ms. Long-running Python functions block your action and can delay message processing. For heavy computations, consider offloading to an external service.
  </Accordion>

  <Accordion title="Always Handle Errors" icon="shield">
    Wrap Python logic in try/except blocks and return structured error responses. This lets your LoT action gracefully handle failures instead of crashing.
  </Accordion>

  <Accordion title="Return JSON-Serializable Types" icon="code">
    Return dictionaries, lists, strings, numbers, and booleans. Custom objects and classes won't serialize properly. When in doubt, convert to a dictionary.
  </Accordion>

  <Accordion title="Validate Input Parameters" icon="check">
    Python functions receive parameters as strings by default. Always convert types explicitly (e.g., `float(value)`, `int(count)`) and validate ranges before processing.
  </Accordion>
</AccordionGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Operations Reference" icon="gear" href="./operations">
    Review all available LoT operations.
  </Card>

  <Card title="Actions Overview" icon="bolt" href="./overview">
    Return to the Actions overview for pattern guidance.
  </Card>
</CardGroup>
