-
Notifications
You must be signed in to change notification settings - Fork 3
feat(python): add Python OpenFeature provider #249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
nicklasl
wants to merge
16
commits into
main
Choose a base branch
from
nicklasl/python-provider
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Implement Python OpenFeature provider for Confidence feature flags with WASM-based local resolution. Components: - WasmResolver: Low-level WASM runtime using wasmtime - LocalResolver: Crash recovery wrapper with state restoration - StateFetcher: CDN state fetching with ETag caching - FlagLogger: Async gRPC flag logging - MaterializationStore: Sticky assignment support - ConfidenceProvider: Main OpenFeature provider implementation Features: - Local WASM-based flag resolution for low latency - Background state polling from CDN - Async flag/assignment logging via gRPC - Thread-safe resolver access - Materialization store support (sticky assignments) - Crash recovery with automatic WASM reload Co-Authored-By: Claude Opus 4.5 <[email protected]>
Match Go e2e test pattern with hardcoded constants. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Add Docker stages for building, testing, and linting the Python OpenFeature provider. Updates the Makefile to support Docker builds with proper WASM file handling. Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add timeout=30.0 to all gRPC calls (required by server) - Add InclusionReadOp and InclusionReadResult for segment targeting - Update RemoteMaterializationStore to handle both op types - Fix e2e tests to match Go test patterns (remove tutorial-feature) Co-Authored-By: Claude Opus 4.5 <[email protected]>
- WASM module is now built from wasm/rust-guest source - Removed committed WASM binary from git tracking - Added resources/wasm/ to .gitignore Co-Authored-By: Claude Opus 4.5 <[email protected]>
Co-Authored-By: Claude Opus 4.5 <[email protected]>
Co-Authored-By: Claude Opus 4.5 <[email protected]>
Replace Optional[Any] with proper types: - http_client: Optional[httpx.Client] - grpc_channel: Optional[grpc.Channel] - state_fetcher: Optional[StateFetcher] - flag_logger: Optional[FlagLogger] Co-Authored-By: Claude Opus 4.5 <[email protected]>
…dence - PyPI name: confidence-local-openfeature-provider - Import: from confidence import ConfidenceProvider - Aligns with Go provider's package naming Co-Authored-By: Claude Opus 4.5 <[email protected]>
nicklasl
commented
Jan 28, 2026
| DEFAULT_ASSIGN_POLL_INTERVAL = 0.1 | ||
|
|
||
|
|
||
| def _load_wasm_from_resources() -> bytes: |
Member
Author
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are 3 fallbacks due to Python's evolving resource loading APIs:
- importlib.resources.files() (Python 3.9+)
- The modern, recommended approach
- Works with installed packages and namespace packages
- Returns a traversable object - pkg_resources (setuptools legacy)
- Old approach, being deprecated (see the warning in tests)
- Still needed for older Python/setuptools combinations
- Works when importlib.resources doesn't find the file - Development fallback (Path-based)
- For local development with pip install -e .
- When WASM is in resources/wasm/ but not yet packaged into the wheel
- Useful during development before running make build
This complexity exists because:
- Python's resource loading has changed significantly between versions
- Editable installs (pip install -e .) behave differently than regular installs
- The WASM file location differs between development and packaged states
We could simplify this by requiring Python 3.11+ (which has stable importlib.resources), but the current code supports Python 3.9+.
- Add _status field initialized to NOT_READY - Add get_status() method - Set READY after successful initial state load - Set NOT_READY on shutdown - Recovery: if initial load fails, retry with 1s interval until success - Emit PROVIDER_READY event on status transition Matches Java provider behavior. Co-Authored-By: Claude Opus 4.5 <[email protected]>
- StateFetcher.fetch() now returns (state, account_id, changed) - changed=False when 304 Not Modified, True otherwise - _state_poll_loop only updates resolver when state changed Co-Authored-By: Claude Opus 4.5 <[email protected]>
Assignment flushing is already handled by the background thread. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Reduces code duplication across resolve_*_details methods. Adds comprehensive type mismatch tests. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Add Python OpenFeature provider for Confidence feature flags with WASM-based local resolution.
Components Implemented
wasm_resolver.py): Low-level WASM runtime using wasmtime for flag resolutionlocal_resolver.py): Crash recovery wrapper with automatic WASM reload and state restorationstate_fetcher.py): CDN state fetching with ETag caching and 304 handlingflag_logger.py): Async gRPC flag logging with ThreadPoolExecutormaterialization.py): Protocol and implementations for sticky assignments and segment inclusionprovider.py): Main OpenFeature provider implementationFeatures
my-flag.nested.value)loggingmoduleBuild
openfeature-provider-python.{test,test_e2e,lint,build,artifact}wasm-rust-guest.artifactin DockerUsage
Logging
Configure logging to see provider activity:
Test plan
make test)make test-e2e)make lint- black, flake8, mypy)🤖 Generated with Claude Code