---
title: Python Expressions
description: Capabilities and limits of Python expressions in App Builder
breadcrumbs: Docs > Actions > Workflow Automation > Expressions > Python Expressions
---

# Python Expressions

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site). ().
{% /alert %}

{% /callout %}

The Python function action lets you write custom Python scripts for data transformations, parsing, and payload enrichment within your workflows.

## Python environment{% #python-environment %}

The Python function action runs in a restricted execution environment with the following characteristics:

- Network access: Restricted
- Python version: **3.12.8**
- Available libraries: In addition to the Python standard library, the following packages are available:
| Package         | Version   | Description                                       |
| --------------- | --------- | ------------------------------------------------- |
| python-dateutil | `==2.9.0` | Extensions to the standard Python datetime module |
| python-hcl2     | `==7.3.1` | A parser for HCL2                                 |
| PyYAML          | `==6.0.3` | YAML parser and emitter for Python                |
| rsa             | `==4.9.1` | Pure-Python RSA implementation                    |

## Script structure{% #script-structure %}

All Python scripts must define a `main` function that accepts a `ctx` parameter of type `Context`. For example:

```python
from execution_context import Context

def main(*, ctx: Context):
  # Use ctx to access Trigger or Steps data
  workflow_name = ctx["WorkflowName"]
  return f"Running workflow {workflow_name!r}"
```

The `ctx` object provides access to all workflow context variables, similar to the `$` variable in JavaScript expressions. Use dictionary-style access (for example, `ctx["Steps"]["Step_name"]["variable"]`) to reference values from previous steps.

## Add a Python function action{% #add-a-python-function-action %}

In the workflow canvas:

1. Click **+** to add a workflow step.
1. Search for `Python`.
1. Select the Python action to add it to your workflow.

## Write Python scripts with AI{% #write-python-scripts-with-ai %}

You can use Bits AI to help write Python scripts inside a workflow step.

To write a script with Bits AI:

1. Add a Python step to your workflow.
1. In the **Inputs** section, click **Write Code with AI**.
1. Enter a custom prompt or select one of the sample prompts.
1. Optionally, click **Test script** to generate a preview of the workflow step.
1. To save the script, click **Accept changes**. To continue editing the script, click **Reject changes**.
1. Click the **X** to close the AI dialog.
1. Enter a **Description**.
1. Click **Save**.

## Script examples{% #script-examples %}

### Parse and transform JSON data{% #parse-and-transform-json-data %}

This example parses a JSON string from a previous step and extracts specific fields.

```python
from execution_context import Context
import json

def main(*, ctx: Context):
    # Get JSON string from previous step
    json_string = ctx["Steps"]["Get_data"]["output"]

    # Parse and transform
    data = json.loads(json_string)
    return {
        "user_ids": [user["id"] for user in data["users"]],
        "total_count": len(data["users"])
    }
```

### Work with dates and timestamps{% #work-with-dates-and-timestamps %}

This example uses the python-dateutil library to perform date calculations.

```python
from execution_context import Context
from dateutil import parser, relativedelta
from datetime import datetime

def main(*, ctx: Context):
    # Parse a date string
    start_date = parser.parse(ctx["Trigger"]["date_string"])

    # Calculate date 30 days in the future
    future_date = start_date + relativedelta.relativedelta(days=30)

    return {
        "start": start_date.isoformat(),
        "end": future_date.isoformat(),
        "days_difference": 30
    }
```

### Cryptographic operations{% #cryptographic-operations %}

This example uses the rsa library to encrypt a message.

```python
from execution_context import Context
import rsa
import base64

def main(*, ctx: Context):
    # Get message from workflow context
    message = ctx["Steps"]["Compose_message"]["text"]

    # Generate RSA key pair
    (public_key, private_key) = rsa.newkeys(512)

    # Encrypt message
    encrypted = rsa.encrypt(message.encode(), public_key)

    return {
        "encrypted_message": base64.b64encode(encrypted).decode(),
        "public_key": public_key.save_pkcs1().decode()
    }
```
