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:
UUIDv7AuditBaseCore 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 |
|---|---|
|
Flag is live and will be evaluated normally |
|
Flag is paused; evaluations return the default value |
|
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:
UUIDv7AuditBaseTargeting 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:
UUIDv7AuditBaseVariant 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:
UUIDv7AuditBaseEntity-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.
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:
Overrides: Entity-specific overrides take highest priority
Rules: Matching rules are evaluated in priority order (lower number first)
Variants: If no rules match but variants exist, a variant is selected
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