Skip to main content

Python SDK

The package name is redpennon. It requires Python 3.12+ and uses httpx. Requests go to the production API at https://api.redpennon.dev (see DEFAULT_API_BASE_URL in the client module); you only configure the environment API key (and optional timeout).

Install

When the package is on PyPI:

pip install redpennon

Configure

from redpennon import Client, UserContext

with Client(api_key="YOUR_ENVIRONMENT_API_KEY") as client:
...

You can inject an httpx.Client (for example with httpx.MockTransport) so unit tests never call the real API.

Evaluate a variable

variable_value — value or default

enabled = client.variable_value(
"show-banner",
default=False,
user=UserContext(id="user-123"),
)

default is keyword-only; user is a UserContext. Returns the served value, or default when value is None, the variable is unknown, or a transport/governance error occurs.

variable — full result

result = client.variable("checkout-flow", user=UserContext(id="user-123"))
# result.value, result.variation, result.reason, result.feature,
# result.evaluation_trace (str | None)

Returns a VariableResult dataclass with all response fields. Use when you need variation, reason, or evaluation_trace.

variables — batch

results = client.variables(
["show-banner", "discount-pct"],
user=UserContext(id="user-123"),
)
banner = results["show-banner"].value or False
discount = results["discount-pct"].value or 0

Resolves multiple variables in one round-trip. Returns dict[str, VariableResult].

VariableResult dataclass

@dataclass
class VariableResult:
key: str
value: Any # None when not served
variation: str | None
reason: str
feature: str | None
evaluation_trace: str | None = None # opaque signed token — forward to track_events

Track events

from redpennon import EventPayload, UserContext

# Evaluate first to capture the trace
user = UserContext(id="user-123")
result = client.variable("checkout-flow", user=user)

# Send the event, forwarding the trace for verified attribution
client.track_events([
EventPayload(
event="purchase",
variable="checkout-flow",
variation=result.variation,
user=user,
value=49.99,
evaluation_trace=result.evaluation_trace,
)
])

track_events POSTs to POST /v1/events and returns a TrackEventsResult(accepted=N). Raises APIError on non-202.

EventPayload dataclass

@dataclass
class EventPayload:
event: str # required
variable: str # required
variation: str # required
user: UserContext | None = None
value: float | None = None
occurred_at: str | None = None # ISO-8601
evaluation_trace: str | None = None # from VariableResult.evaluation_trace

See Ingest events for full field semantics and error codes.

Errors

Failed requests raise APIError with status_code and message. See API errors.

See also