Metadata-Version: 2.4
Name: rendershot
Version: 0.1.8
Summary: Python SDK for the Rendershot screenshot & PDF generation API
Project-URL: Homepage, https://rendershot.io
Project-URL: Repository, https://github.com/rendershot/rendershot-python
License: MIT
License-File: LICENSE
Keywords: api,pdf,rendershot,screenshot,sdk
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.12
Requires-Dist: httpx>=0.27
Requires-Dist: jinja2>=3.1
Requires-Dist: pydantic>=2.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pydantic[mypy]>=2.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Description-Content-Type: text/markdown

# rendershot-python

[![CI](https://github.com/Rendershot/rendershot-python/actions/workflows/ci.yml/badge.svg)](https://github.com/Rendershot/rendershot-python/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/rendershot)](https://pypi.org/project/rendershot/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

Python SDK for the [Rendershot](https://rendershot.io) screenshot & PDF generation API.

## Installation

```bash
pip install rendershot
```

## Quick start

```python
import rendershot

# Sync client
client = rendershot.RenderShotClient(api_key='your-api-key')

# Capture a screenshot
png_bytes = client.screenshot_url('https://example.com')

# Save directly to a file
client.screenshot_url_to_file('https://example.com', 'screenshot.png')

# Render a PDF
pdf_bytes = client.pdf_url('https://example.com')
client.pdf_html_to_file('<h1>Hello</h1>', 'output.pdf')

# Check your balance
balance = client.get_balance()
print(balance.credits_remaining)
```

## Async client

```python
import asyncio
import rendershot

async def main():
    async with rendershot.AsyncRenderShotClient(api_key='your-api-key') as client:
        png = await client.screenshot_url('https://example.com')
        await client.pdf_url_to_file('https://example.com', 'report.pdf')

asyncio.run(main())
```

## Bulk rendering

All bulk methods submit jobs via the `/v1/bulk` endpoint, poll until complete, and save results to a folder.

```python
# Bulk screenshots from URLs
paths = client.bulk_screenshot_urls(
    ['https://example.com', 'https://github.com'],
    output_dir='/tmp/screenshots',
)

# Bulk PDFs from an HTML Jinja2 template (great for invoices)
template = '''
<html><body>
  <h1>Invoice #{{ invoice_id }}</h1>
  <p>Amount: ${{ amount }}</p>
</body></html>
'''
paths = client.bulk_pdf_from_template(
    template,
    contexts=[
        {'invoice_id': 1001, 'amount': '99.00'},
        {'invoice_id': 1002, 'amount': '149.00'},
    ],
    output_dir='/tmp/invoices',
)
```

## Handling network_idle timeouts

Some URLs never reach `network_idle` (e.g. sites with persistent WebSocket connections or infinite polling). Use `timeout_fallback_to='dom_content_loaded'` to automatically retry with `wait_for='dom_content_loaded'` when a timeout occurs:

```python
# Single URL — retries automatically on timeout
png = client.screenshot_url(
    'https://example.com',
    wait_for='network_idle',
    timeout_fallback_to='dom_content_loaded',
)

# Save to file
client.screenshot_url_to_file(
    'https://example.com',
    'sport5.png',
    wait_for='network_idle',
    timeout_fallback_to='dom_content_loaded',
)

# Bulk — each timed-out job is individually retried
paths = client.bulk_screenshot_urls(
    urls=['https://example.com', 'https://example2.com'],
    output_dir='./screenshots',
    wait_for='network_idle',
    timeout_fallback_to='dom_content_loaded',
)
```

## Configuration

| Parameter | Default | Description |
|-----------|---------|-------------|
| `api_key` | required | Your Rendershot API key |
| `base_url` | `https://api.rendershot.io` | API base URL |

Bulk methods also accept `poll_interval` (seconds, default `2.0`) and `timeout` (seconds, default `300.0`).

## Error handling

```python
from rendershot import exceptions

try:
    client.screenshot_url('https://example.com')
except exceptions.AuthenticationError:
    print('Invalid API key')
except exceptions.RateLimitError as e:
    print(f'Rate limited, retry after {e.retry_after}s')
except exceptions.JobFailedError as e:
    print(f'Job {e.job_id} failed')
except exceptions.APIError as e:
    print(f'API error {e.status_code}: {e.detail}')
```
