Writing Python 3.11 Actions for HubSpot Workflows
A practical guide to building, testing, and deploying custom Python 3.11 workflow actions for HubSpot using the official hubspot-api-client.
The Python 3.11 Runtime Environment
Workflood offers first-class **Python 3.11** execution for teams that prefer Python's rich data manipulation and mathematical capabilities over JavaScript.
**Pre-Installed Python Libraries:** - `hubspot-api-client` (Official HubSpot Python SDK) - `requests` & `urllib3` (HTTP Networking) - `pydantic` & `marshmallow` (Data validation) - Standard library modules (`datetime`, `json`, `math`, `re`, `hashlib`)
Python Action Structure
A Python action in Workflood defines a `main(input)` function that accepts a dictionary payload and returns a dictionary response:
import os
import datetime
from hubspot import HubSpot
from hubspot.crm.contacts import SimplePublicObjectInput
def main(event):
"""
Workflood Python 3.11 Action Handler
"""
raw = event[0] if isinstance(event, list) else event
contact_id = raw.get("objectId") or raw.get("contactId")
if not contact_id:
return {"error": "No contact ID provided", "processed": False}
# Initialize HubSpot Client
client = HubSpot(access_token=os.environ.get("HUBSPOT_ACCESS_TOKEN"))
# Fetch contact properties
contact = client.crm.contacts.basic_api.get_by_id(
contact_id=contact_id,
properties=["email", "jobtitle", "annualrevenue", "num_employees"]
)
props = contact.properties
score = 50
# Calculate custom lead score
if "director" in (props.get("jobtitle") or "").lower():
score += 25
if "vp" in (props.get("jobtitle") or "").lower() or "c-level" in (props.get("jobtitle") or "").lower():
score += 35
if float(props.get("annualrevenue") or 0) > 1000000:
score += 20
score = min(100, score)
# Update HubSpot Contact
update_input = SimplePublicObjectInput(properties={"calculated_fit_score": str(score)})
client.crm.contacts.basic_api.update(contact_id=contact_id, simple_public_object_input=update_input)
return {
"contact_id": contact_id,
"score": score,
"updated_at": datetime.datetime.utcnow().isoformat()
}Comparing TypeScript and Python in Workflood
| Feature | TypeScript (Node 20) | Python (3.11) |
|---|---|---|
| **Best For** | High-throughput webhooks, async I/O, API orchestration | Data parsing, regex cleanup, statistical lead scoring |
| **SDK Object** | hubspot.client (Pre-injected) | HubSpot(access_token=...) |
| **Timeout Limit** | 60s (Pro) to 300s (Agency) | 60s (Pro) to 300s (Agency) |
| **Container Sandboxing** | gVisor micro-container | gVisor micro-container |
Frequently Asked Questions
Can I use Pandas or NumPy in Python actions?
Lightweight data operations using native Python and standard math libraries are supported out of the box. High-memory data science libraries are available under dedicated Enterprise sandbox pools.
