--- title: Automate Features | Tabstack description: Execute complex browser automation tasks using natural language with the Tabstack Python SDK. --- 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 Type | Description | Data Fields | | ------------------- | -------------------------- | --------------------------- | | `start` | Automation starting | Task info | | `complete` | Task finished successfully | `result` with `finalAnswer` | | `agent:status` | Status update | `message` | | `agent:processing` | Agent is planning | `operation` | | `agent:action` | Performing an action | `action`, `target` | | `agent:extracted` | Data was extracted | `extractedData` | | `browser:navigated` | Page navigation occurred | `url`, `title` | | `task:completed` | Task finished | `finalAnswer`, `status` | | `task:aborted` | Task was aborted | `reason` | | `error` | An error occurred | `error` | | `done` | Stream 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': 'alex@example.com', '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() | Parameter | Type | Default | Description | | ------------------------- | -------- | -------- | -------------------------------------------------------------------------------- | | `task` | `str` | required | Natural language description of the task | | `url` | `str` | `None` | Starting URL for the automation | | `data` | `object` | `None` | Context data (e.g., form fields to fill) | | `geo_target` | `dict` | `None` | Geotargeting parameters (e.g., `{'country': 'US'}`) for region-specific browsing | | `guardrails` | `str` | `None` | Safety constraints for automation behavior | | `max_iterations` | `int` | `50` | Maximum iterations (range: 1-100) | | `max_validation_attempts` | `int` | `3` | Maximum 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 - **[Error Handling](./error-handling)**: Build robust applications - **[Generate Features](./generate)**: Discover AI transformations - **[REST API Reference](/api/index.md)**: See the REST API endpoint