> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/feature-management-experimentation/new-to-fme/sdks-and-customer-deployed-components/openfeature-providers/python-sdk.md).

# OpenFeature Provider for Python SDK

Integrate your Python applications with Harness FME using the Python OpenFeature Provider, a standardized, vendor-agnostic feature flagging API. This provider implements the OpenFeature specification and bridges the OpenFeature SDK with the Harness FME Python SDK.

This page walks you through installing, configuring, and using the Python OpenFeature provider to evaluate feature flags in your Python applications.

### Before you begin <a href="#before-you-begin" id="before-you-begin"></a>

Before you begin, ensure you have the following:

* A valid [Harness FME SDK key](/feature-management-experimentation/new-to-fme/sdks-and-customer-deployed-components.md#api-keys) for your project
* Python 3.9 or later
* Access to `pip` to install dependencies

### Version compatibility <a href="#version-compatibility" id="version-compatibility"></a>

| Component                                   | Minimum Version |
| ------------------------------------------- | --------------- |
| Python                                      | 3.9 +           |
| `@splitsoftware/split-openfeature-provider` | ≥ 1.0.0         |
| OpenFeature Python SDK                      | ≥ 0.8.1         |

### Install the provider and dependencies <a href="#install-the-provider-and-dependencies" id="install-the-provider-and-dependencies"></a>

Install the Harness FME OpenFeature provider using `pip`:

```bash
pip install split-openfeature-provider==1.0.0
```

### Configure the provider <a href="#configure-the-provider" id="configure-the-provider"></a>

You can register the provider with OpenFeature in one of several ways, depending on your setup.

{% tabs %}
{% tab title="SDK API Key" %}
This example demonstrates how to use the `SplitProvider`:

```python
from openfeature import api
from split_openfeature_provider import SplitProvider
config = {
      'impressionsMode': 'OPTIMIZED',
      'impressionsRefreshRate': 30,
    }
provider = SplitProvider({"SdkKey": "<YOUR_SDK_API_KEY>", "ConfigOptions": config, "ReadyBlockTime": 5})
api.set_provider(provider)
```

{% endtab %}

{% tab title="Split Client" %}
If you want access to [additional initialization options](/feature-management-experimentation/new-to-fme/sdks-and-customer-deployed-components/server-side-sdks/python-sdk.md#configuration), you can provide a Split client to the constructor:

```python
from openfeature import api
from split_openfeature_provider import SplitProvider
from splitio import get_factory

config = {
      'impressionsMode': 'OPTIMIZED',
      'impressionsRefreshRate': 30,
    }
factory = get_factory("<YOUR_SDK_API_KEY>", config=config)
factory.block_until_ready(5)
api.set_provider(SplitProvider({"SplitClient": factory.client()}))
```

{% endtab %}
{% endtabs %}

### Construct an evaluation context <a href="#construct-an-evaluation-context" id="construct-an-evaluation-context"></a>

Provide an evaluation context with a targeting key to evaluate flags. The evaluation context passes targeting information such as user IDs, email addresses, or plan types for flag targeting.

For example:

```python
from openfeature import api
from openfeature.evaluation_context import EvaluationContext

client = api.get_client("CLIENT_NAME")

context = EvaluationContext(targeting_key="TARGETING_KEY")
value = client.get_boolean_value("FLAG_NAME", False, context)
```

If the same targeting key is reused across evaluations, set the context at the client level:

```python
context = EvaluationContext(targeting_key="TARGETING_KEY")
client.context = context
```

Or at the API level:

```python
context = EvaluationContext(targeting_key="TARGETING_KEY")
api.set_evaluation_context(context)
```

Once the context is set at the client or API level, you don't need to provide it for each evaluation.

### Asyncio mode <a href="#asyncio-mode" id="asyncio-mode"></a>

The Harness FME OpenFeature provider also supports [`asyncio` mode](/feature-management-experimentation/new-to-fme/sdks-and-customer-deployed-components/server-side-sdks/python-sdk.md#initialization-asyncio-mode).

For example:

```python
from openfeature import api
from split_openfeature_provider import SplitProviderAsync
config = {
      'impressionsMode': 'OPTIMIZED',
      'impressionsRefreshRate': 30,
    }
provider = SplitProvider({"SdkKey": "<YOUR_SDK_API_KEY>", "ConfigOptions": config, "ReadyBlockTime": 5})
await provider.create()
api.set_provider(provider)
```

To create a Split client externally for `asyncio`:

```python
from openfeature import api
from split_openfeature_provider import SplitProviderAsync
from splitio import get_factory_async

config = {
      'impressionsMode': 'OPTIMIZED',
      'impressionsRefreshRate': 30,
    }
factory = get_factory_async("<YOUR_SDK_API_KEY>", config=config)
await factory.block_until_ready(5)
provider = SplitProviderAsync({"SplitClient": factory.client()})
await provider.create()
api.set_provider(provider)
```

For `asyncio` flag evaluation:

```python
from openfeature import api
from openfeature.evaluation_context import EvaluationContext

client = api.get_client("CLIENT_NAME")

context = EvaluationContext(targeting_key="TARGETING_KEY")
value = await client.get_boolean_value_async("FLAG_NAME", False, context)
```

### Logging <a href="#logging" id="logging"></a>

The Harness FME OpenFeature provider uses Python's [`logging` library](/feature-management-experimentation/new-to-fme/sdks-and-customer-deployed-components/server-side-sdks/python-sdk.md#logging).

For example, this code sample sets all libraries using `logging` (including the provider itself) to use `DEBUG` mode:

```python
import logging

logging.basicConfig(level=logging.DEBUG)
```

### Shutting down the Split SDK factory <a href="#shutting-down-the-split-sdk-factory" id="shutting-down-the-split-sdk-factory"></a>

Before terminating the OpenFeature object, ensure the internal Split client shuts down properly.

For example:

```python
from threading import Event

destroy_event = Event()
provider._split_client_wrapper._factory.destroy(destroy_event)
destroy_event.wait()
```

For `asyncio` mode:

```python
await provider._split_client_wrapper._factory.destroy()
```

For more information, go to the [Harness FME Python OpenFeature Provider GitHub repository](https://github.com/splitio/split-openfeature-provider-python).
