> ## Documentation Index
> Fetch the complete documentation index at: https://docs.simultaneous.live/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> Complete guide to using the Simultaneous Python SDK

## Installation

```bash theme={null}
pip install simultaneous
```

Verify installation:

```bash theme={null}
python -c "from simultaneous import SimClient, Browsers, Models; print('✅ Installed')"
```

## Quick Start

Here's everything you need to get started:

```python theme={null}
import asyncio
from simultaneous import SimClient, Browsers, Models

async def main():
    # Initialize client (replace with your project ID)
    sim = SimClient(project_id="your-project-id")
    
    # Create a browser client
    browser = sim.browser_client(
        provider=Browsers.BROWSERBASE,
        model_name=Models.O4_MINI,
    )
    
    # Use the browser
    async with browser:
        page = browser.page
        await page.goto("https://example.com")
        await page.act("click the login button")
        await page.screenshot(path="screenshot.png")

asyncio.run(main())
```

## Client Setup

### Basic Initialization

```python theme={null}
from simultaneous import SimClient

# Simplest way - uses environment variables
sim = SimClient()

# Or specify project ID directly
sim = SimClient(project_id="your-project-id")

# With API key (optional)
sim = SimClient(
    project_id="your-project-id",
    api_key="SIM_...",
)
```

### Environment Variables

Set these in your environment or `.env` file:

```bash theme={null}
SIMULTANEOUS_PROJECT_ID=your-project-id    # Required
SIMULTANEOUS_API_KEY=your-api-key           # Optional
OPENAI_API_KEY=sk-...                       # Required for AI features
```

Then use:

```python theme={null}
sim = SimClient()  # Automatically reads from environment
```

## Browser Client Usage

### Creating a Browser Client

The `browser_client()` method creates a `BrowserClient` that automatically manages browser sessions:

```python theme={null}
from simultaneous import SimClient, Browsers, Models

sim = SimClient(project_id="your-project-id")

# Create browser client with default settings
browser = sim.browser_client(
    provider=Browsers.BROWSERBASE,
    model_name=Models.O4_MINI,
)

# Or with custom configuration
browser = sim.browser_client(
    provider=Browsers.BROWSERBASE,
    model_name=Models.GPT4O,
    model_api_key="sk-...",  # Optional: defaults to OPENAI_API_KEY env var
    adapter_config={
        "region": "sfo",  # Browserbase region
        "projectId": "proj_xxx",  # Browserbase project ID
    },
)
```

### Using BrowserClient

**Always use the context manager** - it ensures proper cleanup:

```python theme={null}
async with browser:
    page = browser.page
    await page.goto("https://example.com")
    await page.act("click the login button")
    # Session automatically closed on exit
```

## Page Automation Methods

The `page` object (from Stagehand) provides AI-powered browser automation:

### Navigation

```python theme={null}
# Navigate to a URL
await page.goto("https://example.com")

# Wait for navigation
await page.wait_for_load_state("networkidle")
```

### AI-Powered Actions

```python theme={null}
# Use natural language to interact with the page
await page.act("search for 'python tutorials'")
await page.act("click the submit button")
await page.act("fill in the form with name John and email john@example.com")
await page.act("scroll down to the footer")
```

### Screenshots

```python theme={null}
# Take a screenshot
await page.screenshot(path="screenshot.png")

# Screenshot of specific element
await page.screenshot(path="button.png", selector="button#submit")
```

### Element Interaction

```python theme={null}
# Click an element
await page.click("button#submit")

# Type text
await page.type("input#search", "search query")

# Fill a form field
await page.fill("input#email", "user@example.com")

# Select dropdown option
await page.select_option("select#country", "US")
```

### Waiting

```python theme={null}
# Wait for element to appear
await page.wait_for_selector("div#results")

# Wait for text to appear
await page.wait_for_text("Results found")

# Wait for navigation
await page.wait_for_url("https://example.com/success")
```

### Evaluation

```python theme={null}
# Execute JavaScript
result = await page.evaluate("document.title")

# Get element text
text = await page.text_content("h1")

# Get element attribute
href = await page.get_attribute("a#link", "href")
```

## Advanced Examples

### Web Scraping Example

```python theme={null}
import asyncio
from simultaneous import SimClient, Browsers, Models

async def scrape_job_listings():
    sim = SimClient(project_id="your-project-id")
    
    browser = sim.browser_client(
        provider=Browsers.BROWSERBASE,
        model_name=Models.O4_MINI,
    )
    
    async with browser:
        page = browser.page
        
        # Navigate to job board
        await page.goto("https://example-jobs.com")
        
        # Search for jobs
        await page.act("search for 'software engineer'")
        await asyncio.sleep(2)  # Wait for results
        
        # Extract job listings
        jobs = await page.evaluate("""
            () => {
                const listings = document.querySelectorAll('.job-listing');
                return Array.from(listings).map(job => ({
                    title: job.querySelector('.title')?.textContent,
                    company: job.querySelector('.company')?.textContent,
                    location: job.querySelector('.location')?.textContent,
                }));
            }
        """)
        
        return jobs

# Run the scraper
results = asyncio.run(scrape_job_listings())
print(f"Found {len(results)} jobs")
```

### Form Filling Example

```python theme={null}
import asyncio
from simultaneous import SimClient, Browsers, Models

async def fill_contact_form():
    sim = SimClient(project_id="your-project-id")
    
    browser = sim.browser_client(
        provider=Browsers.BROWSERBASE,
        model_name=Models.GPT4O,
    )
    
    async with browser:
        page = browser.page
        
        await page.goto("https://example.com/contact")
        
        # Use AI to fill the form
        await page.act("fill in the contact form with name 'John Doe', email 'john@example.com', and message 'Hello, I am interested in your services'")
        
        # Take screenshot before submitting
        await page.screenshot(path="form-filled.png")
        
        # Submit the form
        await page.act("submit the form")
        
        # Wait for confirmation
        await page.wait_for_text("Thank you")

asyncio.run(fill_contact_form())
```

### Multi-Page Workflow

```python theme={null}
import asyncio
from simultaneous import SimClient, Browsers, Models

async def multi_page_workflow():
    sim = SimClient(project_id="your-project-id")
    
    browser = sim.browser_client(
        provider=Browsers.BROWSERBASE,
        model_name=Models.O4_MINI,
    )
    
    async with browser:
        page = browser.page
        
        # Step 1: Search
        await page.goto("https://example.com")
        await page.act("search for 'python'")
        await asyncio.sleep(2)
        
        # Step 2: Click first result
        await page.act("click on the first search result")
        await asyncio.sleep(2)
        
        # Step 3: Extract information
        title = await page.evaluate("document.title")
        content = await page.text_content("main")
        
        # Step 4: Take screenshot
        await page.screenshot(path="result.png")
        
        return {"title": title, "content": content[:500]}

result = asyncio.run(multi_page_workflow())
print(result)
```

## Available Models

The SDK supports multiple AI models for browser automation:

```python theme={null}
from simultaneous import Models

# OpenAI models
Models.GPT4O          # "openai/gpt-4o" (recommended)
Models.O4_MINI        # "openai/o4-mini" (Computer Use model)
Models.O4             # "openai/o4" (Computer Use model)

# Anthropic models
Models.CLAUDE_3_5     # "anthropic/claude-3.5"
```

## Available Providers

```python theme={null}
from simultaneous import Browsers

Browsers.BROWSERBASE  # Browserbase provider
```

## Environment Variables

**Required:**

* `SIMULTANEOUS_PROJECT_ID` - Your project UUID
* `OPENAI_API_KEY` - For AI-powered browser actions

**Optional:**

* `SIMULTANEOUS_API_KEY` - API key for authentication
* `ANTHROPIC_API_KEY` - For Claude models (if using `Models.CLAUDE_3_5`)
* `BROWSERBASE_PROJECT_ID` - Browserbase project ID (if different from default)
* `BROWSERBASE_REGION` - Browserbase region (default: "sfo")

## Error Handling

```python theme={null}
import asyncio
from simultaneous import SimClient, Browsers, Models

async def robust_example():
    sim = SimClient(project_id="your-project-id")
    
    browser = sim.browser_client(
        provider=Browsers.BROWSERBASE,
        model_name=Models.O4_MINI,
    )
    
    try:
        async with browser:
            page = browser.page
            await page.goto("https://example.com")
            await page.act("click the button")
    except Exception as e:
        print(f"Error occurred: {e}")
        # Browser session is automatically cleaned up

asyncio.run(robust_example())
```

## Choosing a Model

* **`Models.O4_MINI`** - Fast and cost-effective for simple tasks (recommended)
* **`Models.GPT4O`** - More capable for complex interactions
* **`Models.CLAUDE_3_5`** - Alternative AI model (requires `ANTHROPIC_API_KEY`)

## Best Practices

1. ✅ Always use `async with` for automatic cleanup
2. ✅ Set `OPENAI_API_KEY` environment variable
3. ✅ Use `O4_MINI` for simple tasks to save costs
4. ✅ Take screenshots for debugging (`await page.screenshot()`)
5. ✅ Wait for elements before interacting (`await page.wait_for_selector()`)
