Integration Model
ReplayLab is not a background listener. It captures provider calls because the SDK installs small provider wrappers in the Python process where your app code runs.
Production-Style Capture
For existing applications, initialize ReplayLab once near normal app startup:
import replaylab
from replaylab import CapturePayloadPolicy
replaylab_handle = replaylab.init(
project_name="support-bot",
auto_patch_integrations="auto",
capture_payload_policy=CapturePayloadPolicy.FULL,
)
"auto" enables all currently supported provider patchers in stable order: OpenAI, Anthropic,
Gemini, requests, and httpx. Use an explicit tuple such as
("openai", "anthropic", "gemini", "requests", "httpx") when you want a smaller production patch
surface.
After initialization, normal provider calls are captured when they run inside a ReplayLab capture scope. The scope is the request, job, or session boundary you want to persist as one capsule:
with replaylab_handle.capture("classify_ticket", session_id=ticket_id):
classify_ticket(ticket)
Provider code stays normal.
For example, an OpenAI Responses call still uses client.responses.create(...), an Anthropic
Messages call still uses client.messages.create(...), a Gemini call still uses
client.models.generate_content(...), and an HTTP call still uses requests.get(...).
This provider-level model also works inside frameworks when the framework eventually calls a
supported provider client. ReplayLab validates that shape with PydanticAI, LangGraph, LangChain,
Anthropic, and Gemini loopback scenarios, without making those optional SDKs hard ReplayLab
dependencies.
ASGI And FastAPI Middleware
For ASGI web apps, ReplayLab can open the capture scope at the request boundary for you.
This is a convenience layer over handle.capture(...); it does not introduce a separate tracing system.
from fastapi import FastAPI
app = FastAPI()
replaylab.instrument_app(app, handle=replaylab_handle, ignored_paths=("/health",))
Requests that record provider boundaries write one local capsule when the request finishes. Provider-free requests are ignored by default so health checks and static endpoints do not create noise. The middleware records safe request metadata such as method, path, status code, and an optional request ID header. It does not record framework request bodies, response bodies, cookies, or authorization header values.
Worker And Job Decorator
For background workers, ReplayLab can open the capture scope at the job-call boundary.
This is also a convenience layer over handle.capture(...).
from replaylab.integrations.jobs import capture_job
@capture_job(
handle=replaylab_handle,
name="sync_ticket",
session_id_arg="ticket_id",
queue_name="support",
)
def sync_ticket(ticket_id: str) -> dict[str, str]:
return run_ticket_sync(ticket_id)
Each decorated function call can write one local capsule when supported provider calls happen inside the function. Provider-free jobs are skipped by default so routine queue bookkeeping does not create noise.
The job adapter records safe job metadata such as job name, callable module, callable qualname, queue name, worker name, and the configured session-id argument name. It does not record job args, kwargs, return values, queue payloads, or framework-specific worker internals.
What The SDK Patches
When auto_patch_integrations is configured, ReplayLab patches supported provider constructors or helper functions in the current Python process.
It patches already-loaded provider modules and future imports.
Initialize ReplayLab before constructing provider clients.
When possible, prefer module imports such as import openai over binding constructors before ReplayLab starts, because from openai import OpenAI binds the constructor name before ReplayLab can replace the module attribute.
This matters for agent frameworks too: build PydanticAI models, LangGraph nodes, and other provider
client objects after replaylab.init(...) has installed provider wrappers.
Replay Mode
Local replay is still command-oriented in the current MVP:
uv run replaylab replay <capsule_id> -- python app.py
During that command, ReplayLab owns child-process provider patching through a Python startup hook.
Your app can keep its normal startup replaylab.init(...) and handle.capture(...) code.
In replay mode, capture scopes are no-ops and provider calls are served by the CLI-owned replay runtime.
Automatic same-process replay startup for long-lived applications that do not use replaylab replay is still a follow-up item.
replaylab run
replaylab run -- <command> remains useful for no-key dogfood examples, local scripts, CI, and generated regression tests.
It is not the required production deployment model.