Metadata-Version: 2.4
Name: larzflags
Version: 0.1.0
Summary: Feature flags with deterministic percentage rollout, targeting rules, allow/deny lists, and variants. Pure Python, zero dependencies.
Author: larz-scripter
License: MIT
Project-URL: Homepage, https://github.com/larz-scripter/larzflags
Project-URL: Repository, https://github.com/larz-scripter/larzflags
Project-URL: Issues, https://github.com/larz-scripter/larzflags/issues
Keywords: feature-flags,feature-toggle,rollout,ab-testing,targeting,launchdarkly-alternative,experiments,flags,zero-dependency
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# larzflags

**Feature flags with deterministic rollout & targeting. Pure Python, zero deps.**

Ship code dark, turn it on for 5% of users, then 50%, then everyone - or enable it
only for a plan, a country, or an allowlist. The key property is **stable
bucketing**: a given user is always on the same side of a percentage rollout, so
nobody flickers between on and off across requests.

```python
from larzflags import FeatureFlags

flags = FeatureFlags()
flags.add("new_ui", enabled=True)
flags.add("beta", percentage=25)                       # 25% of users
flags.add("pro", rules=[("plan", "eq", "pro")])        # targeting
flags.add("vip", allow=["u1"], deny=["u2"])

flags.is_enabled("beta", user="alice")                 # stable per user
flags.is_enabled("pro", context={"plan": "pro"})       # True
```

## Why

- **Deterministic rollout.** Percentage gating hashes `flag + user`, so a user's
  on/off state is stable across requests and processes - no random flicker, and
  ramping 10% -> 50% keeps the original 10% on.
- **Targeting rules.** `("attribute", op, value)` with `eq`/`ne`/`in`/`nin`/`gt`/
  `lt`/`gte`/`lte`/`contains`, ANDed together, against a context dict.
- **Allow/deny lists** override everything for specific users.
- **A/B variants.** `variant()` returns a weighted variant chosen deterministically
  per user - perfect for experiments.
- **Zero dependencies.** No SaaS, no SDK.

## Install

```bash
pip install larzflags
```

## Usage

```python
from larzflags import FeatureFlags

flags = FeatureFlags()
flags.add("checkout_v2", percentage=10)
flags.add("eu_feature", rules=[("country", "in", ["DE", "FR", "ES"])])
flags.add("experiment", variants={"control": 50, "treatment": 50})

if flags.is_enabled("checkout_v2", user=user_id):
    ...
flags.variant("experiment", user=user_id)     # "control" or "treatment", stable
flags.all_enabled(user=user_id)               # set of on flags
flags.set_percentage("checkout_v2", 50)       # ramp up
```

## Tests

```bash
python -m unittest discover -s tests -v   # 16 tests incl. rollout distribution
```

## The Larz stack

One of 30+ pure-Python, zero-dependency libraries at
[github.com/larz-scripter](https://github.com/larz-scripter).

## License

MIT (c) larz-scripter
