Skip to main content

Automate Features

The Automate operator executes complex browser automation tasks using natural language instructions. It provides real-time streaming updates as the automation progresses.

The agent.automate() method returns a Stream that yields AutomateEvent objects.

Overview

import os
from tabstack import Tabstack

with Tabstack(api_key=os.getenv('TABSTACK_API_KEY')) as client:
# Execute automation (returns a Stream)
stream = client.agent.automate(
task='Your task description',
url='https://example.com', # Optional starting URL
data=None, # Optional context data
geo_target=None, # Optional geotargeting (e.g., {'country': 'US'})
guardrails=None, # Optional safety constraints
max_iterations=50, # Optional (default: 50, range: 1-100)
max_validation_attempts=3 # Optional (default: 3, range: 1-10)
)

for event in stream:
print(event.event, event.data)

Execute Automation

The automate method returns a Stream that yields AutomateEvent objects. Each event has:

  • event: The event type (e.g., 'start', 'agent:processing', 'complete')
  • data: The event payload (varies by event type)

Basic Usage

import os
from tabstack import Tabstack

with Tabstack(api_key=os.getenv('TABSTACK_API_KEY')) as client:
stream = client.agent.automate(
task='Find the top 3 trending repositories on GitHub and extract their names and star counts',
url='https://github.com/trending',
guardrails='browse and extract only'
)

for event in stream:
print(f"Event: {event.event}")

if event.event == 'complete':
result = event.data
print(f'Automation completed: {result}')

Async Usage

import asyncio
import os
from tabstack import AsyncTabstack

async def run_automation():
async with AsyncTabstack(api_key=os.getenv('TABSTACK_API_KEY')) as client:
stream = await client.agent.automate(
task='Find the top 3 trending repositories',
url='https://github.com/trending',
guardrails='browse and extract only'
)

async for event in stream:
print(f"Event: {event.event}")

if event.event == 'complete':
print(f'Completed: {event.data}')

asyncio.run(run_automation())

Event Types

Event TypeDescriptionData Fields
startAutomation startingTask info
completeTask finished successfullyresult with finalAnswer
agent:statusStatus updatemessage
agent:processingAgent is planningoperation
agent:actionPerforming an actionaction, target
agent:extractedData was extractedextractedData
browser:navigatedPage navigation occurredurl, title
task:completedTask finishedfinalAnswer, status
task:abortedTask was abortedreason
errorAn error occurrederror
doneStream is closing-

Real-World Examples

Example 1: Web Scraping

import os
from tabstack import Tabstack

def scrape_trending():
with Tabstack(api_key=os.getenv('TABSTACK_API_KEY')) as client:
print('Starting GitHub trending scraper...\n')

stream = client.agent.automate(
task='Navigate to GitHub trending, find the top 5 repositories, and extract: name, description, primary language, and star count',
url='https://github.com/trending',
guardrails='browse and extract only',
max_iterations=50
)

for event in stream:
if event.event == 'agent:status':
print(f"Status: {event.data}")

elif event.event == 'agent:action':
print(f"Action: {event.data}")

elif event.event == 'browser:navigated':
print(f"Navigated to: {event.data}")

elif event.event == 'agent:extracted':
print(f'Extracted data: {event.data}')

elif event.event == 'complete':
result = event.data
print('\nAutomation completed!')
print(f'Final result: {result}')

elif event.event == 'error':
print(f"Error: {event.data}")

scrape_trending()

Example 2: Form Filling

import os
from tabstack import Tabstack

def fill_contact_form():
form_data = {
'name': 'Alex Johnson',
'email': '[email protected]',
'company': 'Example Corp',
'message': 'I am interested in learning more about your products.'
}

with Tabstack(api_key=os.getenv('TABSTACK_API_KEY')) as client:
print('Filling contact form...\n')

stream = client.agent.automate(
task='Fill out the contact form with the provided data and submit it',
url='https://company.example.com/contact',
data=form_data,
guardrails='do not navigate away from the domain',
max_iterations=30
)

for event in stream:
if event.event == 'agent:action':
print(f"Action: {event.data}")

elif event.event == 'complete':
print('\nForm submitted successfully!')
print(f'Result: {event.data}')

fill_contact_form()

Example 3: Progress Tracking

import os
from tabstack import Tabstack

def track_progress():
progress = {
'status': 'Starting...',
'current_step': 0,
'last_action': '',
'is_complete': False,
'error': None
}

with Tabstack(api_key=os.getenv('TABSTACK_API_KEY')) as client:
try:
stream = client.agent.automate(
task='Find and extract the top 5 blog posts',
url='https://blog.example.com'
)

for event in stream:
if event.event == 'agent:status':
progress['status'] = str(event.data)

elif event.event == 'agent:action':
progress['last_action'] = str(event.data)

elif event.event == 'complete':
progress['is_complete'] = True
progress['status'] = 'Completed'

elif event.event == 'error':
progress['error'] = event.data

# Display progress
print(f"Status: {progress['status']}")
print(f"Last Action: {progress['last_action']}\n")

except Exception as error:
print(f"Automation failed: {error}")

track_progress()

Working with AutomateEvent

Each event in the stream is an AutomateEvent object with two attributes:

for event in stream:
# Event type as a string
event_type = event.event # e.g., 'agent:status', 'complete'

# Event data (type varies by event)
data = event.data

# Example: handling different event types
if event.event == 'agent:status':
message = event.data # Usually a string or dict
print(f'Status: {message}')

elif event.event == 'agent:extracted':
extracted = event.data # The extracted data
print(f'Extracted: {extracted}')

elif event.event == 'complete':
result = event.data # Final result object
print(f'Done: {result}')

Options Reference

agent.automate()

ParameterTypeDefaultDescription
taskstrrequiredNatural language description of the task
urlstrNoneStarting URL for the automation
dataobjectNoneContext data (e.g., form fields to fill)
geo_targetdictNoneGeotargeting parameters (e.g., {'country': 'US'}) for region-specific browsing
guardrailsstrNoneSafety constraints for automation behavior
max_iterationsint50Maximum iterations (range: 1-100)
max_validation_attemptsint3Maximum validation retry attempts (range: 1-10)

Guardrails

Use guardrails to constrain what the automation agent can do:

# Browse only - no form submissions
guardrails = 'browse and extract only'

# Stay on domain
guardrails = 'do not navigate away from the domain'

# No purchases
guardrails = 'do not add items to cart or make purchases'

# Read-only
guardrails = 'read-only operations, do not submit forms'

# Multiple constraints
guardrails = 'browse and extract only, do not submit forms, stay on the main domain'

Best Practices

1. Be Specific with Instructions

# Vague
task = 'Get some products'

# Specific
task = 'Find the top 5 best-selling products in Electronics and extract names, prices, and ratings'

2. Always Use Guardrails

# Good: Clear safety constraints
stream = client.agent.automate(
task='Extract data',
guardrails='browse and extract only, do not submit forms'
)

3. Handle All Event Types

for event in stream:
if event.event == 'agent:status':
# Show progress
pass
elif event.event == 'complete':
# Handle success
pass
elif event.event == 'error':
# Handle errors
break
elif event.event == 'task:aborted':
# Handle abortion
break

4. Set Appropriate Iteration Limits

# Simple single-page tasks
max_iterations = 20

# Multi-page workflows
max_iterations = 50 # default

# Complex deep pagination
max_iterations = 100

5. Handle Errors Gracefully

import tabstack
from tabstack import Tabstack

with Tabstack() as client:
try:
stream = client.agent.automate(task=task, url=url)

for event in stream:
if event.event == 'error':
print(f"Automation error: {event.data}")
break
elif event.event == 'complete':
print(f"Success: {event.data}")

except tabstack.APIStatusError as error:
print(f"API error: {error.status_code} - {error}")
except tabstack.APIConnectionError as error:
print(f"Connection error: {error}")

Next Steps