Metadata-Version: 2.4
Name: lexmount
Version: 0.4.1
Summary: Python SDK for Lexmount browser automation service
Author-email: lexmount <your.email@example.com>
License: MIT
Project-URL: Homepage, https://dev.lexmount.net/
Project-URL: Documentation, https://dev.lexmount.net/docs
Project-URL: Repository, https://github.com/lexmount/lexmount-python-sdk
Project-URL: Bug Tracker, https://github.com/lexmount/lexmount-python-sdk/issues
Keywords: browser,automation,playwright,selenium,cloud,testing
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.23.0
Requires-Dist: python-dotenv>=0.19.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: pytest-mock>=3.10.0; extra == "dev"
Requires-Dist: respx>=0.20.0; extra == "dev"
Requires-Dist: pytest-timeout>=2.1.0; extra == "dev"
Requires-Dist: black>=22.0.0; extra == "dev"
Requires-Dist: flake8>=4.0.0; extra == "dev"
Requires-Dist: mypy>=0.950; extra == "dev"
Dynamic: license-file

# Lexmount Python SDK

[English](#english) | [中文](#中文)

---

## English

Python SDK for Lexmount browser automation service.

### ✨ Features

- 🚀 **Easy to Use**: Simple and intuitive API design
- 🔒 **Type-Safe**: Complete type hints for better IDE support
- 📝 **Well Documented**: Comprehensive docstrings and examples
- 🛡️ **Production Ready**: Error handling, logging, and retry support
- 📊 **Session Management**: Create, list, and delete browser sessions
- 🔍 **Advanced Querying**: Pagination support and status filtering

### 📦 Installation

```bash
pip install lexmount
```

**Requirements:**
- Python 3.8+
- httpx >= 0.23.0
- python-dotenv >= 0.19.0
- playwright (optional, for browser automation)

### 🛠️ Development Setup (For Running Examples)

If you want to run the example code from the repository, follow these steps:

#### 1. Create Virtual Environment

```bash
# Navigate to project directory
cd /path/to/lexmount-python-sdk

# Create virtual environment using Python's built-in venv
python3 -m venv venv
```

#### 2. Activate Virtual Environment

```bash
# Linux/macOS
source venv/bin/activate

# Windows
venv\Scripts\activate
```

#### 3. Install SDK in Development Mode

```bash
# Install SDK and all dependencies (including dev dependencies)
pip install -e ".[dev]"
```

This installs the SDK in editable mode, so code changes take effect immediately without reinstalling.

#### 4. Configure Environment Variables

Create a `.env` file in the project root directory:

```bash
LEXMOUNT_API_KEY=your-api-key-here
LEXMOUNT_PROJECT_ID=your-project-id-here
# Optional: for test environments
LEXMOUNT_BASE_URL=https://api.lexmount.net
```

#### 5. Run Examples

```bash
# From project root directory
python3 examples/context_basic.py
python3 examples/session_list.py

# Or from examples directory
cd examples
python3 ./context_basic.py
```

**Note:** Each time you open a new terminal, you need to activate the virtual environment again:
```bash
source venv/bin/activate
```

### 🚀 Quick Start

#### Basic Usage

```python
from lexmount import Lexmount

# Initialize client (credentials from environment variables)
client = Lexmount(
    api_key="your-api-key",
    project_id="your-project-id"
)

# Create a browser session
session = client.sessions.create()
print(f"Session ID: {session.id}")
print(f"Connect URL: {session.connect_url}")

# Close session when done
session.close()
```

#### Using Context Managers (Recommended)

Context managers provide automatic resource cleanup:

```python
from lexmount import Lexmount

# Client and session will be automatically closed
with Lexmount(api_key="key", project_id="proj") as client:
    with client.sessions.create() as session:
        print(f"Using session: {session.id}")
        # Use session...
        # Automatically closed on exit
```

#### Integration with Playwright

```python
from lexmount import Lexmount
from playwright.sync_api import sync_playwright

# Create session
client = Lexmount(api_key="key", project_id="proj")
session = client.sessions.create()

# Connect with Playwright
with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(session.connect_url)
    page = browser.new_page()

    page.goto("https://example.com")
    print(page.title())

    browser.close()

session.close()
```

### 📚 Core Features

#### Session Management

**Create Session**

```python
# Basic creation
session = client.sessions.create()

# With specific browser mode
session = client.sessions.create(browser_mode="normal")

# Available browser modes:
# - "normal": Chrome in Docker container
# - "light": Lightweight Chrome in Docker
```

**List Sessions**

```python
# List all sessions with pagination
result = client.sessions.list()
print(f"Total: {result.pagination.total_count}")
print(f"Active: {result.pagination.active_count}")

for session in result.sessions:
    print(f"{session.id}: {session.status}")

# Filter by status (server-side filtering)
active_sessions = client.sessions.list(status="active")
print(f"Found {len(active_sessions)} active sessions")
```

**Delete Session**

```python
# Delete by session ID
client.sessions.delete(session_id="session-id")

# Or use session object
session.close()
```

#### Error Handling

```python
from lexmount import (
    Lexmount,
    AuthenticationError,
    SessionNotFoundError,
    TimeoutError,
    NetworkError,
    APIError
)

try:
    client = Lexmount(api_key="key", project_id="proj")
    session = client.sessions.create()
except AuthenticationError:
    print("Invalid credentials")
except TimeoutError:
    print("Request timed out")
except NetworkError:
    print("Network connection failed")
except APIError as e:
    print(f"API error: {e.status_code}")
```

#### Logging

```python
from lexmount import set_log_level

# Enable debug logging
set_log_level("DEBUG")

# Available levels: DEBUG, INFO, WARNING, ERROR, CRITICAL
client = Lexmount(api_key="key", project_id="proj")
session = client.sessions.create()  # Will log detailed info
```

### 📖 API Reference

#### Lexmount Client

```python
Lexmount(
    api_key: str = None,           # API key (or LEXMOUNT_API_KEY env var)
    project_id: str = None,        # Project ID (or LEXMOUNT_PROJECT_ID env var)
    base_url: str = None,          # API URL (or LEXMOUNT_BASE_URL env var)
    timeout: float = 60.0          # Request timeout in seconds
)
```

#### Sessions Resource

**`sessions.create()`** - Create a new browser session

- **Parameters:**
  - `project_id` (str, optional): Override default project ID
  - `browser_mode` (str, optional): Browser mode (default: "normal")
- **Returns:** `SessionInfo` object
- **Raises:** `AuthenticationError`, `ValidationError`, `APIError`, `NetworkError`, `TimeoutError`

**`sessions.list()`** - List browser sessions with pagination

- **Parameters:**
  - `project_id` (str, optional): Override default project ID
  - `status` (str, optional): Filter by status ("active", "closed", or None for all)
- **Returns:** `SessionListResponse` with sessions and pagination info
- **Raises:** `AuthenticationError`, `APIError`, `NetworkError`, `TimeoutError`

**`sessions.delete()`** - Delete a browser session

- **Parameters:**
  - `session_id` (str, required): Session ID to delete
  - `project_id` (str, optional): Override default project ID
- **Returns:** None
- **Raises:** `AuthenticationError`, `SessionNotFoundError`, `APIError`

#### SessionInfo Object

**Attributes:**
- `id` (str): Session identifier
- `session_id` (str): Alias for id
- `status` (str): Session status ("active", "closed")
- `browser_type` (str): Browser mode used
- `created_at` (str): ISO 8601 timestamp
- `connect_url` (str): WebSocket URL for Playwright
- `ws` (str): Alias for connect_url
- `container_id` (str): Docker container ID (if applicable)
- `inspect_url` (str): Chrome DevTools inspection URL

**Methods:**
- `close()`: Close the session and release resources
- `__enter__()`, `__exit__()`: Context manager support

### 🔧 Configuration

#### Environment Variables

```bash
export LEXMOUNT_API_KEY="your-api-key"
export LEXMOUNT_PROJECT_ID="your-project-id"
export LEXMOUNT_BASE_URL="https://api.lexmount.com"  # Optional
```

Or use a `.env` file:

```bash
LEXMOUNT_API_KEY=your-api-key
LEXMOUNT_PROJECT_ID=your-project-id
```

### 📄 License

MIT License

---

## 中文

Lexmount 浏览器自动化服务的 Python SDK。

### ✨ 特性

- 🚀 **简单易用**：直观的 API 设计
- 🔒 **类型安全**：完整的类型提示，IDE 支持友好
- 📝 **文档完善**：详细的文档和示例
- 🛡️ **生产就绪**：错误处理、日志记录、重试支持
- 📊 **会话管理**：创建、列表、删除浏览器会话
- 🔍 **高级查询**：支持分页和状态过滤

### 📦 安装

```bash
pip install lexmount
```

**依赖要求：**
- Python 3.8+
- httpx >= 0.23.0
- python-dotenv >= 0.19.0
- playwright（可选，用于浏览器自动化）

### 🛠️ 开发环境设置（运行示例代码）

如果你想运行仓库中的示例代码，请按以下步骤操作：

#### 1. 创建虚拟环境

```bash
# 进入项目目录
cd /path/to/lexmount-python-sdk

# 使用 Python 内置的 venv 创建虚拟环境
python3 -m venv venv
```

#### 2. 激活虚拟环境

```bash
# Linux/macOS
source venv/bin/activate

# Windows
venv\Scripts\activate
```

#### 3. 以开发模式安装 SDK

```bash
# 安装 SDK 和所有依赖（包括开发依赖）
pip install -e ".[dev]"
```

这会以可编辑模式安装 SDK，代码修改会立即生效，无需重新安装。

#### 4. 配置环境变量

在项目根目录创建 `.env` 文件：

```bash
LEXMOUNT_API_KEY=your-api-key-here
LEXMOUNT_PROJECT_ID=your-project-id-here
# 可选：测试环境
LEXMOUNT_BASE_URL=https://api.lexmount.net
```

#### 5. 运行示例

```bash
# 从项目根目录运行
python3 examples/context_basic.py
python3 examples/session_list.py

# 或从 examples 目录运行
cd examples
python3 ./context_basic.py
```

**注意：** 每次新开终端时，需要重新激活虚拟环境：
```bash
source venv/bin/activate
```

### 🚀 快速开始

#### 基础用法

```python
from lexmount import Lexmount

# 初始化客户端（从环境变量读取凭据）
client = Lexmount(
    api_key="your-api-key",
    project_id="your-project-id"
)

# 创建浏览器会话
session = client.sessions.create()
print(f"会话 ID: {session.id}")
print(f"连接 URL: {session.connect_url}")

# 使用完毕后关闭会话
session.close()
```

#### 使用上下文管理器（推荐）

上下文管理器提供自动资源清理：

```python
from lexmount import Lexmount

# 客户端和会话会自动关闭
with Lexmount(api_key="key", project_id="proj") as client:
    with client.sessions.create() as session:
        print(f"使用会话: {session.id}")
        # 使用会话...
        # 退出时自动关闭
```

#### 与 Playwright 集成

```python
from lexmount import Lexmount
from playwright.sync_api import sync_playwright

# 创建会话
client = Lexmount(api_key="key", project_id="proj")
session = client.sessions.create()

# 使用 Playwright 连接
with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(session.connect_url)
    page = browser.new_page()

    page.goto("https://example.com")
    print(page.title())

    browser.close()

session.close()
```

### 📚 核心功能

#### 会话管理

**创建会话**

```python
# 基础创建
session = client.sessions.create()

# 指定浏览器模式
session = client.sessions.create(browser_mode="normal")

# 可用的浏览器模式：
# - "normal": Docker 中的 Chrome
# - "light": Docker 中的轻量级 Chrome
```

**列出会话**

```python
# 列出所有会话（带分页信息）
result = client.sessions.list()
print(f"总计: {result.pagination.total_count}")
print(f"活跃: {result.pagination.active_count}")

for session in result.sessions:
    print(f"{session.id}: {session.status}")

# 按状态过滤（服务端过滤）
active_sessions = client.sessions.list(status="active")
print(f"找到 {len(active_sessions)} 个活跃会话")
```

**删除会话**

```python
# 通过会话 ID 删除
client.sessions.delete(session_id="session-id")

# 或使用会话对象
session.close()
```

#### 错误处理

```python
from lexmount import (
    Lexmount,
    AuthenticationError,
    SessionNotFoundError,
    TimeoutError,
    NetworkError,
    APIError
)

try:
    client = Lexmount(api_key="key", project_id="proj")
    session = client.sessions.create()
except AuthenticationError:
    print("认证失败")
except TimeoutError:
    print("请求超时")
except NetworkError:
    print("网络连接失败")
except APIError as e:
    print(f"API 错误: {e.status_code}")
```

#### 日志配置

```python
from lexmount import set_log_level

# 启用调试日志
set_log_level("DEBUG")

# 可用级别：DEBUG, INFO, WARNING, ERROR, CRITICAL
client = Lexmount(api_key="key", project_id="proj")
session = client.sessions.create()  # 会输出详细日志
```

### 📖 API 参考

#### Lexmount 客户端

```python
Lexmount(
    api_key: str = None,           # API 密钥（或 LEXMOUNT_API_KEY 环境变量）
    project_id: str = None,        # 项目 ID（或 LEXMOUNT_PROJECT_ID 环境变量）
    base_url: str = None,          # API 地址（或 LEXMOUNT_BASE_URL 环境变量）
    timeout: float = 60.0          # 请求超时时间（秒）
)
```

#### Sessions 资源

**`sessions.create()`** - 创建新的浏览器会话

- **参数：**
  - `project_id` (str, 可选): 覆盖默认项目 ID
  - `browser_mode` (str, 可选): 浏览器模式（默认: "normal"）
- **返回：** `SessionInfo` 对象
- **异常：** `AuthenticationError`, `ValidationError`, `APIError`, `NetworkError`, `TimeoutError`

**`sessions.list()`** - 列出浏览器会话（带分页）

- **参数：**
  - `project_id` (str, 可选): 覆盖默认项目 ID
  - `status` (str, 可选): 按状态过滤（"active"、"closed" 或 None 表示全部）
- **返回：** `SessionListResponse`，包含会话列表和分页信息
- **异常：** `AuthenticationError`, `APIError`, `NetworkError`, `TimeoutError`

**`sessions.delete()`** - 删除浏览器会话

- **参数：**
  - `session_id` (str, 必需): 要删除的会话 ID
  - `project_id` (str, 可选): 覆盖默认项目 ID
- **返回：** None
- **异常：** `AuthenticationError`, `SessionNotFoundError`, `APIError`

#### SessionInfo 对象

**属性：**
- `id` (str): 会话标识符
- `session_id` (str): id 的别名
- `status` (str): 会话状态（"active", "closed"）
- `browser_type` (str): 使用的浏览器模式
- `created_at` (str): ISO 8601 时间戳
- `connect_url` (str): Playwright 的 WebSocket URL
- `ws` (str): connect_url 的别名
- `container_id` (str): Docker 容器 ID（如适用）
- `inspect_url` (str): Chrome DevTools 检查 URL

**方法：**
- `close()`: 关闭会话并释放资源
- `__enter__()`, `__exit__()`: 上下文管理器支持

### 🔧 配置

#### 环境变量

```bash
export LEXMOUNT_API_KEY="your-api-key"
export LEXMOUNT_PROJECT_ID="your-project-id"
export LEXMOUNT_BASE_URL="https://api.lexmount.com"  # 可选
```

或使用 `.env` 文件：

```bash
LEXMOUNT_API_KEY=your-api-key
LEXMOUNT_PROJECT_ID=your-project-id
```

### 📄 许可证

MIT License
