# Python Integration — RenderPix

**API Endpoint:** `POST https://renderpix.dev/v1/render`

---

## Authentication

Pass your API key in the `X-API-Key` header on every request.

```python
API_KEY = 'rpx_your_api_key'
ENDPOINT = 'https://renderpix.dev/v1/render'
```

---

## Basic Example — HTML to PNG

```python
import requests

def render_html(html: str, output_file: str = 'output.png') -> None:
    response = requests.post(
        'https://renderpix.dev/v1/render',
        headers={
            'X-API-Key': 'rpx_your_api_key',
            'Content-Type': 'application/json',
        },
        json={
            'html': html,
            'width': 1200,
            'height': 630,
            'format': 'png',
        },
    )
    response.raise_for_status()

    with open(output_file, 'wb') as f:
        f.write(response.content)
    print(f'Saved to {output_file}')


render_html('<h1 style="font-family:sans-serif;color:#1e293b">Hello, RenderPix!</h1>')
```

---

## Real-World Example — OG Image Generator

```python
import requests

def generate_og_image(
    title: str,
    description: str,
    domain: str,
    output_file: str = 'og.png',
) -> str:
    html = f"""<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    * {{ margin: 0; padding: 0; box-sizing: border-box; }}
    body {{
      width: 1200px; height: 630px; overflow: hidden;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
      background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
      display: flex; align-items: center; justify-content: center; padding: 80px;
    }}
    .card {{ display: flex; flex-direction: column; gap: 24px; width: 100%; }}
    .domain {{
      font-size: 20px; font-weight: 600; color: #38bdf8;
      text-transform: uppercase; letter-spacing: 2px;
    }}
    h1 {{ font-size: 72px; font-weight: 800; color: #f1f5f9; line-height: 1.1; }}
    p {{ font-size: 28px; color: #94a3b8; line-height: 1.5; }}
  </style>
</head>
<body>
  <div class="card">
    <div class="domain">{domain}</div>
    <h1>{title}</h1>
    <p>{description}</p>
  </div>
</body>
</html>"""

    response = requests.post(
        'https://renderpix.dev/v1/render',
        headers={'X-API-Key': 'rpx_your_api_key'},
        json={'html': html, 'width': 1200, 'height': 630, 'format': 'png'},
    )
    response.raise_for_status()

    with open(output_file, 'wb') as f:
        f.write(response.content)

    return output_file


# Usage
path = generate_og_image(
    title='Build Faster with RenderPix',
    description='HTML to image in one API call. No puppeteer, no headless browser.',
    domain='renderpix.dev',
)
print(f'OG image saved: {path}')
```

---

## Response Handling

A successful render returns the image binary directly.

```python
import requests

response = requests.post(
    'https://renderpix.dev/v1/render',
    headers={'X-API-Key': 'rpx_your_api_key'},
    json={'html': '<h1>Hello</h1>', 'width': 1200, 'height': 630},
)

if response.status_code == 200:
    content_type = response.headers.get('Content-Type')  # 'image/png'
    image_bytes = response.content  # raw bytes ready to save or serve
```

---

## Error Handling

```python
import requests
from requests.exceptions import ConnectionError, Timeout

def render_safe(html: str) -> bytes | None:
    try:
        response = requests.post(
            'https://renderpix.dev/v1/render',
            headers={
                'X-API-Key': 'rpx_your_api_key',
                'Content-Type': 'application/json',
            },
            json={'html': html, 'width': 1200, 'height': 630},
            timeout=30,
        )
    except (ConnectionError, Timeout) as e:
        print(f'Network error: {e}')
        return None

    if response.status_code == 401:
        raise ValueError('Invalid API key — check X-API-Key header')
    if response.status_code == 429:
        raise RuntimeError('Rate limit exceeded — slow down or upgrade plan')
    if response.status_code == 422:
        raise ValueError(f"Invalid request: {response.json().get('message')}")

    response.raise_for_status()
    return response.content


# Usage
image = render_safe('<h1>Hello</h1>')
if image:
    with open('output.png', 'wb') as f:
        f.write(image)
```

---

## Django / Flask — Serve Image Directly

```python
# Django view
from django.http import HttpResponse
import requests

def og_image(request):
    title = request.GET.get('title', 'Untitled')
    html = f'<html><body style="margin:0;background:#0f172a;display:flex;align-items:center;justify-content:center;width:1200px;height:630px"><h1 style="color:#f1f5f9;font-family:sans-serif;font-size:80px">{title}</h1></body></html>'

    r = requests.post(
        'https://renderpix.dev/v1/render',
        headers={'X-API-Key': 'rpx_your_api_key'},
        json={'html': html, 'width': 1200, 'height': 630},
        timeout=30,
    )
    r.raise_for_status()

    return HttpResponse(r.content, content_type='image/png')
```
