flow-captcha-solver 1.0.1
A Python library to solve reCAPTCHA v3 for Google Labs Flow projects
License: MIT
Requires Python: >=3.8
Keywords: recaptcha, captcha, google-labs, flow, playwright, automation

# Flow Captcha Solver

A Python library to solve reCAPTCHA v3 for Google Labs Flow projects.

## Features

- **Multi-browser pool** - Run multiple browsers in parallel
- **Auto-switching** - Automatically switch to another browser on failure
- **Auto-reset** - Reset browser with new fingerprint after consecutive failures
- **Random fingerprint** - User-Agent, Viewport, Timezone randomization
- **API feedback** - Report success/failure to adjust browser selection
- **Both sync and async APIs**

## Installation

```bash
pip install flow-captcha-solver
playwright install chromium
```

## Quick Start

### Simple Usage (Sync)

```python
from flow_captcha_solver import get_token_sync

token = get_token_sync("your-project-id")
if token:
    print(f"Token: {token[:50]}...")
```

### With Manager (Recommended)

```python
from flow_captcha_solver import FlowCaptchaManager

# Get singleton instance
manager = FlowCaptchaManager.get_instance()

# Start with 2 browsers
manager.start(num_browsers=2)

# Get token
token = manager.get_token_sync("your-project-id")

if token:
    # Use token with your API...
    api_response = call_your_api(token)

    if api_response.success:
        manager.report_success()  # Reset failure counter
    else:
        manager.report_failure("Token rejected")  # Increment counter
else:
    manager.report_failure("No token")

# Check status
print(manager.get_status())
# {'browsers': [{'id': 0, 'failures': 0, 'resets': 1}, {'id': 1, 'failures': 2, 'resets': 0}]}

# Stop when done
manager.stop()
```

### Async Usage

```python
import asyncio
from flow_captcha_solver import FlowCaptchaPool

async def main():
    async with FlowCaptchaPool(num_browsers=2) as pool:
        token = await pool.get_token("your-project-id")

        if token:
            print(f"Token: {token[:50]}...")
            pool.report_success()
        else:
            pool.report_failure("Failed")

asyncio.run(main())
```

### Single Browser (Async)

```python
from flow_captcha_solver import BrowserInstance

async def main():
    async with BrowserInstance(headless=True) as browser:
        token, error = await browser.get_token("your-project-id")

        if token:
            print(f"Token: {token}")
        else:
            print(f"Error: {error}")
```

## Configuration

Default configuration can be imported and modified:

```python
from flow_captcha_solver import MAX_CONSECUTIVE_FAILURES

# Default: 3 failures before auto-reset
print(MAX_CONSECUTIVE_FAILURES)
```

## How It Works

1. **Browser Pool**: Creates multiple Chromium browser instances using Playwright
2. **Stealth Mode**: Injects scripts to avoid bot detection (hide webdriver, fake plugins, etc.)
3. **Load Page**: Navigates to Google Labs Flow project page
4. **Inject reCAPTCHA**: Loads reCAPTCHA v3 script if not present
5. **Execute**: Calls `grecaptcha.execute()` to get token
6. **Auto-Reset**: If browser fails 3 times consecutively, it resets with new fingerprint

## API Reference

### FlowCaptchaManager

| Method | Description |
|--------|-------------|
| `get_instance(headless=True)` | Get singleton instance |
| `start(num_browsers=2)` | Start service with N browsers |
| `get_token_sync(project_id)` | Get token (blocking) |
| `report_success()` | Report API success |
| `report_failure(reason)` | Report API failure |
| `get_status()` | Get pool status |
| `stop()` | Stop service |

### FlowCaptchaPool

| Method | Description |
|--------|-------------|
| `initialize()` | Initialize all browsers |
| `get_token(project_id)` | Get token (async) |
| `report_success()` | Report API success |
| `report_failure(reason)` | Report API failure |
| `get_status()` | Get pool status |
| `close()` | Close all browsers |

### BrowserInstance

| Method | Description |
|--------|-------------|
| `initialize()` | Initialize browser |
| `get_token(project_id)` | Get token (returns tuple) |
| `mark_api_success()` | Mark API success |
| `mark_api_failure(reason)` | Mark API failure |
| `reset()` | Reset with new fingerprint |
| `close()` | Close browser |

## License

MIT License