Metadata-Version: 2.4
Name: switchbox-openfeature
Version: 0.1.0
Summary: OpenFeature provider for Switchbox feature flags
Project-URL: Homepage, https://github.com/ignat14/switchbox-sdk-python
Project-URL: Repository, https://github.com/ignat14/switchbox-sdk-python
Project-URL: Issues, https://github.com/ignat14/switchbox-sdk-python/issues
Author: Switchbox
License-Expression: MIT
Keywords: feature-flags,feature-toggles,openfeature,openfeature-provider
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: openfeature-sdk<0.11,>=0.10
Requires-Dist: switchbox-flags<1.0,>=0.7.0
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == 'dev'
Description-Content-Type: text/markdown

# switchbox-openfeature

[OpenFeature](https://openfeature.dev) provider for [Switchbox](https://switchbox.dev) feature flags.

## What is this?

A thin provider that plugs Switchbox into the vendor-neutral OpenFeature API. Your app codes against OpenFeature; Switchbox is one constructor line. Swap vendors by swapping the provider, not your call sites. That is the point: no lock-in.

The provider contains zero evaluation logic. It wraps [switchbox-flags](https://pypi.org/project/switchbox-flags/), which fetches static JSON from a CDN and evaluates rules locally in your process. Nothing about the architecture changes: same 30 second polling, same local evaluation, same deterministic rollouts. Every resolve is a direct in-process call, so evaluation costs zero network.

## Install

```bash
pip install switchbox-openfeature
```

This pulls in `openfeature-sdk` and `switchbox-flags`.

## Quick Start

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

api.set_provider(SwitchboxProvider(sdk_key="your-sdk-key-from-dashboard"))
client = api.get_client()

context = EvaluationContext(targeting_key="user-42", attributes={"plan": "pro"})

if client.get_boolean_value("new_checkout", False, context):
    show_new_checkout()
```

`SwitchboxProvider(...)` accepts every `Switchbox` constructor option (`poll_interval`, `cdn_base_url`, `on_error`, ...). To share a client you already manage, pass it instead; the provider will not close it:

```python
provider = SwitchboxProvider(client=my_switchbox)
```

## Context mapping

OpenFeature's evaluation context maps onto the Switchbox user context:

| OpenFeature | Switchbox |
|---|---|
| `targeting_key` | `user_id` (deterministic rollout bucketing) |
| every other attribute | targeting attribute, passed through as-is |

## Error behavior

- Missing flag: OpenFeature returns your code default with `FLAG_NOT_FOUND`
- Evaluated value has the wrong type: code default with `TYPE_MISMATCH`
- CDN unreachable at startup: the provider reports not-ready and OpenFeature serves code defaults (the same fail-safe posture as the SDK itself)

## License

MIT
