Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion OpenFeature.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ from devcycle_python_sdk import DevCycleLocalClient, DevCycleLocalOptions
devcycle_client = DevCycleLocalClient("DEVCYCLE_SERVER_SDK_KEY", DevCycleLocalOptions())

# Set the initialzed DevCycle client as the provider for OpenFeature
api.set_provider(devcycle_client.get_openfeature_provider())
api.set_provider_and_wait(devcycle_client.get_openfeature_provider())

# Get the OpenFeature client
open_feature_client = api.get_client()
Expand All @@ -37,6 +37,25 @@ api.set_evaluation_context(EvaluationContext(targeting_key="test-1234"))
bool_flag = open_feature_client.get_boolean_value("bool-flag", False)
```

#### Provider Initialization

Use `api.set_provider_and_wait()` rather than `api.set_provider()`. The DevCycle provider waits for the
underlying DevCycle client to finish initializing and raises a `GeneralError` if it does not become ready
in time. `set_provider_and_wait()` blocks until initialization completes and surfaces that error to the
caller, so a failed startup is visible immediately.

`api.set_provider()` returns before the provider is ready. Initialization failures are reported only as a
`PROVIDER_ERROR` event on a background thread, and until the provider is ready every evaluation returns
your default value with the `PROVIDER_NOT_READY` error code. If you use `set_provider()`, register an error
handler so those failures are not silently discarded:

```python
from openfeature.event import ProviderEvent

api.add_handler(ProviderEvent.PROVIDER_ERROR, lambda details: logger.error(details.message))
api.set_provider(devcycle_client.get_openfeature_provider())
```

#### Required Targeting Key

For DevCycle SDK to work we require either a `targeting_key` or `user_id` attribute to be set on the OpenFeature context.
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ This SDK provides an alpha implementation of the [OpenFeature](https://openfeatu
from openfeature import api

devcycle_client = DevCycleLocalClient('DEVCYCLE_SERVER_SDK_KEY', options)
api.set_provider(devcycle_client.get_openfeature_provider())
api.set_provider_and_wait(devcycle_client.get_openfeature_provider())
```

Use `set_provider_and_wait()` so that initialization failures are raised to the caller. `set_provider()` returns before the provider is ready, which means a failed initialization is only reported as a background `PROVIDER_ERROR` event while evaluations return their default values.

More details are in the [DevCycle Python SDK OpenFeature Provider](OpenFeature.md) guide.

> :warning: **OpenFeature support is in an early release and may have some rough edges**. Please report any issues to us and we'll be happy to help!
Expand Down
10 changes: 9 additions & 1 deletion example/openfeature_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from openfeature import api
from openfeature.evaluation_context import EvaluationContext
from openfeature.exception import GeneralError

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -48,7 +49,14 @@ def main():
logger.info("DevCycle initialized successfully!\n")

# set the provider for OpenFeature
api.set_provider(devcycle_client.get_openfeature_provider())
# set_provider_and_wait blocks until the provider is ready and raises if it fails to
# initialize. set_provider would return immediately and evaluations would silently
# fall back to their default values until the provider became ready.
try:
api.set_provider_and_wait(devcycle_client.get_openfeature_provider())
except GeneralError as e:
logger.error(f"DevCycle OpenFeature provider failed to initialize: {e}")
exit(1)

# get the OpenFeature client
open_feature_client = api.get_client()
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ urllib3 >= 1.15.1
requests >= 2.33.0
wasmtime ~= 30.0.0
protobuf >= 4.23.3
openfeature-sdk ~= 0.8
openfeature-sdk ~= 0.10.0
launchdarkly-eventsource >= 1.2.1
Loading