Skip to content

Quickstart

Usman Abbas edited this page Jun 8, 2026 · 3 revisions

Python SDK — Quickstart

A copy-paste-ready guide to get the Convert Python SDK running in under 5 minutes.

1. Install

pip install convert-python-sdk

Or with uv:

uv add convert-python-sdk

The install includes httpx as the default HTTP client — no extra install is needed. Python 3.9 or newer is required. To swap the default transport, see Extending.

2. Full Working Example

import os

from convert_sdk import (
    Core,
    SDKConfig,
    TransportConfig,
    FeatureStatus,
    ConversionStatus,
)

# 1. Initialize the SDK (sync, blocking)
core = Core(
    SDKConfig(
        sdk_key=os.environ["CONVERT_SDK_KEY"],
        environment="production",
        transport=TransportConfig(
            base_url="https://cdn-4.convertexperiments.com",
        ),
    )
).initialize()

# 2. Verify the SDK is ready
assert core.is_ready, "SDK failed to initialize"

# 3. Create a visitor context
context = core.create_context(
    "visitor-123",
    visitor_attributes={"country": "US", "plan": "premium"},
)

# 4. Run an experience
result = context.run_experience("homepage-redesign")

if result is not None:
    print(f"Experience: {result.experience_key}")
    print(f"Variation:  {result.variation_key}")

# 5. Resolve a feature flag
feature = context.run_feature("dark-mode")

if feature is not None and feature.status == FeatureStatus.ENABLED:
    theme = feature.variables.get("theme", "dark")
    print(f"Dark mode theme: {theme}")

# 6. Track a conversion with revenue
result = context.track_conversion(
    "purchase-completed",
    revenue=49.99,
    conversion_data={"transaction_id": "txn-abc-123"},
)
if result.status is ConversionStatus.QUEUED:
    print("conversion queued")

# 7. Flush queued tracking events before the process exits or the request ends
core.flush()
core.close()

Key Points

  • Synchronous: The Python SDK is fully synchronous. There is no on_ready() coroutine. Core(SDKConfig(...)).initialize() blocks while the config is fetched and returns when the SDK is ready.
  • is_ready: Read core.is_ready after initialize(); it is True once the snapshot is loaded. A failed config fetch raises ConfigLoadError from initialize(), so reaching core.is_ready already implies success.
  • No auto-flush by default: Tracking events are queued in-process. Call core.flush() explicitly at end-of-request, before exit, or in a finally block. See Code Examples — Queue Control.
  • Config refresh is opt-in: Long-running services that want background config refresh must pass SDKConfig(refresh=RefreshConfig(...)). See Initialization § automatic config refresh.
  • None is a normal outcome: run_experience() and run_feature() return None when the visitor doesn't qualify — no exception is raised.
  • Goal not found is a result, not an exception: track_conversion() returns a ConversionResult with status == ConversionStatus.GOAL_NOT_FOUND when the goal key is absent from the config — it never raises for this case.

Direct config (no network)

For tests, CI, or local development, pass an inline config dict:

from convert_sdk import Core, SDKConfig

core = Core(SDKConfig(data={
    "account_id": "1001",
    "project": {"id": "2002", "name": "Demo"},
    "experiences": [],
    "features": [],
    "goals": [],
})).initialize()

Context manager

from convert_sdk import Core, SDKConfig

with Core(SDKConfig(data=project_config)).initialize() as core:
    context = core.create_context("visitor-1")
    result = context.run_experience("checkout-experiment")
# core.close() called automatically; queued events flushed

Next Steps

Clone this wiki locally