|
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
- Batch screenshot endpoint: take 1-10 screenshots in a single request - Concurrent processing with Promise.allSettled (partial success support) - Upfront quota check for all URLs before processing - Per-URL SSRF validation via existing takeScreenshot() - Added incrementUsage() to usage middleware for granular tracking - 10 new tests covering all edge cases - Updated OpenAPI docs (JSDoc on route) - Updated Node.js and Python SDK READMEs with batch method docs |
||
|---|---|---|
| .. | ||
| src/snapapi | ||
| tests | ||
| pyproject.toml | ||
| README.md | ||
SnapAPI Python SDK
Official Python client for SnapAPI — the EU-hosted screenshot API.
Zero dependencies. Uses only Python standard library (urllib).
Installation
pip install snapapi
Quick Start
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
png = snap.capture("https://example.com")
With Options
jpg = snap.capture(
"https://example.com",
format="jpeg",
width=1920,
height=1080,
quality=90,
)
Full-Page Capture
full = snap.capture(
"https://example.com/blog",
full_page=True,
device_scale=2, # Retina
)
Mobile Viewport
mobile = snap.capture(
"https://example.com",
width=375,
height=812,
device_scale=2,
)
Wait for Dynamic Content
screenshot = snap.capture(
"https://example.com/dashboard",
wait_for_selector="#chart-loaded",
wait_until="networkidle2",
)
Dark Mode Capture
# Capture in dark mode (prefers-color-scheme: dark)
dark_screenshot = snap.capture(
"https://example.com",
dark_mode=True,
format="png",
)
Custom User Agent
# 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
# 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
# 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
# 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)
# 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
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 (320–3840) |
height |
int |
800 |
Viewport height (200–2160) |
full_page |
bool |
False |
Capture full page |
quality |
int |
80 |
JPEG/WebP quality (1–100) |
wait_for_selector |
str |
— | CSS selector to wait for |
device_scale |
float |
1 |
Device pixel ratio (1–3) |
delay |
int |
0 |
Extra delay in ms (0–5000) |
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.batch(urls, **options) -> list[dict]
Take multiple screenshots in a single request. Each URL counts as one screenshot toward usage limits.
results = snap.batch(
["https://example.com", "https://example.org"],
format="jpeg", width=1920, height=1080
)
for result in results:
if result["status"] == "success":
with open(f"{result['url']}.jpg", "wb") as f:
f.write(base64.b64decode(result["image"]))
else:
print(f"Failed: {result['url']} — {result['error']}")
- Max 10 URLs per batch
- All options (format, width, height, etc.) are shared across all URLs
- Returns partial results — some may succeed while others fail
- Response is always JSON with
{ "results": [...] }
snap.health() -> dict
Returns API health status.
EU-Hosted & GDPR Compliant
SnapAPI runs entirely on EU infrastructure (Germany). Your data never leaves the EU.