SnapAPI/sdk/python/README.md
Hoid 8a36826e35
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
feat: add POST /v1/screenshots/batch endpoint
- 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
2026-03-06 09:09:27 +01:00

6.1 KiB
Raw Permalink Blame History

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 (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.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.

License

MIT — Cloonar Technologies GmbH