Skip to content

Releases: FtrOnOff/ftrio-python

Release list

1.0.1

Choose a tag to compare

@TheScottBot TheScottBot released this 08 Jul 22:15

FtrIO Python v1.0.1

Released: 2026-07-08

A patch release completing case-insensitive key handling across every configuration source, so keys resolve the same on every platform.

Fixed

  • Config keys are now matched case-insensitively. AppSettingsConfiguration.get_value resolves colon-path keys regardless of case (e.g. Toggles:newcheckout finds Toggles:NewCheckout), mirroring Microsoft.Extensions.Configuration's OrdinalIgnoreCase comparer. An exact match is still preferred as a fast path.
  • Environment-variable buffer mode now works on Windows. EnvironmentVariableToggleParser matched its prefix case-sensitively, but Windows uppercases env-var names at the OS boundary (FTRIO__Toggles__BufA becomes FTRIO__TOGGLES__BUFA), so buffer mode staged nothing there. The prefix is now matched case-insensitively; the extracted key keeps the OS-provided case, which is harmless because toggle keys are compared case-insensitively throughout. Standalone mode was already correct and is unchanged.

Internal

  • Added a hidden conformance-resolve CLI command (help suppressed, not user-facing) that reads one resolution case as JSON on stdin and prints the outcome as JSON, letting the cross-language ftrio-conformance matrix exercise the port's real resolution logic.

Notes

No API or behavioural changes for correctly-cased keys; existing configurations continue to work unchanged. This is the environment/OS counterpart to the JSON-side config fix, making key handling consistently case-insensitive across every source on every platform.

Full changelog: v1.0.0...v1.0.1

1.0.0

Choose a tag to compare

@TheScottBot TheScottBot released this 02 Jul 13:20
1c04c1c

FtrIO for Python 1.0.0

Initial release. A faithful Python port of the .NET
FtrIO feature-toggle library.

Decorate a function with @toggle and it is gated by its own name. Add a matching
key to appsettings.json, and the function runs only when the toggle is on. Richer
decisions (percentage rollouts, A/B buckets, blue/green slots, user and attribute
targeting, per-user overrides) layer in through a strategy chain. The core depends
on the standard library only.

Install

pip install ftrio

Optional Azure App Configuration provider:

pip install "ftrio[azure]"

Highlights

  • @toggle / @toggle_async decorators: gate a function by its own name; off
    returns None (sync) or an awaitable resolving to None (async), so await is
    always safe.
  • Strategy chain: Boolean (always-on fallback), PercentageRollout ("20%"),
    UserTargeting ("users:alice,bob"), AttributeRule
    ("attribute:plan equals premium", seven operators), ABTest ("ab:50"), and
    BlueGreen ("blue" / "green"). First match wins.
  • Deterministic A/B: the same user, key, and salt always bucket identically, and
    identically to the .NET implementation (SHA-256, first four bytes little-endian
    signed, absolute value mod 100).
  • Per-user overrides: TogglesOverrides win unconditionally, before any strategy.
  • Parsers: appsettings.json, strategy chain, environment variables (standalone or
    buffered), and a first-wins CompositeToggleParser.
  • Providers + buffer: ToggleProviderBuffer flushes staged values to
    appsettings.json atomically; HTTP (stdlib) and Azure App Config (optional extra)
    providers, both fail-safe.
  • Configuration: colon-path access, environment overlay
    (appsettings.{Environment}.json), and reload-on-change, replicating
    IConfiguration with the standard library only.
  • ftrio lint CLI: flags any @toggle function whose key is missing from
    appsettings.json (diagnostic FTRIO001); supports --exclude, default excludes,
    and -v/--verbose. Exits non-zero to gate CI.
  • python -m playground: a live demo honouring reload-on-change.

Notes for adopters

  • Toggle keys follow the host language's method-naming convention: snake_case keys
    derived from snake_case method names. The PascalCase in the .NET original was a C#
    artifact, not part of the wire contract (which is the JSON shape).
  • Exceptions use the Python-canonical *Error suffix (ToggleDoesNotExistError,
    ToggleParsedOutOfRangeError, ToggleAttributeMissingError).

Quality

Full pytest suite (re-proving every behaviour the .NET NUnit suite covers),
ruff (including pep8-naming) clean, and mypy clean on the public surface.

Links