Skip to main content

lexigram-features

Feature flag evaluation and runtime gating for the Lexigram Framework.


Overview

Feature flag evaluation and runtime gating for the Lexigram Framework. Provides a DI-friendly FeatureFlagsModule, multiple evaluation backends (in-memory, environment variables, chained, cache-backed, testing), decorator-based gates, and a FlagManager with TTL caching, runtime overrides, variant flags, and an audit log.

Full documentation: docs.lexigram.dev

Install

uv add lexigram-features

Quick Start

from lexigram import Application
from lexigram.di.module import Module, module

from lexigram.features.config import FeatureFlagsConfig
from lexigram.features.manager import FlagManager
from lexigram.features.module import FeatureFlagsModule


@module(
    imports=[
        FeatureFlagsModule.configure(
            FeatureFlagsConfig(
                initial_flags={"beta_dashboard": True},
                cache_ttl=60,
            )
        )
    ]
)
class AppModule(Module):
    pass


class DashboardService:
    def __init__(self, flags: FlagManager) -> None:
        self._flags = flags

    async def show_beta(self) -> bool:
        return await self._flags.is_enabled("beta_dashboard")

Configuration

Zero-config usage: Call FeatureFlagsModule.configure() with no arguments to start with all built-in defaults — no config file or environment variables needed. See the Config reference below for all default values.

Option 1 — YAML file (use when config lives in a single explicit file)

Declare config in a YAML file loaded at a fixed, explicit path. LEX_* environment variables override YAML values at startup.

config_section = "features" is already set on this class — section= can be omitted in all calls. Pass an explicit section= only to override the default (e.g. when this config is nested under a non-standard key).

# application.yaml — copy example.yaml for a fully-annotated starting point
features:
  enabled: true
  cache_ttl: 300
  default_enabled: false
  flag_env_prefix: "LEX_FLAG_"

Then load and wire it in your composition root:

from lexigram.features.config import FeatureFlagsConfig
from lexigram.features.module import FeatureFlagsModule

config = FeatureFlagsConfig.from_yaml("application.yaml")
app.add_module(FeatureFlagsModule.configure(config))

Environment variables override YAML values and use the LEX_FEATURES__ prefix:

LEX_FEATURES__CACHE_TTL=60
LEX_FEATURES__DEFAULT_ENABLED=false
LEX_FEATURES__FLAG_ENV_PREFIX=LEX_FLAG_

Option 2 — Profiles + Environment Variables (recommended for production, staging, Docker, CI/CD)

Loads a base application.yaml, then overlays an environment-specific file (application.production.yaml, application.staging.yaml, etc.) based on the LEX_PROFILE environment variable. LEX_* env vars are applied last as the final override layer.

# Set LEX_FEATURES__* env vars before starting the process
export LEX_FEATURES__ENABLED=true
from lexigram.features.config import FeatureFlagsConfig
from lexigram.features.module import FeatureFlagsModule

config = FeatureFlagsConfig.from_env_profile()
app.add_module(FeatureFlagsModule.configure(config))

Loading order: application.yaml (base) → application.{profile}.yaml (overlay, if LEX_PROFILE is set) → LEX_* environment variables (final override). Missing files are silently skipped so this is safe to call in all environments.

Option 3 — Python (use when config is dynamic or computed at boot)

Build config in code at boot time. Use this when settings are derived at runtime — e.g. secrets fetched from a vault, per-tenant configurations, or when you need multiple module instances with different settings.

from lexigram.features.module import FeatureFlagsModule
from lexigram.features.config import FeatureFlagsConfig

app.add_module(
    FeatureFlagsModule.configure(
        FeatureFlagsConfig(
            cache_ttl=60,
            initial_flags={"beta_dashboard": True},
        )
    )
)

Config reference

Field Default Env var Description
enabled true LEX_FEATURES__ENABLED Enable the feature flags subsystem
cache_ttl 300 LEX_FEATURES__CACHE_TTL Seconds to cache flag evaluations (0 = disabled)
default_enabled false LEX_FEATURES__DEFAULT_ENABLED Fallback result when a flag is not found in the provider
flag_env_prefix "LEX_FLAG_" LEX_FEATURES__FLAG_ENV_PREFIX Env var prefix used by EnvProvider when reading flag values
initial_flags {} Seed flags for the in-memory provider (name → enabled)

Module Factory Methods

Method Description
FeatureFlagsModule.configure(config) Features subsystem with an explicit FeatureFlagsConfig
FeatureFlagsModule.stub() In-memory module for tests, all flags disabled unless overridden

Key Features

  • DI-friendly registration: FeatureFlagsModule wires the subsystem with one call
  • Multiple backends: LocalProvider, EnvProvider, ChainedProvider, MemoryProvider, and CacheBackendFlagProvider
  • Runtime gating: feature_flag, require_flag, feature_flag_sync, and require_flag_sync decorators
  • Evaluation primitives: Flag, FlagContext, FlagEvaluation, and FlagType
  • TTL caching: flag evaluations cached in-process with a configurable TTL
  • Runtime overrides: enable(), disable(), set_override(), and clear_override() win over provider results
  • Variant flags: available through get_variant() and FlagType.VARIANT
  • Audit trail: get_audit_log() exposes override history

Testing

async with Application.boot(modules=[FeatureFlagsModule.stub()]) as app:
    # your test code
    ...
  • FeatureFlagsModule.stub() is the fastest way to import the package in tests.
  • MemoryProvider is the purpose-built test backend.
  • FlagManager.enable(), disable(), set_override(), and clear_override() let you force runtime behavior without changing stored definitions.
  • get_audit_log() is available when you need to inspect override history.

Key Source Files

File What it contains
src/lexigram/features/module.py FeatureFlagsModule.configure() and FeatureFlagsModule.stub()
src/lexigram/features/config.py FeatureFlagsConfig
src/lexigram/features/di/provider.py FeatureFlagsProvider — registers config, backends, and FlagManager
src/lexigram/features/backends/ LocalProvider, EnvProvider, ChainedProvider, MemoryProvider, CacheBackendFlagProvider
src/lexigram/features/manager/ FlagManager — evaluation, caching, overrides, audit log
src/lexigram/features/decorators/ feature_flag, require_flag and sync variants

Backends and Evaluation Flow

The shipped backends cover local development, environment-driven rollout, layered lookup, tests, and cache-backed storage:

  • LocalProvider: in-memory definitions and sync evaluation support.
  • EnvProvider: reads flags from environment variables.
  • ChainedProvider: queries multiple providers in order.
  • MemoryProvider: lightweight testing backend with explicit overrides.
  • CacheBackendFlagProvider: stores flag definitions in a cache backend.

Evaluation flows through the provider into FlagManager, which applies TTL caching, supports FlagContext, and returns FlagEvaluation data. Runtime overrides win before provider results, and variant flags are available through get_variant() and FlagType.VARIANT.

Decorators and Runtime Gates

Use decorators when you want feature checks close to the callable being guarded.

from lexigram.features.decorators import feature_flag, require_flag


@feature_flag("beta_dashboard", manager=flags, fallback=lambda *_args, **_kwargs: None)
async def render_beta() -> None: ...


@require_flag("admin_reports", manager=flags)
async def export_report() -> bytes: ...

Use the sync variants only when the active backend supports synchronous in-memory evaluation.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lexigram_features-0.1.5002.tar.gz (157.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lexigram_features-0.1.5002-py3-none-any.whl (42.5 kB view details)

Uploaded Python 3

File details

Details for the file lexigram_features-0.1.5002.tar.gz.

File metadata

  • Download URL: lexigram_features-0.1.5002.tar.gz
  • Upload date:
  • Size: 157.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.14

File hashes

Hashes for lexigram_features-0.1.5002.tar.gz
Algorithm Hash digest
SHA256 845aa107495da30c1962bf8e1d2af4fd54df70a0508424e78c3b5a5dc0c30502
MD5 87653edf72efa56399d836f35f2c01b8
BLAKE2b-256 e3f856891fbd08101d82bed223977794fd0b9fb037d99f450eb203b8ab4d7ba9

See more details on using hashes here.

File details

Details for the file lexigram_features-0.1.5002-py3-none-any.whl.

File metadata

File hashes

Hashes for lexigram_features-0.1.5002-py3-none-any.whl
Algorithm Hash digest
SHA256 80eb787ba2f724a5d4d43c2ee42a183e8dfaa5c83f77296ae2d63bbc3226f056
MD5 b6ba5fce0aa73d08c4fc91fb3d7a476e
BLAKE2b-256 faaa4ac1538fd263616876275fd531d0e726c7e13b6231940a765be400320c5e

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.5009

1 file

0.1.5007

2 files

This release

0.1.5002 This release

2 files

0.1.5001

2 files

0.1.3007

1 file

0.1.3006

1 file

0.1.3005

1 file

0.1.4

2 files

0.1.2

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page