Metadata-Version: 2.4
Name: rendex
Version: 0.1.0
Summary: Official Python SDK for the Rendex screenshot API — capture any webpage as an image
Project-URL: Homepage, https://rendex.dev
Project-URL: Documentation, https://rendex.dev/docs
Project-URL: Repository, https://github.com/copperline-labs/copperline-labs
Project-URL: Issues, https://github.com/copperline-labs/copperline-labs/issues
Author-email: Copperline Labs LLC <support@rendex.dev>
License-Expression: MIT
License-File: LICENSE
Keywords: ai-agent,rendex,screenshot,screenshot-api,sdk,webpage-capture
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
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: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx>=0.27
Description-Content-Type: text/markdown

# rendex

Official Python SDK for the [Rendex](https://rendex.dev) screenshot API. Capture any webpage as a high-quality image with a single function call.

- Full type hints (PEP 561 compatible)
- Single dependency (`httpx`)
- Sync API with context manager support
- Typed error handling with API error codes

## Install

```bash
pip install rendex
```

## Quick Start

```python
from pathlib import Path
from rendex import Rendex

rendex = Rendex("your-api-key")

# Capture a screenshot (returns binary image)
result = rendex.screenshot("https://example.com", format="png", full_page=True)
Path("screenshot.png").write_bytes(result.image)

print(f"{result.metadata.bytes_size} bytes, loaded in {result.metadata.load_time_ms}ms")
```

## API Reference

### `Rendex(api_key, *, base_url="https://api.rendex.dev")`

Create a new Rendex client.

```python
rendex = Rendex("your-api-key")

# Or with context manager for connection reuse
with Rendex("your-api-key") as rendex:
    result = rendex.screenshot("https://example.com")
```

### `rendex.screenshot(url, **options)`

Capture a screenshot and return the binary image with metadata.

```python
result = rendex.screenshot(
    "https://example.com",
    format="webp",
    width=1920,
    height=1080,
    dark_mode=True,
)
Path("screenshot.webp").write_bytes(result.image)
print(result.metadata.load_time_ms)  # 350
```

**Returns** `ScreenshotResult`:
- `image` — `bytes` of the captured image
- `metadata` — `ScreenshotMetadata` with url, dimensions, format, bytes_size, load_time_ms, quality, etc.

### `rendex.screenshot_json(url, **options)`

Capture a screenshot and return JSON with a base64-encoded image.

```python
result = rendex.screenshot_json("https://example.com")
print(result["data"]["bytesSize"])        # 45823
print(result["meta"]["usage"]["remaining"])  # 499
```

**Returns** `ScreenshotJsonResponse` dict with `data` (image + metadata) and `meta` (request ID, usage).

### `rendex.screenshot_url(url, **options)`

Generate a GET URL for embedding. No network call — pure URL builder.

```python
url = rendex.screenshot_url("https://example.com", format="png", width=1200)
# Use in <img> tags, OpenGraph, etc.
```

> **Note**: The API key is included in the URL. Use server-side only.

### Screenshot Options

All options are keyword arguments in snake_case. Only `url` (positional) is required:

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `format` | `str` | `"png"` | `"png"`, `"jpeg"`, or `"webp"` |
| `width` | `int` | `1280` | Viewport width (320–3840) |
| `height` | `int` | `800` | Viewport height (240–2160) |
| `full_page` | `bool` | `False` | Capture the full scrollable page |
| `quality` | `int` | — | JPEG/WebP quality (1–100) |
| `delay` | `int` | `0` | Delay before capture in ms (0–10000) |
| `dark_mode` | `bool` | `False` | Emulate dark mode |
| `device_scale_factor` | `float` | `1` | Device pixel ratio (1–3) for Retina |
| `block_ads` | `bool` | `True` | Block ads and trackers |
| `block_resource_types` | `list` | — | Block: `"font"`, `"image"`, `"media"`, `"stylesheet"`, `"other"` |
| `timeout` | `int` | `30` | Page load timeout in seconds (5–60) |
| `wait_until` | `str` | `"networkidle2"` | `"load"`, `"domcontentloaded"`, `"networkidle0"`, `"networkidle2"` |
| `wait_for_selector` | `str` | — | CSS selector to wait for |
| `best_attempt` | `bool` | `True` | Return best-effort screenshot on timeout |
| `selector` | `str` | — | Capture a specific element by CSS selector |

## Error Handling

```python
from rendex import Rendex, RendexApiError, RendexNetworkError

rendex = Rendex("your-api-key")

try:
    rendex.screenshot("https://example.com")
except RendexApiError as e:
    # API returned an error
    print(e.error_code)   # "RATE_LIMITED", "VALIDATION_ERROR", etc.
    print(e.status_code)  # 429, 400, etc.
    print(e.request_id)   # For debugging with Rendex support
    print(e.details)      # Validation details (if any)
except RendexNetworkError as e:
    # Network failure (DNS, timeout, connection refused)
    print(f"Network error: {e}")
```

### Error Codes

| Code | HTTP Status | Description |
|------|-------------|-------------|
| `VALIDATION_ERROR` | 400 | Invalid request parameters |
| `INVALID_URL` | 400 | URL failed SSRF validation |
| `TIMEOUT` | 408 | Page took too long to load |
| `CAPTURE_FAILED` | 500 | Browser rendering error |
| `RATE_LIMITED` | 429 | Rate limit exceeded |
| `USAGE_EXCEEDED` | 429 | Monthly credit limit reached |
| `MISSING_API_KEY` | 401 | No API key provided |
| `INVALID_API_KEY` | 401 | API key verification failed |

## License

MIT - [Copperline Labs LLC](https://copperlinelabs.com)
