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
2 changes: 1 addition & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[run]
source =
splitio/
split_openfeature_provider/

omit =
tests/*
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @splitio/sdk
* @splitio/sdk
33 changes: 15 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
name: ci

on:
push:
branches:
Expand All @@ -16,58 +17,54 @@ concurrency:
jobs:
test:
name: Test
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Setup Python
uses: actions/setup-python@v3
uses: actions/setup-python@v6
with:
python-version: '3.9.13'

- name: Install dependencies
run: |
sudo apt update
sudo apt-get install -y libkrb5-dev
pip install -U setuptools pip wheel
pip install -e .[cpphash,redis,uwsgi]
pip install pytest --quiet
pip install mock
pip install pytest-asyncio
pip install -r requirements.txt
pip install -U setuptools pip wheel
pip install -e .
pip install -r requirements-dev.txt

- name: Run tests
run: cd tests; pytest -v
- name: Run tests with coverage
working-directory: tests
run: pytest -v --cov=split_openfeature_provider --cov-report=xml:../coverage.xml

- name: Set VERSION env
run: echo "VERSION=$(cat setup.py | grep "version=" | cut -d'"' -f2)" >> $GITHUB_ENV

- name: SonarQube Scan (Push)
if: github.event_name == 'push'
uses: SonarSource/sonarcloud-github-action@v1.9
uses: SonarSource/sonarqube-scan-action@v6
env:
SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
projectBaseDir: .
args: >
-Dsonar.host.url=${{ secrets.SONARQUBE_HOST }}
-Dsonar.host.url=${{ vars.SONARQUBE_HOST }}
-Dsonar.projectVersion=${{ env.VERSION }}

- name: SonarQube Scan (Pull Request)
if: github.event_name == 'pull_request'
uses: SonarSource/sonarcloud-github-action@v1.9
uses: SonarSource/sonarqube-scan-action@v6
env:
SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
projectBaseDir: .
args: >
-Dsonar.host.url=${{ secrets.SONARQUBE_HOST }}
-Dsonar.host.url=${{ vars.SONARQUBE_HOST }}
-Dsonar.projectVersion=${{ env.VERSION }}
-Dsonar.pullrequest.key=${{ github.event.pull_request.number }}
-Dsonar.pullrequest.branch=${{ github.event.pull_request.head.ref }}
-Dsonar.pullrequest.base=${{ github.event.pull_request.base.ref }}
-Dsonar.pullrequest.base=${{ github.event.pull_request.base.ref }}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,4 @@ dmypy.json
.idea/

# Other
.DS_Store
.DS_Store
9 changes: 9 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-added-large-files
- id: check-json
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
23 changes: 11 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This SDK is compatible with Python 3.9 and higher.

This package replaces the previous `split-openfeature-provider` Python provider in [Pypi](https://pypi.org/project/split-openfeature-provider/).

### Pip Installation
### Pip Installation
```python
pip install split-openfeature-provider==1.0.0
```
Expand Down Expand Up @@ -57,12 +57,12 @@ 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 used repeatedly, the evaluation context may be set at the client level
If the same targeting key is used repeatedly, the evaluation context may be set at the client level
```python
context = EvaluationContext(targeting_key="TARGETING_KEY")
client.context = context
```
or at the OpenFeatureAPI level
or at the OpenFeatureAPI level
```python
context = EvaluationContext(targeting_key="TARGETING_KEY")
api.set_evaluation_context(context)
Expand Down Expand Up @@ -137,7 +137,7 @@ await provider._split_client_wrapper._factory.destroy()
```

## Submitting issues

The Split team monitors all issues submitted to this [issue tracker](https://github.com/splitio/split-openfeature-provider-python/issues). We encourage you to use this issue tracker to submit any bug reports, feedback, and feature enhancements. We'll do our best to respond in a timely manner.

## Contributing
Expand All @@ -147,13 +147,13 @@ Please see [Contributors Guide](CONTRIBUTORS-GUIDE.md) to find all you need to s
Licensed under the Apache License, Version 2.0. See: [Apache License](http://www.apache.org/licenses/).

## About Split

Split is the leading Feature Delivery Platform for engineering teams that want to confidently deploy features as fast as they can develop them. Split’s fine-grained management, real-time monitoring, and data-driven experimentation ensure that new features will improve the customer experience without breaking or degrading performance. Companies like Twilio, Salesforce, GoDaddy and WePay trust Split to power their feature delivery.

To learn more about Split, contact hello@split.io, or get started with feature flags for free at https://www.split.io/signup.

Split has built and maintains SDKs for:

* Java [Github](https://github.com/splitio/java-client) [Docs](https://help.split.io/hc/en-us/articles/360020405151-Java-SDK)
* Javascript [Github](https://github.com/splitio/javascript-client) [Docs](https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK)
* Node [Github](https://github.com/splitio/javascript-client) [Docs](https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK)
Expand All @@ -164,10 +164,9 @@ Split has built and maintains SDKs for:
* GO [Github](https://github.com/splitio/go-client) [Docs](https://help.split.io/hc/en-us/articles/360020093652-Go-SDK)
* Android [Github](https://github.com/splitio/android-client) [Docs](https://help.split.io/hc/en-us/articles/360020343291-Android-SDK)
* iOS [Github](https://github.com/splitio/ios-client) [Docs](https://help.split.io/hc/en-us/articles/360020401491-iOS-SDK)

For a comprehensive list of open source projects visit our [Github page](https://github.com/splitio?utf8=%E2%9C%93&query=%20only%3Apublic%20).

**Learn more about Split:**

Visit [split.io/product](https://www.split.io/product) for an overview of Split, or visit our documentation at [help.split.io](http://help.split.io) for more detailed information.

Visit [split.io/product](https://www.split.io/product) for an overview of Split, or visit our documentation at [help.split.io](http://help.split.io) for more detailed information.
5 changes: 5 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-r requirements.txt
mock>=5.0.0
pytest-asyncio>=0.21.0
pytest-cov>=4.0.0
pytest>=7.0.0
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
openfeature_sdk==0.8.3
splitio_client[cpphash,asyncio]==10.5.1
splitio_client[cpphash,asyncio]==10.5.1
1 change: 0 additions & 1 deletion split_openfeature_provider/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
from split_openfeature_provider.split_provider import SplitProvider, SplitProviderAsync
from split_openfeature_provider.split_client_wrapper import SplitClientWrapper

38 changes: 19 additions & 19 deletions split_openfeature_provider/split_client_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@
_LOGGER = logging.getLogger(__name__)

class SplitClientWrapper():

def __init__(self, initial_context):
self.sdk_ready = False
self.split_client = None

if not self._validate_context(initial_context):
raise AttributeError()
raise AttributeError()

self._api_key = initial_context.get("SdkKey")
self._config = {}
if initial_context.get("ConfigOptions") != None:
self._config = initial_context.get("ConfigOptions")

self._ready_block_time = 10
if initial_context.get("ReadyBlockTime") != None:
self._ready_block_time = initial_context.get("ReadyBlockTime")
Expand All @@ -32,66 +32,66 @@ def __init__(self, initial_context):
self.split_client = initial_context.get("SplitClient")
self._factory = self.split_client._factory
return

try:
self._factory = get_factory(self._api_key, config=self._config)
self._factory.block_until_ready(self._ready_block_time)
self.sdk_ready = True
except TimeoutException:
_LOGGER.debug("Split SDK timed out")

self.split_client = self._factory.client()

async def create(self):
if self._initial_context.get("SplitClient") != None:
self.split_client = self._initial_context.get("SplitClient")
self._factory = self.split_client._factory
return

try:
self._factory = await get_factory_async(self._api_key, config=self._config)
await self._factory.block_until_ready(self._ready_block_time)
self.sdk_ready = True
except TimeoutException:
_LOGGER.debug("Split SDK timed out")

self.split_client = self._factory.client()

def is_sdk_ready(self):
if self.sdk_ready:
return True

try:
self._factory.block_until_ready(0.1)
self.sdk_ready = True
except TimeoutException:
_LOGGER.debug("Split SDK timed out")

return self.sdk_ready

def destroy(self, destroy_event=None):
self._factory.destroy(destroy_event)

async def destroy_async(self):
await self._factory.destroy()

async def is_sdk_ready_async(self):
if self.sdk_ready:
return True

try:
await self._factory.block_until_ready(0.1)
self.sdk_ready = True
except TimeoutException:
_LOGGER.debug("Split SDK timed out")

return self.sdk_ready

def _validate_context(self, initial_context):
if initial_context != None and not isinstance(initial_context, dict):
_LOGGER.error("SplitClientWrapper: initial_context must be of type `dict`")
return False

if initial_context.get("SplitClient") == None and initial_context.get("SdkKey") == None:
_LOGGER.error("SplitClientWrapper: initial_context must contain keys `SplitClient` or `SdkKey`")
return False
Expand All @@ -103,5 +103,5 @@ def _validate_context(self, initial_context):
if initial_context.get("ConfigOptions") != None and not isinstance(initial_context.get("ConfigOptions"), dict):
_LOGGER.error("SplitClientWrapper: key `ConfigOptions` must be of type `dict`")
return False
return True

return True
Loading