feat: expose variation ID and data update status listeners#14
feat: expose variation ID and data update status listeners#14WuJiayi0307 wants to merge 5 commits into
Conversation
📝 WalkthroughWalkthroughChangesThe SDK now exposes stable variation IDs in evaluation details and supports data-update status listeners. Packaging, README examples, release metadata, singleton declarations, and tests are updated accordingly. SDK behavior and validation
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant FBClient
participant DataUpdateStatusProviderImpl
participant StatusListener
FBClient->>DataUpdateStatusProviderImpl: update_state(new State)
DataUpdateStatusProviderImpl->>DataUpdateStatusProviderImpl: snapshot state and listeners
DataUpdateStatusProviderImpl-->>StatusListener: invoke callback(State)
StatusListener-->>DataUpdateStatusProviderImpl: callback completes or raises
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
tests/test_fbclient.py (1)
32-39: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winLock down the unchanged JSON contract.
This verifies constructor compatibility but not the stated backward-compatible JSON output. Assert that
to_json_dict()remains unchanged even whenvariation_idis provided.Proposed test addition
assert detail_with_id.variation_id == "variation-id" + assert detail_with_id.to_json_dict() == legacy_detail.to_json_dict()🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_fbclient.py` around lines 32 - 39, Extend test_eval_detail_variation_id_is_backward_compatible to call to_json_dict() on detail_with_id and assert its serialized dictionary remains identical to the established legacy JSON contract, excluding variation_id. Keep the existing constructor and variation_id assertions unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@featbit_openfeature/provider.py`:
- Around line 84-94: Update shutdown so _flag_change_listener is cleared only
after _client.flag_tracker.remove_flag_change_notifier(listener) succeeds; if
removal raises, retain the listener reference so cleanup can be retried and
subsequent initialization cannot register a duplicate listener.
In `@README.md`:
- Line 21: Update the README installation sentence to say “Install the SDK using
pip” instead of “install the sdk in using pip,” while preserving the Python
compatibility statement.
In `@release/description.md`:
- Around line 4-6: Update the release-note section in description.md to use the
standard heading “Breaking changes” and the text “No breaking changes,” or
remove the empty section entirely.
---
Nitpick comments:
In `@tests/test_fbclient.py`:
- Around line 32-39: Extend test_eval_detail_variation_id_is_backward_compatible
to call to_json_dict() on detail_with_id and assert its serialized dictionary
remains identical to the established legacy JSON contract, excluding
variation_id. Keep the existing constructor and variation_id assertions
unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 457f6a3b-e2e5-43ec-a493-af734f3ee36a
📒 Files selected for processing (22)
.github/workflows/code-quality.yamlMANIFEST.inREADME.mddocs/openfeature.mdfbclient/__init__.pyfbclient/common_types.pyfeatbit_openfeature/__init__.pyfeatbit_openfeature/impl/__init__.pyfeatbit_openfeature/impl/context_converter.pyfeatbit_openfeature/impl/details_converter.pyfeatbit_openfeature/provider.pyfeatbit_openfeature/py.typedrelease/description.mdrelease/package.jsonsetup.pytests/openfeature/__init__.pytests/openfeature/fixtures/bootstrap.jsontests/openfeature/test_context_converter.pytests/openfeature/test_details_converter.pytests/openfeature/test_offline_integration.pytests/openfeature/test_provider.pytests/test_fbclient.py
💤 Files with no reviewable changes (1)
- fbclient/init.py
|
Addressed all four review findings in
Validation after the fixes: |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
fbclient/status.py (1)
59-84: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy liftPreserve transition order when publishing callbacks.
Concurrent
update_statecalls can notify in reverse order: one thread can snapshotOK, release__lock, then another can publishINTERRUPTEDbefore the first invokes its callback. Serialize queued publications in transition order while keeping user callbacks outside__lock, and add a concurrent ordering regression test.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@fbclient/status.py` around lines 59 - 84, The update_state callback flow must preserve state-transition order under concurrent calls. Modify update_state and its listener-publication mechanism to queue committed states while holding the existing lock, then drain that queue serially outside __lock so callbacks execute in transition order without invoking user listeners under the lock; add a concurrent regression test verifying ordered OK/INTERRUPTED publications.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@fbclient/status.py`:
- Around line 59-84: The update_state callback flow must preserve
state-transition order under concurrent calls. Modify update_state and its
listener-publication mechanism to queue committed states while holding the
existing lock, then drain that queue serially outside __lock so callbacks
execute in transition order without invoking user listeners under the lock; add
a concurrent regression test verifying ordered OK/INTERRUPTED publications.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 62070b14-1267-4839-993b-9a887e3830d5
📒 Files selected for processing (8)
MANIFEST.inREADME.mdfbclient/interfaces.pyfbclient/status.pyrelease/description.mdrelease/package.jsontests/test_data_update_status_provider.pytests/test_fbclient.py
💤 Files with no reviewable changes (1)
- MANIFEST.in
🚧 Files skipped from review as they are similar to previous changes (2)
- release/package.json
- tests/test_fbclient.py
Summary
This PR now contains only the FeatBit Python SDK capabilities required by the standalone OpenFeature provider:
EvalDetail.variation_idadd_listener()/remove_listener()EvalDetailconstruction, JSON output, and custom status-provider implementations1.1.8The OpenFeature provider implementation has been moved to the dedicated repository:
https://github.com/featbit/openfeature-provider-python-server
Status mapping support
The provider repository maps FeatBit SDK states as follows:
OK→ OpenFeatureREADYINTERRUPTED→STALEOFF→FATALNOT_READYValidation
58 passed52 passedv2, variantvariation-v2, statusREADYThe SDK PR remains compatible with Python 3.6–3.12. The standalone provider requires Python 3.10+.