Pricing Docs About
Get Started
Ready to start creating map animations? Get Started Free →

Python SDK

The official Python SDK for Georender. Simplifies authentication, request handling, and async job management.

Installation

pip install georender

Quick Start

import georender

# Initialize client
client = georender.Client(api_key="gr_live_xxxxxxxxxxxx")

# Create a render job
job = client.render(
    waypoints=[
        {"lat": 29.9792, "lng": 32.5731, "label": "Suez Canal"},
        {"lat": 1.2644, "lng": 103.8176, "label": "Singapore"},
    ],
    style="maritime-dark",
    duration=12
)

# Wait for completion
video = job.wait()
print(video.url)
# https://cdn.georender.io/renders/job_8f3k2m9x.mp4

Async Usage

import asyncio
import georender

async def main():
    client = georender.AsyncClient(api_key="gr_live_xxxxxxxxxxxx")

    job = await client.render(
        waypoints=[
            {"lat": 29.9792, "lng": 32.5731, "label": "Suez Canal"},
            {"lat": 1.2644, "lng": 103.8176, "label": "Singapore"},
        ],
        style="maritime-dark"
    )

    video = await job.wait()
    print(video.url)

asyncio.run(main())

Client Options

client = georender.Client(
    api_key="gr_live_xxxxxxxxxxxx",
    base_url="https://api.georender.io/v1",  # Optional
    timeout=30,  # Request timeout in seconds
    max_retries=3  # Retry failed requests
)

Render Options

job = client.render(
    # Required
    waypoints=[
        {"lat": 29.9792, "lng": 32.5731, "label": "Suez Canal"},
        {"lat": 1.2644, "lng": 103.8176, "label": "Singapore"},
    ],

    # Optional
    mode="route_animation",
    style="maritime-dark",
    duration=15,
    resolution="4k",
    fps=60,
    transport="ship",

    # Advanced
    route_style={
        "color": "#00D4FF",
        "width": 4,
        "vehicle_icon": "ship"
    },
    camera={
        "preset": "global_corridor_reveal",
        "intensity": "bold"
    },
    hud={
        "stats": {"show_distance": True},
        "progress_bar": True
    },
    webhook_url="https://your-server.com/webhook"
)

Job Management

# Check status without waiting
job = client.render(waypoints=[...])
print(job.id)  # job_8f3k2m9x
print(job.status)  # "queued"

# Poll for status
job.refresh()
print(job.status)  # "processing"

# Wait with timeout
try:
    video = job.wait(timeout=120)  # Wait up to 2 minutes
except georender.TimeoutError:
    print("Render took too long")

# Wait with callback
def on_progress(job):
    print(f"Status: {job.status}")

video = job.wait(callback=on_progress)

Video Object

video = job.wait()

print(video.url)        # https://cdn.georender.io/renders/job_xxx.mp4
print(video.thumbnail)  # https://cdn.georender.io/renders/job_xxx_thumb.jpg
print(video.duration)   # 12
print(video.resolution) # "1920x1080"
print(video.file_size)  # 18432000
print(video.expires_at) # datetime object

# Download the video
video.download("output.mp4")

Templates

# Create a template
template = client.templates.create(
    name="suez-cinematic",
    style="maritime-dark",
    duration=15,
    camera={"preset": "canal_bottleneck"}
)

# List templates
templates = client.templates.list()

# Use a template
job = client.render(
    template_id="suez-cinematic",
    waypoints=[...]
)

Batch Rendering

# Submit multiple jobs at once (Studio tier only)
batch = client.render_batch(
    jobs=[
        {"waypoints": [...], "style": "maritime-dark"},
        {"waypoints": [...], "style": "satellite"},
        {"waypoints": [...], "style": "geopolitics"},
    ],
    webhook_url="https://your-server.com/batch-complete"
)

print(batch.id)  # batch_xyz123
print(batch.jobs)  # List of job objects

# Wait for all jobs
results = batch.wait()
for video in results:
    print(video.url)

Error Handling

import georender
from georender.exceptions import (
    AuthenticationError,
    ValidationError,
    RateLimitError,
    RenderLimitError,
)

try:
    job = client.render(waypoints=[...])
    video = job.wait()
except AuthenticationError:
    print("Invalid API key")
except ValidationError as e:
    print(f"Invalid request: {e.message}")
    print(f"Fields: {e.fields}")
except RateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after} seconds")
except RenderLimitError:
    print("Monthly render limit exceeded")
except georender.GeoRenderError as e:
    print(f"API error: {e}")

Checking Usage

usage = client.usage()

print(usage.renders_used)      # 35
print(usage.renders_limit)     # 50
print(usage.renders_remaining) # 15
print(usage.period_end)        # datetime object