Storage Backends¶
Storage backends provide persistence for feature flags. The library includes three built-in backends with different characteristics and use cases.
Overview¶
All storage backends implement the StorageBackend protocol, ensuring a
consistent interface regardless of the underlying storage mechanism.
Available Backends:
Backend |
Use Case |
Requirements |
|---|---|---|
|
Development, testing, single-instance |
None (built-in) |
|
Production with SQL database |
|
|
Distributed deployments |
|
StorageBackend Protocol¶
All backends implement this protocol:
Protocols and interfaces for feature flag storage backends.
- class litestar_flags.protocols.StorageBackend[source]¶
Bases:
ProtocolProtocol for feature flag storage backends.
All storage backend implementations must implement this protocol. Methods are async to support both sync and async backends.
- Implementations:
MemoryStorageBackend: In-memory storage for development/testing
DatabaseStorageBackend: SQLAlchemy-based persistent storage
RedisStorageBackend: Redis-based distributed storage
- async get_flag(key)[source]¶
Retrieve a single flag by key.
- Parameters:
key (
str) – The unique flag key.- Return type:
- Returns:
The FeatureFlag if found, None otherwise.
- async get_flags(keys)[source]¶
Retrieve multiple flags by keys.
- Parameters:
- Return type:
- Returns:
Dictionary mapping flag keys to FeatureFlag objects.
- async get_all_active_flags()[source]¶
Retrieve all active flags.
- Return type:
- Returns:
List of all FeatureFlag objects with ACTIVE status.
- async get_override(flag_id, entity_type, entity_id)[source]¶
Retrieve entity-specific override.
- Parameters:
- Return type:
- Returns:
The FlagOverride if found, None otherwise.
- async create_flag(flag)[source]¶
Create a new flag.
- Parameters:
flag (
FeatureFlag) – The flag to create.- Return type:
- Returns:
The created flag with any generated fields populated.
- async update_flag(flag)[source]¶
Update an existing flag.
- Parameters:
flag (
FeatureFlag) – The flag with updated values.- Return type:
- Returns:
The updated flag.
- async health_check()[source]¶
Check storage backend health.
- Return type:
- Returns:
True if the backend is healthy, False otherwise.
- async get_scheduled_changes(flag_id=None, pending_only=True)[source]¶
Get scheduled changes, optionally filtered by flag and status.
- async create_scheduled_change(change)[source]¶
Create a new scheduled change.
- Parameters:
change (
ScheduledFlagChange) – The scheduled change to create.- Return type:
ScheduledFlagChange- Returns:
The created scheduled change with any generated fields populated.
- async update_scheduled_change(change)[source]¶
Update a scheduled change (e.g., mark as executed).
- Parameters:
change (
ScheduledFlagChange) – The scheduled change with updated values.- Return type:
ScheduledFlagChange- Returns:
The updated scheduled change.
- async create_time_schedule(schedule)[source]¶
Create a new time schedule.
- Parameters:
schedule (
TimeSchedule) – The time schedule to create.- Return type:
TimeSchedule- Returns:
The created time schedule with any generated fields populated.
- async create_rollout_phase(phase)[source]¶
Create a new rollout phase.
- Parameters:
phase (
RolloutPhase) – The rollout phase to create.- Return type:
RolloutPhase- Returns:
The created rollout phase with any generated fields populated.
- async get_all_segments()[source]¶
Retrieve all segments.
- Return type:
list[Segment]- Returns:
List of all Segment objects.
- async create_segment(segment)[source]¶
Create a new segment.
- Parameters:
segment (
Segment) – The segment to create.- Return type:
Segment- Returns:
The created segment with any generated fields populated.
- async update_segment(segment)[source]¶
Update an existing segment.
- Parameters:
segment (
Segment) – The segment with updated values.- Return type:
Segment- Returns:
The updated segment.
- async get_all_environments()[source]¶
Retrieve all environments.
- Return type:
list[Environment]- Returns:
List of all Environment objects.
- async get_child_environments(parent_id)[source]¶
Retrieve all child environments of a parent environment.
- async create_environment(env)[source]¶
Create a new environment.
- Parameters:
env (
Environment) – The environment to create.- Return type:
Environment- Returns:
The created environment with any generated fields populated.
- async update_environment(env)[source]¶
Update an existing environment.
- Parameters:
env (
Environment) – The environment with updated values.- Return type:
Environment- Returns:
The updated environment.
- async get_environment_flag(env_id, flag_id)[source]¶
Retrieve environment-specific flag configuration.
- async create_environment_flag(env_flag)[source]¶
Create a new environment-specific flag configuration.
- Parameters:
env_flag (
EnvironmentFlag) – The environment flag configuration to create.- Return type:
EnvironmentFlag- Returns:
The created EnvironmentFlag with any generated fields populated.
- async update_environment_flag(env_flag)[source]¶
Update an existing environment-specific flag configuration.
- Parameters:
env_flag (
EnvironmentFlag) – The environment flag configuration with updated values.- Return type:
EnvironmentFlag- Returns:
The updated EnvironmentFlag.
- async delete_environment_flag(env_id, flag_id)[source]¶
Delete an environment-specific flag configuration.
- __init__(*args, **kwargs)¶
MemoryStorageBackend¶
In-memory storage for development and testing. Data is not persisted between application restarts.
In-memory storage backend for feature flags.
- class litestar_flags.storage.memory.MemoryStorageBackend[source]¶
Bases:
objectIn-memory storage backend for development and testing.
This backend stores all data in memory and is not persistent. Ideal for development, testing, and simple single-instance deployments.
Example
>>> storage = MemoryStorageBackend() >>> await storage.create_flag(flag) >>> flag = await storage.get_flag("my-feature")
- async get_flag(key)[source]¶
Retrieve a single flag by key.
- Parameters:
key (
str) – The unique flag key.- Return type:
- Returns:
The FeatureFlag if found, None otherwise.
- async get_flags(keys)[source]¶
Retrieve multiple flags by keys.
- Parameters:
- Return type:
- Returns:
Dictionary mapping flag keys to FeatureFlag objects.
- async get_all_active_flags()[source]¶
Retrieve all active flags.
- Return type:
- Returns:
List of all FeatureFlag objects with ACTIVE status.
- async get_override(flag_id, entity_type, entity_id)[source]¶
Retrieve entity-specific override.
- Parameters:
- Return type:
- Returns:
The FlagOverride if found and not expired, None otherwise.
- async get_overrides_for_entity(entity_type, entity_id)[source]¶
Retrieve all overrides for an entity.
- Parameters:
- Return type:
- Returns:
List of non-expired overrides for the entity.
- async create_flag(flag)[source]¶
Create a new flag.
- Parameters:
flag (
FeatureFlag) – The flag to create.- Return type:
- Returns:
The created flag.
- Raises:
ValueError – If a flag with the same key already exists.
- async update_flag(flag)[source]¶
Update an existing flag.
- Parameters:
flag (
FeatureFlag) – The flag with updated values.- Return type:
- Returns:
The updated flag.
- Raises:
ValueError – If the flag does not exist.
- async create_override(override)[source]¶
Create a new override.
- Parameters:
override (
FlagOverride) – The override to create.- Return type:
- Returns:
The created override.
- async health_check()[source]¶
Check storage backend health.
- Return type:
- Returns:
Always True for in-memory storage.
- async get_scheduled_changes(flag_id=None, pending_only=True)[source]¶
Get scheduled changes, optionally filtered by flag and status.
- async create_scheduled_change(change)[source]¶
Create a new scheduled change.
- Parameters:
change (
ScheduledFlagChange) – The scheduled change to create.- Return type:
ScheduledFlagChange- Returns:
The created scheduled change.
- async update_scheduled_change(change)[source]¶
Update a scheduled change (e.g., mark as executed).
- Parameters:
change (
ScheduledFlagChange) – The scheduled change with updated values.- Return type:
ScheduledFlagChange- Returns:
The updated scheduled change.
- Raises:
ValueError – If the scheduled change does not exist.
- async create_time_schedule(schedule)[source]¶
Create a new time schedule.
- Parameters:
schedule (
TimeSchedule) – The time schedule to create.- Return type:
TimeSchedule- Returns:
The created time schedule.
- async create_rollout_phase(phase)[source]¶
Create a new rollout phase.
- Parameters:
phase (
RolloutPhase) – The rollout phase to create.- Return type:
RolloutPhase- Returns:
The created rollout phase.
- async get_all_segments()[source]¶
Retrieve all segments.
- Return type:
list[Segment]- Returns:
List of all Segment objects.
- async create_segment(segment)[source]¶
Create a new segment.
- Parameters:
segment (
Segment) – The segment to create.- Return type:
Segment- Returns:
The created segment.
- Raises:
ValueError – If a segment with the same name already exists.
- async update_segment(segment)[source]¶
Update an existing segment.
- Parameters:
segment (
Segment) – The segment with updated values.- Return type:
Segment- Returns:
The updated segment.
- Raises:
ValueError – If the segment does not exist or name conflict occurs.
- async get_all_environments()[source]¶
Retrieve all environments.
- Return type:
list[Environment]- Returns:
List of all Environment objects.
- async get_child_environments(parent_id)[source]¶
Retrieve all child environments of a parent environment.
- async create_environment(env)[source]¶
Create a new environment.
- Parameters:
env (
Environment) – The environment to create.- Return type:
Environment- Returns:
The created environment.
- Raises:
ValueError – If an environment with the same slug already exists.
- async update_environment(env)[source]¶
Update an existing environment.
- Parameters:
env (
Environment) – The environment with updated values.- Return type:
Environment- Returns:
The updated environment.
- Raises:
ValueError – If the environment does not exist or slug conflict occurs.
- async delete_environment(slug)[source]¶
Delete an environment by slug.
Also deletes all related environment flags.
- async get_environment_flag(env_id, flag_id)[source]¶
Retrieve an environment-specific flag configuration.
- async create_environment_flag(env_flag)[source]¶
Create a new environment flag configuration.
- Parameters:
env_flag (
EnvironmentFlag) – The environment flag configuration to create.- Return type:
EnvironmentFlag- Returns:
The created environment flag.
- Raises:
ValueError – If the environment flag already exists.
- async update_environment_flag(env_flag)[source]¶
Update an existing environment flag configuration.
- Parameters:
env_flag (
EnvironmentFlag) – The environment flag with updated values.- Return type:
EnvironmentFlag- Returns:
The updated environment flag.
- Raises:
ValueError – If the environment flag does not exist.
Usage¶
from litestar_flags import MemoryStorageBackend, FeatureFlagClient
# Create storage
storage = MemoryStorageBackend()
# Create client
client = FeatureFlagClient(storage=storage)
# Or via plugin configuration
from litestar_flags import FeatureFlagsConfig
config = FeatureFlagsConfig(backend="memory")
When to Use¶
Local development
Unit and integration testing
Simple single-instance deployments
Prototyping and experimentation
DatabaseStorageBackend¶
SQLAlchemy-based persistent storage using Advanced-Alchemy. Supports PostgreSQL, MySQL, SQLite, and other SQLAlchemy-compatible databases.
Database storage backend using Advanced-Alchemy.
- class litestar_flags.storage.database.DatabaseStorageBackend[source]¶
Bases:
objectDatabase storage backend using Advanced-Alchemy.
This backend stores feature flags and related data in a relational database using SQLAlchemy async operations.
Example
>>> storage = await DatabaseStorageBackend.create( ... connection_string="postgresql+asyncpg://user:pass@localhost/db" ... ) >>> flag = await storage.get_flag("my-feature")
- Parameters:
engine (
AsyncEngine)session_maker (
async_sessionmaker[AsyncSession])
- __init__(engine, session_maker)[source]¶
Initialize the database storage backend.
- Parameters:
engine (
AsyncEngine) – The SQLAlchemy async engine.session_maker (
async_sessionmaker[AsyncSession]) – The session maker factory.
- Return type:
None
- async classmethod create(connection_string, table_prefix='ff_', create_tables=True, **engine_kwargs)[source]¶
Create a new database storage backend.
- Parameters:
- Return type:
- Returns:
Configured DatabaseStorageBackend instance.
- async get_flag(key)[source]¶
Retrieve a single flag by key.
- Parameters:
key (
str) – The unique flag key.- Return type:
- Returns:
The FeatureFlag if found, None otherwise.
- async get_flags(keys)[source]¶
Retrieve multiple flags by keys.
- Parameters:
- Return type:
- Returns:
Dictionary mapping flag keys to FeatureFlag objects.
- async get_all_active_flags()[source]¶
Retrieve all active flags.
- Return type:
- Returns:
List of all FeatureFlag objects with ACTIVE status.
- async get_override(flag_id, entity_type, entity_id)[source]¶
Retrieve entity-specific override.
- Parameters:
- Return type:
- Returns:
The FlagOverride if found, None otherwise.
- async create_flag(flag)[source]¶
Create a new flag.
- Parameters:
flag (
FeatureFlag) – The flag to create.- Return type:
- Returns:
The created flag with any generated fields populated.
- async update_flag(flag)[source]¶
Update an existing flag.
- Parameters:
flag (
FeatureFlag) – The flag with updated values.- Return type:
- Returns:
The updated flag.
- async create_override(override)[source]¶
Create a new override.
- Parameters:
override (
FlagOverride) – The override to create.- Return type:
- Returns:
The created override.
- async health_check()[source]¶
Check storage backend health.
- Return type:
- Returns:
True if the backend is healthy, False otherwise.
- async get_scheduled_changes(flag_id=None, pending_only=True)[source]¶
Get scheduled changes, optionally filtered by flag and status.
- async create_scheduled_change(change)[source]¶
Create a new scheduled change.
- Parameters:
change (
ScheduledFlagChange) – The scheduled change to create.- Return type:
ScheduledFlagChange- Returns:
The created scheduled change with any generated fields populated.
- async update_scheduled_change(change)[source]¶
Update a scheduled change (e.g., mark as executed).
- Parameters:
change (
ScheduledFlagChange) – The scheduled change with updated values.- Return type:
ScheduledFlagChange- Returns:
The updated scheduled change.
- async create_time_schedule(schedule)[source]¶
Create a new time schedule.
- Parameters:
schedule (
TimeSchedule) – The time schedule to create.- Return type:
TimeSchedule- Returns:
The created time schedule with any generated fields populated.
- class litestar_flags.storage.database.FeatureFlagRepository[source]¶
Bases:
SQLAlchemyAsyncRepository[FeatureFlag]Repository for feature flag CRUD operations.
- Parameters:
session (
Union[AsyncSession,async_scoped_session[AsyncSession]])auto_expunge (
bool)auto_refresh (
bool)auto_commit (
bool)order_by (
Union[list[Union[tuple[Union[str,InstrumentedAttribute[Any]],bool],UnaryExpression[Any]]],tuple[Union[str,InstrumentedAttribute[Any]],bool],UnaryExpression[Any],None])load (
Union[Sequence[Union[_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any],Sequence[Union[_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any]]]]],_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any],ExecutableOption,Sequence[ExecutableOption],None])wrap_exceptions (
bool)kwargs (
Any)
- model_type¶
alias of
FeatureFlag
- async get_by_key(key)[source]¶
Get a flag by its unique key.
- Parameters:
key (
str) – The flag key.- Return type:
- Returns:
The flag if found, None otherwise.
- async get_by_keys(keys)[source]¶
Get multiple flags by their keys.
- Parameters:
- Return type:
- Returns:
List of found flags.
- class litestar_flags.storage.database.FlagOverrideRepository[source]¶
Bases:
SQLAlchemyAsyncRepository[FlagOverride]Repository for flag override CRUD operations.
- Parameters:
session (
Union[AsyncSession,async_scoped_session[AsyncSession]])auto_expunge (
bool)auto_refresh (
bool)auto_commit (
bool)order_by (
Union[list[Union[tuple[Union[str,InstrumentedAttribute[Any]],bool],UnaryExpression[Any]]],tuple[Union[str,InstrumentedAttribute[Any]],bool],UnaryExpression[Any],None])load (
Union[Sequence[Union[_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any],Sequence[Union[_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any]]]]],_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any],ExecutableOption,Sequence[ExecutableOption],None])wrap_exceptions (
bool)kwargs (
Any)
- model_type¶
alias of
FlagOverride
- class litestar_flags.storage.database.RolloutPhaseRepository[source]¶
Bases:
SQLAlchemyAsyncRepository[RolloutPhase]Repository for rollout phase CRUD operations.
- Parameters:
session (
Union[AsyncSession,async_scoped_session[AsyncSession]])auto_expunge (
bool)auto_refresh (
bool)auto_commit (
bool)order_by (
Union[list[Union[tuple[Union[str,InstrumentedAttribute[Any]],bool],UnaryExpression[Any]]],tuple[Union[str,InstrumentedAttribute[Any]],bool],UnaryExpression[Any],None])load (
Union[Sequence[Union[_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any],Sequence[Union[_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any]]]]],_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any],ExecutableOption,Sequence[ExecutableOption],None])wrap_exceptions (
bool)kwargs (
Any)
- model_type¶
alias of
RolloutPhase
- class litestar_flags.storage.database.ScheduledFlagChangeRepository[source]¶
Bases:
SQLAlchemyAsyncRepository[ScheduledFlagChange]Repository for scheduled flag change CRUD operations.
- Parameters:
session (
Union[AsyncSession,async_scoped_session[AsyncSession]])auto_expunge (
bool)auto_refresh (
bool)auto_commit (
bool)order_by (
Union[list[Union[tuple[Union[str,InstrumentedAttribute[Any]],bool],UnaryExpression[Any]]],tuple[Union[str,InstrumentedAttribute[Any]],bool],UnaryExpression[Any],None])load (
Union[Sequence[Union[_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any],Sequence[Union[_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any]]]]],_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any],ExecutableOption,Sequence[ExecutableOption],None])wrap_exceptions (
bool)kwargs (
Any)
- model_type¶
alias of
ScheduledFlagChange
- class litestar_flags.storage.database.TimeScheduleRepository[source]¶
Bases:
SQLAlchemyAsyncRepository[TimeSchedule]Repository for time schedule CRUD operations.
- Parameters:
session (
Union[AsyncSession,async_scoped_session[AsyncSession]])auto_expunge (
bool)auto_refresh (
bool)auto_commit (
bool)order_by (
Union[list[Union[tuple[Union[str,InstrumentedAttribute[Any]],bool],UnaryExpression[Any]]],tuple[Union[str,InstrumentedAttribute[Any]],bool],UnaryExpression[Any],None])load (
Union[Sequence[Union[_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any],Sequence[Union[_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any]]]]],_AbstractLoad,Literal['*'],InstrumentedAttribute[Any],RelationshipProperty[Any],MapperProperty[Any],ExecutableOption,Sequence[ExecutableOption],None])wrap_exceptions (
bool)kwargs (
Any)
- model_type¶
alias of
TimeSchedule
Installation¶
uv add litestar-flags[database]
pip install litestar-flags[database]
Usage¶
from litestar_flags import FeatureFlagsConfig
# PostgreSQL
config = FeatureFlagsConfig(
backend="database",
connection_string="postgresql+asyncpg://user:pass@localhost/mydb",
)
# MySQL
config = FeatureFlagsConfig(
backend="database",
connection_string="mysql+aiomysql://user:pass@localhost/mydb",
)
# SQLite (for development)
config = FeatureFlagsConfig(
backend="database",
connection_string="sqlite+aiosqlite:///flags.db",
)
Direct Usage¶
For advanced use cases, you can create the backend directly:
from litestar_flags.storage.database import DatabaseStorageBackend
storage = await DatabaseStorageBackend.create(
connection_string="postgresql+asyncpg://user:pass@localhost/mydb",
table_prefix="ff_",
create_tables=True, # Auto-create tables on startup
)
# Use with client
client = FeatureFlagClient(storage=storage)
# Don't forget to close when done
await storage.close()
When to Use¶
Production deployments requiring persistence
Multi-instance deployments with shared database
When you need transactional consistency
Integration with existing database infrastructure
RedisStorageBackend¶
Redis-based distributed storage for high-performance, distributed deployments.
Redis storage backend for feature flags.
- class litestar_flags.storage.redis.RedisStorageBackend[source]¶
Bases:
objectRedis storage backend for distributed feature flags.
This backend stores feature flags in Redis, making it suitable for distributed deployments where multiple application instances need to share flag state.
Data is stored as JSON strings with the following key patterns: - Flags: {prefix}flag:{key} - Overrides: {prefix}override:{flag_id}:{entity_type}:{entity_id} - Flag index: {prefix}flags (SET of all flag keys)
Example
>>> storage = await RedisStorageBackend.create( ... url="redis://localhost:6379", ... prefix="ff:" ... ) >>> flag = await storage.get_flag("my-feature")
- Parameters:
redis (
Redis)prefix (
str)
- __init__(redis, prefix='feature_flags:')[source]¶
Initialize the Redis storage backend.
- Parameters:
redis (
Redis) – The Redis client instance.prefix (
str) – Key prefix for all stored data.
- Return type:
None
- async classmethod create(url, prefix='feature_flags:', **redis_kwargs)[source]¶
Create a new Redis storage backend.
- Parameters:
- Return type:
- Returns:
Configured RedisStorageBackend instance.
- async get_flag(key)[source]¶
Retrieve a single flag by key.
- Parameters:
key (
str) – The unique flag key.- Return type:
- Returns:
The FeatureFlag if found, None otherwise.
- async get_flags(keys)[source]¶
Retrieve multiple flags by keys.
- Parameters:
- Return type:
- Returns:
Dictionary mapping flag keys to FeatureFlag objects.
- async get_all_active_flags()[source]¶
Retrieve all active flags.
- Return type:
- Returns:
List of all FeatureFlag objects with ACTIVE status.
- async get_override(flag_id, entity_type, entity_id)[source]¶
Retrieve entity-specific override.
- Parameters:
- Return type:
- Returns:
The FlagOverride if found and not expired, None otherwise.
- async create_flag(flag)[source]¶
Create a new flag.
- Parameters:
flag (
FeatureFlag) – The flag to create.- Return type:
- Returns:
The created flag.
- async update_flag(flag)[source]¶
Update an existing flag.
- Parameters:
flag (
FeatureFlag) – The flag with updated values.- Return type:
- Returns:
The updated flag.
- async create_override(override)[source]¶
Create a new override.
- Parameters:
override (
FlagOverride) – The override to create.- Return type:
- Returns:
The created override.
- async health_check()[source]¶
Check storage backend health.
- Return type:
- Returns:
True if the backend is healthy, False otherwise.
- async get_scheduled_changes(flag_id=None, pending_only=True)[source]¶
Get scheduled changes, optionally filtered by flag and status.
- async create_scheduled_change(change)[source]¶
Create a new scheduled change.
- Parameters:
change (
ScheduledFlagChange) – The scheduled change to create.- Return type:
ScheduledFlagChange- Returns:
The created scheduled change.
- async update_scheduled_change(change)[source]¶
Update a scheduled change (e.g., mark as executed).
- Parameters:
change (
ScheduledFlagChange) – The scheduled change with updated values.- Return type:
ScheduledFlagChange- Returns:
The updated scheduled change.
- async create_time_schedule(schedule)[source]¶
Create a new time schedule.
- Parameters:
schedule (
TimeSchedule) – The time schedule to create.- Return type:
TimeSchedule- Returns:
The created time schedule.
Installation¶
uv add litestar-flags[redis]
pip install litestar-flags[redis]
Usage¶
from litestar_flags import FeatureFlagsConfig
# Basic Redis
config = FeatureFlagsConfig(
backend="redis",
redis_url="redis://localhost:6379/0",
)
# With authentication
config = FeatureFlagsConfig(
backend="redis",
redis_url="redis://:password@localhost:6379/0",
redis_prefix="myapp:flags:", # Custom key prefix
)
# Redis Sentinel
config = FeatureFlagsConfig(
backend="redis",
redis_url="redis+sentinel://sentinel1:26379,sentinel2:26379/mymaster/0",
)
Direct Usage¶
from litestar_flags.storage.redis import RedisStorageBackend
storage = await RedisStorageBackend.create(
url="redis://localhost:6379/0",
prefix="feature_flags:",
)
client = FeatureFlagClient(storage=storage)
# Close when done
await storage.close()
Key Structure¶
Data is stored with the following key patterns:
Flags:
{prefix}flag:{key}Overrides:
{prefix}override:{flag_id}:{entity_type}:{entity_id}Flag index:
{prefix}flags(SET of all flag keys)
When to Use¶
High-performance distributed deployments
When you need fast reads across multiple instances
Microservices architecture
When database latency is a concern
Choosing a Backend¶
Criteria |
Memory |
Database |
Redis |
|---|---|---|---|
Persistence |
No |
Yes |
Yes (configurable) |
Multi-instance |
No |
Yes |
Yes |
Performance |
Fastest |
Good |
Very Fast |
Transactions |
No |
Yes |
No |
Setup complexity |
None |
Medium |
Low |
Custom Storage Backends¶
You can implement custom storage backends by implementing the StorageBackend
protocol:
from litestar_flags.protocols import StorageBackend
from litestar_flags.models import FeatureFlag, FlagOverride
from collections.abc import Sequence
from uuid import UUID
class MyCustomBackend:
"""Custom storage backend implementation."""
async def get_flag(self, key: str) -> FeatureFlag | None:
# Implement flag retrieval
...
async def get_flags(self, keys: Sequence[str]) -> dict[str, FeatureFlag]:
# Implement bulk retrieval
...
async def get_all_active_flags(self) -> list[FeatureFlag]:
# Implement active flags retrieval
...
async def get_override(
self,
flag_id: UUID,
entity_type: str,
entity_id: str,
) -> FlagOverride | None:
# Implement override retrieval
...
async def create_flag(self, flag: FeatureFlag) -> FeatureFlag:
# Implement flag creation
...
async def update_flag(self, flag: FeatureFlag) -> FeatureFlag:
# Implement flag update
...
async def delete_flag(self, key: str) -> bool:
# Implement flag deletion
...
async def health_check(self) -> bool:
# Implement health check
return True
async def close(self) -> None:
# Clean up resources
...
# Use with client
storage = MyCustomBackend()
client = FeatureFlagClient(storage=storage)