Models

Data models representing feature flags and their components. These models are used for creating, storing, and evaluating feature flags.

Overview

The litestar-flags library provides four main models:

  • FeatureFlag: The core flag entity with configuration and metadata

  • FlagRule: Targeting rules for conditional evaluation

  • FlagVariant: Variants for A/B testing and multivariate flags

  • FlagOverride: Entity-specific overrides for individual users or organizations

Note

When advanced-alchemy is installed, these models are SQLAlchemy ORM models with database persistence. Otherwise, they are simple dataclasses suitable for in-memory or Redis storage.

FeatureFlag

The core feature flag model containing configuration and relationships.

Feature flag model.

class litestar_flags.models.flag.FeatureFlag[source]

Bases: UUIDv7AuditBase

Core feature flag model.

Uses UUIDv7 for time-sortable IDs and automatic audit timestamps.

key

Unique identifier for the flag (used in code).

name

Human-readable name for the flag.

description

Optional description of the flag’s purpose.

flag_type

The type of value the flag returns.

status

Current lifecycle status of the flag.

default_enabled

Default boolean value when flag type is BOOLEAN.

default_value

Default value for non-boolean flags (stored as JSON).

tags

List of tags for organizing flags.

metadata

Additional metadata stored as JSON.

rules

Targeting rules for conditional evaluation.

overrides

Entity-specific overrides.

variants

Variants for A/B testing.

key: Mapped[str]
name: Mapped[str]
__init__(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any mapped columns or relationships.

id: UUID

UUID Primary key column.

description: Mapped[str | None]
flag_type: Mapped[FlagType]
status: Mapped[FlagStatus]
default_enabled: Mapped[bool]
default_value: Mapped[dict[str, Any] | None]
tags: Mapped[list[str]]
metadata_: Mapped[dict[str, Any]]
rules: Mapped[list[FlagRule]]
overrides: Mapped[list[FlagOverride]]
variants: Mapped[list[FlagVariant]]
scheduled_changes: Mapped[list[ScheduledFlagChange]]
time_schedules: Mapped[list[TimeSchedule]]
rollout_phases: Mapped[list[RolloutPhase]]
created_at: datetime | None

Date/time of instance creation.

updated_at: datetime | None

Date/time of instance last update.

Creating Flags

from litestar_flags.models import FeatureFlag
from litestar_flags.types import FlagType, FlagStatus

# Boolean flag (most common)
flag = FeatureFlag(
    key="new-checkout",
    name="New Checkout Flow",
    description="Enable the redesigned checkout experience",
    flag_type=FlagType.BOOLEAN,
    status=FlagStatus.ACTIVE,
    default_enabled=False,
    tags=["checkout", "experiment"],
)

# String flag for variants
flag = FeatureFlag(
    key="button-color",
    name="Button Color Experiment",
    flag_type=FlagType.STRING,
    default_value={"value": "blue"},
)

# JSON flag for complex configuration
flag = FeatureFlag(
    key="feature-limits",
    name="Feature Limits",
    flag_type=FlagType.JSON,
    default_value={
        "max_items": 100,
        "rate_limit": 1000,
        "features": ["basic", "advanced"],
    },
)

Flag Lifecycle

Flags have three lifecycle statuses:

Status

Description

ACTIVE

Flag is live and will be evaluated normally

INACTIVE

Flag is paused; evaluations return the default value

ARCHIVED

Flag is retired; evaluations return the default value

FlagRule

Targeting rules for conditional flag evaluation based on context attributes.

Flag rule model for targeting conditions.

class litestar_flags.models.rule.FlagRule[source]

Bases: UUIDv7AuditBase

Targeting rule for conditional flag evaluation.

Rules are evaluated in priority order (lower number = higher priority). The first matching rule determines the flag value.

flag_id

Reference to the parent flag.

name

Name of the rule for identification.

description

Optional description of what this rule targets.

priority

Evaluation order (lower = evaluated first).

enabled

Whether this rule is active.

conditions

JSON array of condition objects.

serve_enabled

Boolean value to serve when rule matches (for boolean flags).

serve_value

Value to serve when rule matches (for non-boolean flags).

rollout_percentage

Optional percentage rollout (0-100).

flag

Reference to the parent FeatureFlag.

Example conditions format:

[
    {"attribute": "country", "operator": "in", "value": ["US", "CA"]},
    {"attribute": "plan", "operator": "eq", "value": "premium"}
]
name: Mapped[str]
flag_id: Mapped[UUID]
__init__(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any mapped columns or relationships.

id: UUID

UUID Primary key column.

description: Mapped[str | None]
priority: Mapped[int]
enabled: Mapped[bool]
conditions: Mapped[list[dict[str, Any]]]
serve_enabled: Mapped[bool]
serve_value: Mapped[dict[str, Any] | None]
rollout_percentage: Mapped[int | None]
flag: Mapped[FeatureFlag]
created_at: datetime | None

Date/time of instance creation.

updated_at: datetime | None

Date/time of instance last update.

Rule Conditions

Rules use a JSON array of condition objects for targeting:

from litestar_flags.models import FlagRule

# Target premium users
rule = FlagRule(
    name="Premium Users",
    priority=1,  # Lower number = higher priority
    conditions=[
        {"attribute": "plan", "operator": "eq", "value": "premium"},
    ],
    serve_enabled=True,
)

# Target users in specific countries
rule = FlagRule(
    name="US and Canada",
    priority=2,
    conditions=[
        {"attribute": "country", "operator": "in", "value": ["US", "CA"]},
    ],
    serve_enabled=True,
)

# Multiple conditions (AND logic)
rule = FlagRule(
    name="Premium Beta Testers",
    priority=1,
    conditions=[
        {"attribute": "plan", "operator": "eq", "value": "premium"},
        {"attribute": "beta_tester", "operator": "eq", "value": True},
    ],
    serve_enabled=True,
)

Percentage Rollouts

Use rollout_percentage for gradual rollouts:

# Enable for 25% of users
rule = FlagRule(
    name="25% Rollout",
    priority=1,
    conditions=[],  # No conditions = matches all
    serve_enabled=True,
    rollout_percentage=25,  # 0-100
)

FlagVariant

Variants for multivariate flags and A/B testing experiments.

Flag variant model for A/B testing.

class litestar_flags.models.variant.FlagVariant[source]

Bases: UUIDv7AuditBase

Variant for multivariate flags and A/B testing.

Weights should sum to 100 for percentage-based distribution. If weights don’t sum to 100, they will be normalized.

flag_id

Reference to the parent flag.

key

Unique key for this variant within the flag.

name

Human-readable name for the variant.

description

Optional description of the variant.

value

The value to return when this variant is selected.

weight

Distribution weight (0-100) for this variant.

flag

Reference to the parent FeatureFlag.

Example

# A/B test with 50/50 split variant_a = FlagVariant(key=”control”, name=”Control”, weight=50, value={}) variant_b = FlagVariant(key=”treatment”, name=”Treatment”, weight=50, value={“new_ui”: True})

key: Mapped[str]
name: Mapped[str]
__init__(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any mapped columns or relationships.

flag_id: Mapped[UUID]
id: UUID

UUID Primary key column.

description: Mapped[str | None]
value: Mapped[dict[str, Any]]
weight: Mapped[int]
flag: Mapped[FeatureFlag]
created_at: datetime | None

Date/time of instance creation.

updated_at: datetime | None

Date/time of instance last update.

A/B Testing Setup

from litestar_flags.models import FeatureFlag, FlagVariant
from litestar_flags.types import FlagType

flag = FeatureFlag(
    key="checkout-experiment",
    name="Checkout A/B Test",
    flag_type=FlagType.JSON,
)

# 50/50 split
variant_a = FlagVariant(
    key="control",
    name="Control Group",
    weight=50,
    value={"layout": "classic", "button_color": "blue"},
)

variant_b = FlagVariant(
    key="treatment",
    name="Treatment Group",
    weight=50,
    value={"layout": "modern", "button_color": "green"},
)

flag.variants = [variant_a, variant_b]

Multiple Variants

# Three-way split
variants = [
    FlagVariant(key="control", name="Control", weight=33, value={"theme": "classic"}),
    FlagVariant(key="modern", name="Modern UI", weight=33, value={"theme": "modern"}),
    FlagVariant(key="minimal", name="Minimal UI", weight=34, value={"theme": "minimal"}),
]

FlagOverride

Entity-specific overrides that take precedence over rules and defaults.

Flag override model for entity-specific overrides.

class litestar_flags.models.override.FlagOverride[source]

Bases: UUIDv7AuditBase

Entity-specific flag override.

Overrides take precedence over rules and default values. They allow specific users, organizations, or other entities to have a different flag value than what rules would determine.

flag_id

Reference to the parent flag.

entity_type

Type of entity (e.g., “user”, “organization”, “tenant”).

entity_id

Identifier of the specific entity.

enabled

Whether the flag is enabled for this entity.

value

Optional value override for non-boolean flags.

expires_at

Optional expiration time for the override.

flag

Reference to the parent FeatureFlag.

Example:

# Enable beta feature for specific user
override = FlagOverride(
    entity_type="user",
    entity_id="user-123",
    enabled=True,
)

# Temporary override with expiration
override = FlagOverride(
    entity_type="organization",
    entity_id="org-456",
    enabled=True,
    expires_at=datetime(2024, 12, 31),
)
entity_type: Mapped[str]
entity_id: Mapped[str]
__init__(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any mapped columns or relationships.

enabled: Mapped[bool]
flag_id: Mapped[UUID]
id: UUID

UUID Primary key column.

value: Mapped[dict[str, Any] | None]
expires_at: Mapped[datetime | None]
flag: Mapped[FeatureFlag]
created_at: datetime | None

Date/time of instance creation.

updated_at: datetime | None

Date/time of instance last update.

is_expired(now=None)[source]

Check if this override has expired.

Parameters:

now (datetime | None) – Current time to check against. Defaults to UTC now.

Return type:

bool

Returns:

True if the override has expired.

User Overrides

from litestar_flags.models import FlagOverride
from datetime import datetime, timedelta

# Enable feature for specific user
override = FlagOverride(
    flag_id=flag.id,
    entity_type="user",
    entity_id="user-123",
    enabled=True,
)

# Temporary override with expiration
override = FlagOverride(
    flag_id=flag.id,
    entity_type="user",
    entity_id="user-456",
    enabled=True,
    expires_at=datetime.now() + timedelta(days=30),
)

Organization Overrides

# Enable for entire organization
override = FlagOverride(
    flag_id=flag.id,
    entity_type="organization",
    entity_id="org-789",
    enabled=True,
)

Evaluation Priority

When evaluating a flag, the system checks in this order:

  1. Overrides: Entity-specific overrides take highest priority

  2. Rules: Matching rules are evaluated in priority order (lower number first)

  3. Variants: If no rules match but variants exist, a variant is selected

  4. Default: The flag’s default value is used as fallback

Request comes in with context
        |
        v
Check for entity override -----> Override found? --> Return override value
        |
        | No override
        v
Evaluate rules in priority order --> Rule matches? --> Return rule value
        |
        | No match
        v
Select variant (if any) ---------> Variant selected? --> Return variant value
        |
        | No variants
        v
Return default value