Official Python SDK for SEER — monitor jobs, capture logs, record heartbeats, and reliably report execution results including when the network is down.
pip install seerpy
Requirements: Python 3.7 or higher. New in 0.2.x: adds the filelock dependency for cross-process offline queue locking.
from seerpy import Seer
# Initialize with your API key
# api_key= is preferred; apiKey= is kept for backwards compatibility
seer = Seer(api_key="YOUR_API_KEY")
# Your existing imports
import pandas as pd
def run_report():
data = pd.read_csv("sales_data.csv")
processed = data.groupby("region").sum()
processed.to_csv("daily_report.csv")
# job_name must match a pipeline that exists in your Seer dashboard
with seer.monitor("daily_report_job", tags=["etl", "prod"]):
run_report()That's it! SEER automatically tracks execution time, success/failure status, and sends notifications if something goes wrong. Monitoring never raises — Seer outages cannot mask your job's exception.
api_key (str, required) — Your SEER API key. apiKey= is accepted for backwards compatibility.auto_replay (bool) — Flush the offline queue once on client init. Default: False.background_replay (bool) — Start a daemon thread that flushes the queue periodically. Default: False.replay_interval (int) — Seconds between background flushes. Default: 60.base_url (str) — Override the default API host (https://api.ansrstudio.com/). Can also be set via SEER_BASE_URL.timeout (int) — HTTP timeout in seconds. Default: 30.from seerpy import Seer
import os
seer = Seer(
api_key=os.environ["SEER_API_KEY"],
auto_replay=True,
background_replay=True,
replay_interval=60,
)job_name (str, required) — Must match a pipeline that already exists in your Seer dashboard.capture_logs (bool) — Capture all stdout/stderr and logging output. Logs are synced progressively. Default: False.metadata (dict) — Custom metadata attached to the run.tags (list[str]) — Tags attached to the run (e.g. ["etl", "prod"]).with seer.monitor(
"etl_pipeline",
capture_logs=True,
metadata={"source": "postgres", "target": "s3", "env": "production"},
tags=["etl", "prod"],
):
extract_data()
transform_data()
load_data()job_name (str, required) — Name of the job sending the heartbeat.metadata (dict) — Additional context (e.g., progress, status).tags (list[str]) — Tags attached to the heartbeat.import time
for batch in range(100):
process_batch(batch)
if batch % 5 == 0:
seer.heartbeat(
"batch_processor",
metadata={"batch": batch, "progress": f"{batch}%"},
tags=["prod"],
)
time.sleep(300) # 5 minutesA result object with sent, failed, and dead_lettered counts.
~/.seer/queue (shared with the Seer CLI)endpoint, payload, created_at, attempts, idempotency_key, and base_urlfilelock; claim-by-rename (.sending) avoids double-sends~/.seer/queue/dead/result = seer.replay() print(result.sent, result.failed, result.dead_lettered)
SEER automatically captures and reports exceptions with full stack traces. Monitoring never raises — if Seer is down, the final result is queued for replay.
from seerpy import Seer
import pandas as pd
seer = Seer(api_key="YOUR_API_KEY", auto_replay=True)
# Automatic error capture
with seer.monitor("data_processing", capture_logs=True):
# This error will be automatically captured with full traceback
data = pd.read_csv("missing_file.csv")
process_data(data)
# If the API is down, the payload is saved to ~/.seer/queue and
# will be replayed automatically on the next run (auto_replay=True)
# or you can flush manually:
result = seer.replay()
print(f"Sent: {result.sent}, Failed: {result.failed}")Idempotency-Key header{key}:register then {key}:complete to avoid duplicatesauto_replay=True for scripts, background_replay=True for serverstags= to group related jobspayloads.replay_failed_payloads() — use seer.replay() instead| Variable | Purpose |
|---|---|
| SEER_API_KEY | API key (pass into Seer(api_key=...)) |
| SEER_BASE_URL | Override default API host (https://api.ansrstudio.com/) |
| SEER_QUEUE_DIR | Offline queue directory (default ~/.seer/queue) |
| SEER_QUEUE_MAX_FILES | Max queued envelopes (default 500) |
| SEER_QUEUE_MAX_BYTES | Max queue size in bytes (default 50 MiB) |
Store your API key securely using environment variables:
export SEER_API_KEY="your_api_key_here" from seerpy import Seer import os seer = Seer(api_key=os.environ["SEER_API_KEY"])
import os
from seerpy import Seer
seer = Seer(
api_key=os.getenv("SEER_API_KEY"),
auto_replay=True,
background_replay=True,
replay_interval=60,
)
def run_job():
with seer.monitor(
"example_worker",
capture_logs=True,
metadata={"env": "prod"},
tags=["worker"],
):
print("Starting work...")
for i in range(3):
print(f"step {i+1}")
seer.heartbeat("example_worker", metadata={"progress": "50%"})
print("Work complete.")
if __name__ == "__main__":
run_job()
seer.stop_background_replay()