SnapAPI/sdk/python/README.md
SnapAPI Developer 3e9336ae67
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
Add clip parameter for viewport cropping
- Add clip object parameter to crop rectangular areas from screenshots
- Support POST body: clip {x, y, width, height} number fields
- Support GET query: clipX, clipY, clipW, clipH params
- Validation: all fields required, x/y >=0, width/height >0, max 3840x2160
- Mutually exclusive with fullPage and selector
- Update OpenAPI docs with clip examples
- Update Node.js and Python SDK READMEs with clip usage
- Add comprehensive test coverage (11 new tests)
- Tests: missing fields, negative coords, zero dimensions, max limits, mutual exclusivity
2026-03-05 15:13:12 +01:00

238 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SnapAPI Python SDK
Official Python client for [SnapAPI](https://snapapi.eu) — the EU-hosted screenshot API.
**Zero dependencies.** Uses only Python standard library (`urllib`).
## Installation
```bash
pip install snapapi
```
## Quick Start
```python
from snapapi import SnapAPI
snap = SnapAPI("your-api-key")
# Capture a screenshot
screenshot = snap.capture("https://example.com")
with open("screenshot.png", "wb") as f:
f.write(screenshot)
```
## Usage
### Basic Screenshot
```python
png = snap.capture("https://example.com")
```
### With Options
```python
jpg = snap.capture(
"https://example.com",
format="jpeg",
width=1920,
height=1080,
quality=90,
)
```
### Full-Page Capture
```python
full = snap.capture(
"https://example.com/blog",
full_page=True,
device_scale=2, # Retina
)
```
### Mobile Viewport
```python
mobile = snap.capture(
"https://example.com",
width=375,
height=812,
device_scale=2,
)
```
### Wait for Dynamic Content
```python
screenshot = snap.capture(
"https://example.com/dashboard",
wait_for_selector="#chart-loaded",
wait_until="networkidle2",
)
```
### Dark Mode Capture
```python
# Capture in dark mode (prefers-color-scheme: dark)
dark_screenshot = snap.capture(
"https://example.com",
dark_mode=True,
format="png",
)
```
### Custom User Agent
```python
# Set a custom User-Agent string for the request
screenshot = snap.capture(
"https://example.com",
user_agent="Mozilla/5.0 (compatible; SnapAPI/1.0)",
format="png",
)
```
### Hide Elements Before Capture
```python
# Hide cookie banners, popups, ads
clean_screenshot = snap.capture(
"https://example.com",
hide_selectors=[
".cookie-banner",
".popup-overlay",
"#advertisement",
".tracking-notice"
],
)
# Hide single element
single_hide = snap.capture(
"https://example.com",
hide_selectors=".newsletter-popup",
)
```
### Custom CSS Injection
```python
# Inject custom CSS before capture
styled = snap.capture(
"https://example.com",
css='body { background: #1a1a2e !important; color: #eee !important }',
)
# Combine with other options
combined = snap.capture(
"https://example.com",
css=".hero { padding: 80px 0 } h1 { font-size: 48px }",
dark_mode=True,
hide_selectors=[".cookie-banner"],
)
```
### JavaScript Injection
```python
# Execute custom JavaScript before capture
interactive_screenshot = snap.capture(
"https://example.com",
js="""
// Dismiss modal popup
document.querySelector('.modal-overlay')?.remove();
// Scroll to specific content
window.scrollTo(0, 500);
// Click button to reveal content
document.querySelector('#show-more-btn')?.click();
// Wait for animation to complete
await new Promise(resolve => setTimeout(resolve, 1000));
""",
)
# Combine with other options for complex scenarios
complex_capture = snap.capture(
"https://example.com/app",
js='document.querySelector(".sidebar").style.display = "none";',
css="body { zoom: 0.8 }",
wait_for_selector="#content-loaded",
hide_selectors=[".ad-banner", ".cookie-notice"],
)
```
### Crop Specific Areas (Clip)
```python
# Crop a specific rectangular area from the screenshot
cropped_screenshot = snap.capture(
"https://example.com",
clip={
"x": 100, # X coordinate (pixels from left)
"y": 50, # Y coordinate (pixels from top)
"width": 800, # Width of the crop area
"height": 600, # Height of the crop area
},
)
# Useful for capturing specific UI elements or sections
header_screenshot = snap.capture(
"https://example.com",
clip={"x": 0, "y": 0, "width": 1280, "height": 120}, # Top banner only
format="png",
)
```
### Error Handling
```python
from snapapi import SnapAPI, SnapAPIError
snap = SnapAPI("your-api-key")
try:
screenshot = snap.capture("https://example.com")
except SnapAPIError as e:
print(f"API error {e.status}: {e.detail}")
```
## API Reference
### `SnapAPI(api_key, base_url="https://snapapi.eu", timeout=30)`
### `snap.capture(url, **options) -> bytes`
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `url` | `str` | — | URL to capture (required) |
| `format` | `str` | `"png"` | Output: `png`, `jpeg`, `webp` |
| `width` | `int` | `1280` | Viewport width (3203840) |
| `height` | `int` | `800` | Viewport height (2002160) |
| `full_page` | `bool` | `False` | Capture full page |
| `quality` | `int` | `80` | JPEG/WebP quality (1100) |
| `wait_for_selector` | `str` | — | CSS selector to wait for |
| `device_scale` | `float` | `1` | Device pixel ratio (13) |
| `delay` | `int` | `0` | Extra delay in ms (05000) |
| `wait_until` | `str` | `"domcontentloaded"` | Load event |
| `dark_mode` | `bool` | `False` | Emulate prefers-color-scheme: dark |
| `hide_selectors` | `list` | — | CSS selectors to hide before capture |
| `css` | `str` | — | Custom CSS to inject before capture (max 5000 chars) |
| `clip` | `dict` | — | Crop rectangle: `{"x": int, "y": int, "width": int, "height": int}` (mutually exclusive with full_page/selector) |
### `snap.health() -> dict`
Returns API health status.
## EU-Hosted & GDPR Compliant
SnapAPI runs entirely on EU infrastructure (Germany). Your data never leaves the EU.
## License
MIT — [Cloonar Technologies GmbH](https://snapapi.eu)