Repository navigation
Releases: deftinc/feature_gate
Releases · deftinc/feature_gate
Release list
v0.2.0
Per-actor feature flags (#24)
Turn a flag on for particular users or groups without enabling it for everyone.
client.enable_actor("new_ui", "user:42") # or any object with a feature_gate_id attribute
client.disable_actor("new_ui", "org:7")
client.actors("new_ui") # ids in the order they were added
client.is_enabled("new_ui", user, user.org) # globally on, or on for any actor passed- Actors are namespaced strings (
"user:42","org:7") or objects with afeature_gate_idattribute. Bare integers are rejected so user 42 and org 42 can't collide.is_enabledskipsNoneactors. is_enabled(key, *actors)is true when the flag is on globally or for any actor passed. Pass a user together with their groups.disable()only turns off the global switch; actors keep the flag untildisable_actor().- PostgresAdapter: new
<prefix>feature_actorstable (migration0002_create_feature_actors). - PosthogAdapter: actors are stored as a
distinct_idrelease condition on the flag and evaluated by feature_gate. Other conditions you set up in PostHog are left alone, andenable_actorraisesValueErrorrather than activating an inactive flag that has them. Behavior without actors is unchanged. - See the Actors section of the README.
Upgrading
- PostgresAdapter users: run
feature-gate-migrateafter upgrading.is_enabled(key)without actors keeps working until you do, but the actor methods need the new table. - On PostHog,
disable()on a flag with actors keeps the flag active for those actors, so any other conditions on it keep running.
Full Changelog: v0.1.1...v0.2.0
v0.1.1
Configurable logging with opt-in structured JSON logs (#21)
- Every adapter (
MemoryAdapter,PostgresAdapter,PosthogAdapter) andPosthogAPIClienttakes alogger=argument. It defaults tostructlog.get_logger(), so logs follow your application's structlog configuration. - feature_gate no longer calls
structlog.configure, so creating an adapter no longer replaces your app's structlog config. - New
feature_gate.structured_loggingmodule for JSON logs:json_logger(file=None): JSON-lines logger (stdout by default) to pass aslogger=.PROCESSORS: use withstructlog.configure(processors=PROCESSORS)to render your whole app as JSON.
- See the Logging section of the README.
Breaking changes
MemoryAdapterno longer writes./logs/feature_gate.log, andPosthogAPIClientno longer writes$PROJECT_ROOT/logs/development.log;PROJECT_ROOTis no longer used. To keep a log file, passlogger=json_logger(open("logs/feature_gate.log", "a")).- Logs render however your app has configured structlog (structlog's console output if unconfigured) rather than always as JSON.
This is the first release with these changes on PyPI. 0.1.0 was never published there (PyPI blocks that filename from an earlier deleted upload).
Full Changelog: v0.0.9...v0.1.1
v0.0.9
What's changed
New: PostgreSQL adapter
PostgresAdapterstores feature flags in your own PostgreSQL database. Install it withpip install "feature_gate[postgres]"(psycopg 3). psycopg is only imported when you use this adapter, soMemoryAdapterandPosthogAdapterwork without it.- Configure it with
PostgresAdapter(database_url=...), orFEATURE_GATE_DATABASE_URL, falling back toDATABASE_URL. You can also pass an existing psycopgconnection; if it's already inside a transaction, the adapter's writes become part of it. - Behaves like
MemoryAdapter: adding a flag that already exists is harmless, a missing key raisesFeatureNotFound, andfeatures()returns flags in the order they were added.
- Configure it with
feature-gate-migratecommand creates and updates the adapter's tables on your database. Running it again only applies new migrations, and a PostgreSQL advisory lock stops two deploys from migrating at the same time. You can also call it from Python asfeature_gate.migrate.migrate(connection).- Configurable table prefix, defaulting to
feature_gate_. Set it withtable_prefix=,--table-prefixorFEATURE_GATE_TABLE_PREFIX. The migrations and the adapter must use the same prefix. - Feature IDs are UUIDv7s, created by a
<prefix>uuidv7()function the migration adds, so PostgreSQL 13 and later are supported. The full schema is in the README.
Compatibility
- PostgreSQL 13+ for the new adapter. CI tests it on PostgreSQL 16 and 18.
- Python support is unchanged (3.10+). CI runs the suite on 3.10 and 3.15.
Development & packaging
- New CI workflow runs the test suite on every pull request, on Python 3.10 and 3.15 against PostgreSQL 16 and 18.
- The publish workflow now runs the PostgreSQL tests against a
postgres:16service before publishing. - PostgreSQL tests run locally when
FEATURE_GATE_TEST_DATABASE_URLis set; otherwise they're skipped.
Full changelog: v0.0.8...v0.0.9
v0.0.8
What's changed
⚠️ Behavior change
- Default PostHog host is now
https://us.posthog.com(previously the legacyhttps://app.posthog.com). If you're on EU Cloud, setPOSTHOG_API_BASE=https://eu.posthog.com; self-hosted users should set it to their own domain.POSTHOG_API_KEYmust be a personal API key with thefeature_flag:readandfeature_flag:writescopes.
Fixes
from feature_gate.adapters import PosthogAdapter, MemoryAdapternow works as documented in the README.MemoryAdapter.addno longer creates duplicate features when the same key is added twice.FeatureNotFoundmessages now include the feature key instead of the literal text{feature_key}.reload.pyreloads the correctposthog_api_clientmodule.
Compatibility
- Tested on Python 3.10 through 3.15.
- Minimum dependency versions raised to
structlog>=26.1.0andrequests>=2.34.2.
Development & packaging
- Replaced Poetry with uv. Python 3.15.1 and uv 0.13.5 are pinned in
.tool-versionsand installed with asdf. Builds use hatchling. bin/bootstrap,bin/update,bin/ciandbin/replnow useuv sync/uv runand work with asdf 0.16+.- The publish workflow now runs the test suite before
uv buildanduv publish.
Full changelog: v0.0.7...v0.0.8
v0.0.7
What's Changed
- Add logging for Client's public API calls by @vinbarnes in #14
- add is_enabled test for the case when rate limiting error is returned by @vinbarnes in #16
Full Changelog: v0.0.6...v0.0.7
v0.0.6
What's Changed
- use append mode when writing to logs by @vinbarnes in #11
Full Changelog: v0.0.5...v0.0.6
better handling of upstream posthog errors
What's Changed
- fix KeyError by providing empty dict as default value by @vinbarnes in #10
Full Changelog: v0.0.4...v0.0.5
Better Logs
Changelog
- Make sure to create the logs directory and the log file
- Rename the log file to
feature_gate.log
Move logs to log/development.log
Changelog
- Merge #8 -- Store logs in log directory