Actions are the fundamental building blocks of Ziet. They’re Python functions decorated with @Action that become serverless, scalable units of work with automatic:
Unique identifier for the action. Defaults to module.function_name.
@Action(id="process_payment", name="Process Payment", description="Process payment")def process_payment(amount: int) -> None: # Process and store in memory memory.add(key="payment", value={"amount": amount})
Human-readable description of what the action does. Used in logs and dashboard.
@Action( id="charge_customer", name="Charge Customer", description="Charge customer via Stripe")def charge_customer(amount: int) -> None: # Process payment and store in memory memory.add(key="charge", value={"amount": amount})
from ziet import Action, memory@Action( id="long_running_task", name="Long Running Task", description="Expensive computation with timeout", timeout=60)def long_running_task(data: dict) -> None: # If this takes > 60s, execution is terminated # and a TimeoutError is raised result = expensive_computation(data) # Store result in memory memory.add(key="computation_result", value=result)
Important: Set appropriate timeouts based on your action’s expected duration.
from ziet import Action, memory@Action( id="fetch_user", name="Fetch User", description="Fetch user data from database")def fetch_user(user_id: str) -> None: user = database.get_user(user_id) # Store in memory for other actions memory.add(key=f"user_{user_id}", value=user)@Action( id="send_notification", name="Send Notification", description="Send notification email")def send_notification(user_id: str, message: str) -> None: # Retrieve from memory (avoid redundant database call) user = memory.get(f"user_{user_id}") if not user: # Fetch if not in memory fetch_user(user_id) user = memory.get(f"user_{user_id}") # Send email result = send_email(user["email"], message) memory.add(key="notification_sent", value=result)
@Action( id="validate_email", name="Validate Email", description="Validate email format")def validate_email(email: str) -> None: is_valid = "@" in email and "." in email memory.add(key="email_valid", value=is_valid)@Action( id="send_welcome_email", name="Send Welcome Email", description="Send welcome email")def send_welcome_email(email: str) -> None: result = sendgrid.send(email, "Welcome!") memory.add(key="email_sent", value=result)
❌ Bad
@Action(description="Validate and send email")def validate_and_send(email: str) -> None: # Doing too much in one action if "@" not in email: memory.add(key="error", value="Invalid email") return result = sendgrid.send(email, "Welcome!") memory.add(key="email_sent", value=result)
Descriptive Names
Use clear, action-oriented names.✅ Good
fetch_user_profile
calculate_shipping_cost
send_confirmation_email
❌ Bad
get_data
do_thing
process
Document Behavior
Add docstrings explaining what the action does.
@Action( id="calculate_tax", name="Calculate Tax", description="Calculate tax amount", timeout=10)def calculate_tax(amount: float, region: str) -> None: """ Calculate tax for a given amount and region. Args: amount: The subtotal amount in USD region: Two-letter region code (e.g., "CA", "NY") Stores: tax_amount: Tax amount in USD Raises: ValueError: If region is invalid """ tax_rates = {"CA": 0.0725, "NY": 0.04, "TX": 0.0625} if region not in tax_rates: raise ValueError(f"Unknown region: {region}") tax_amount = amount * tax_rates[region] memory.add(key="tax_amount", value=tax_amount)