Docs / Strand / nodes/python-snippet

Python Snippet Node

Execute secure Python code snippets within your workflows.

The Python Snippet node's Configuration section with an inline code preview and Edit Code button. The inspector previews the code inline; Edit Code opens the full editor with the module reference.

Overview

Python Snippet nodes allow you to write custom Python code to process and transform data. The code runs in a secure, sandboxed environment.

Use Python snippets for:

Don't use Python snippets for:

Getting Started

Your First Python Snippet

When you create your first Python snippet, here's what to expect:

1

You'll see a code editor

Large, syntax-highlighted editor

2

Available variables are shown

payload, meta are documented

3

Libraries are ready

json, math, datetime, re work immediately (no imports)

4

Code executes quickly

Most snippets complete in < 1 second

5

Output becomes next node's input

Return a dict, it becomes payload for next node

Typical Workflow

python

# Step 1: Access your input data
user_id = payload.get('user_id')
email = payload.get('email', '')

# Step 2: Process/transform the data
email_lower = email.lower()
is_valid = '@' in email and '.' in email.split('@')[1] if email else False

# Step 3: Return your result
return {
    'user_id': user_id,
    'email_normalized': email_lower,
    'is_valid': is_valid
}

What Happens When You Run

1

Code is validated

Checked for disallowed patterns

2

Sandbox is created

Isolated execution environment

3

Code executes

Your Python code runs with resource limits enforced

4

Output is validated

Return value is checked

5

Result passed to next node

Your return value becomes next node's payload

Available Variables

Your Python code has access to:

Vault Values in Output

Any vault secret values that appear in your return data are automatically replaced with their {{ vault.key_name }} placeholder before being stored or displayed. Vault secrets are never exposed in run logs or step outputs.

Python vs Jinja: What's Available Where

Variable Python Snippets Jinja Templates Notes
payload Yes Yes Current event data
meta Yes Yes Event metadata
return / output Yes No Return a dict (or assign output) to pass data forward
vault Yes Yes Encrypted secrets from Global Vault
variables No Yes Workflow configuration values
steps No Yes Previous step outputs
initial No Yes Original workflow input

Returning Output

Use return (or assign output = {...}) to pass data to the next node. If you don't set either, the input payload is passed through unchanged.

python

# Process the payload
result = payload.get('value', 0) * 2

# Return your result
return {
    'processed_value': result,
    'original': payload,
    'timestamp': meta.get('received_at')
}
Output Requirements
  • Return value must be a dictionary
  • If you return a non-dict value, it will be wrapped: {'result': your_value}
  • Output size is limited to 1MB
  • Nested structures are validated and sanitized

Available Libraries

You can import the following safe libraries using standard Python import statements:

Category Libraries
Data Formats json, csv, base64, html
Math & Numbers math, decimal, statistics, random
Date/Time datetime
Text Processing re, string, textwrap
Data Structures collections, itertools, functools, operator
Utilities hashlib, hmac, uuid
URL Handling urllib.parse
Efficient Imports

Only the modules you actually import are loaded. Import only what you need:

python

from datetime import datetime

Examples

Data Transformation

python

# Transform user data
user_data = payload.get('user', {})
full_name = f"{user_data.get('first_name', '')} {user_data.get('last_name', '')}".strip()

return {
    'user_id': user_data.get('id'),
    'full_name': full_name,
    'email': user_data.get('email'),
    'processed_at': meta.get('received_at')
}

Data Validation

python

# Validate and enrich data
email = payload.get('email', '')
is_valid = '@' in email and '.' in email.split('@')[1] if email else False

return {
    'email': email,
    'is_valid': is_valid,
    'domain': email.split('@')[1] if is_valid else None
}

Calculations

python

# Perform calculations
items = payload.get('items', [])
total = sum(item.get('price', 0) * item.get('quantity', 0) for item in items)
tax = total * 0.08
grand_total = total + tax

return {
    'subtotal': total,
    'tax': tax,
    'total': grand_total,
    'item_count': len(items)
}

Using Libraries

python

from datetime import datetime

# Parse JSON string
data = json.loads(payload.get('json_data', '{}'))

# Math operations
result = math.sqrt(payload.get('value', 0))

# Date operations
now = datetime.utcnow()
return {
    'processed_at': now.isoformat(),
    'result': result,
    'data': data
}

Security

Python snippets run in a secure, sandboxed environment with multiple layers of protection. Code is validated, executed in isolation, and subject to resource limits. Vault secrets are accessible via the vault variable, but any vault values in output are automatically replaced with {{ vault.key }} placeholders.

Resource Limits

Resource Default Limit
Code Size 10,000 characters (10KB)
Execution Time 5 seconds
Memory 50 MB
Output Size 1 MB
Plan-Based Limits

Resource limits vary based on your account plan. Higher-tier plans have increased execution time, memory, and output size limits.

Restrictions

What's NOT Allowed

What IS Allowed

Error Handling

Handle errors gracefully in your code:

python

try:
    value = payload.get('value', 0)
    result = 100 / value
    return {'result': result}
except ZeroDivisionError:
    return {'error': 'Division by zero', 'result': None}
except Exception as e:
    return {'error': str(e), 'result': None}

Troubleshooting

Common Errors and Solutions

"Import of 'X' is not allowed"

"Code execution exceeded time limit"

"Code execution exceeded memory limit"

"Output size exceeds maximum allowed size"

Performance Expectations

Operation Expected Time Notes
Simple calculations < 100ms Very fast
String operations < 500ms Fast for reasonable strings
List processing (1000 items) < 1s Efficient
List processing (10,000 items) 1-3s May approach timeout
Regex on large text (1MB) 1-2s Depends on pattern complexity

Best Practices

Development Best Practices
1

Keep code simple

Focus on data transformation

2

Handle errors

Use try/except for robustness

3

Return output explicitly

Always return a dict

4

Test incrementally

Test with sample data first

5

Validate input

Check payload structure before processing

6

Limit output size

Keep return values reasonable (< 1MB)

7

Use descriptive variable names

Makes code easier to understand

Security Best Practices
1

No sandbox is 100% secure

Use with caution

2

Monitor execution logs

Watch for suspicious patterns

3

Limit access

Only allow trusted users to create Python snippets

4

Don't trust user input

Validate all data from payload

5

Keep code size reasonable

Stay well under 10KB limit