Skip to content

Commit fc445d4

Browse files
authored
Merge branch 'main' into feat/gherkin_and_testcontainers
2 parents 7c809e8 + a17c0e7 commit fc445d4

File tree

13 files changed

+465
-39
lines changed

13 files changed

+465
-39
lines changed

.github/workflows/build.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
runs-on: ubuntu-latest
2323
strategy:
2424
matrix:
25-
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
25+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
2626
package:
2727
- "hooks/openfeature-hooks-opentelemetry"
2828
- "providers/openfeature-provider-flagd"
@@ -38,9 +38,10 @@ jobs:
3838
python-version: ${{ matrix.python-version }}
3939
cache: "pip"
4040

41-
- uses: bufbuild/buf-setup-action@v1.28.1
41+
- uses: bufbuild/buf-action@v1
4242
with:
4343
github_token: ${{ github.token }}
44+
setup_only: true
4445

4546
- name: Install hatch
4647
run: pip install hatch
@@ -49,8 +50,9 @@ jobs:
4950
run: hatch run cov
5051
working-directory: ${{ matrix.package }}
5152

52-
- name: Upload coverage to Codecov
53-
uses: codecov/[email protected]
53+
- if: matrix.python-version == '3.11'
54+
name: Upload coverage to Codecov
55+
uses: codecov/[email protected]
5456
with:
5557
name: Code Coverage for ${{ matrix.package }} on Python ${{ matrix.python-version }}
5658
directory: ${{ matrix.package }}
@@ -69,7 +71,7 @@ jobs:
6971
cache: "pip"
7072

7173
- name: Run pre-commit
72-
uses: pre-commit/[email protected].0
74+
uses: pre-commit/[email protected].1
7375

7476
sast:
7577
runs-on: ubuntu-latest

.pre-commit-config.yaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
default_stages: [commit]
22
repos:
33
- repo: https://github.com/astral-sh/ruff-pre-commit
4-
rev: v0.3.3
4+
rev: v0.6.3
55
hooks:
66
- id: ruff
77
args: [--fix]
88
- id: ruff-format
99

1010
- repo: https://github.com/pre-commit/pre-commit-hooks
11-
rev: v4.5.0
11+
rev: v4.6.0
1212
hooks:
1313
- id: check-toml
1414
- id: check-yaml
1515
- id: trailing-whitespace
1616
- id: check-merge-conflict
1717

1818
- repo: https://github.com/pre-commit/mirrors-mypy
19-
rev: v1.9.0
19+
rev: v1.11.2
2020
hooks:
2121
- id: mypy
2222
args: [--python-version=3.8]
@@ -25,6 +25,7 @@ repos:
2525
- opentelemetry-api
2626
- types-protobuf
2727
- types-PyYAML
28+
- types-requests
2829
- mmh3
2930
- semver
3031
- panzi-json-logic

.release-please-manifest.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
22
"hooks/openfeature-hooks-opentelemetry": "0.1.3",
3-
"providers/openfeature-provider-flagd": "0.1.5"
3+
"providers/openfeature-provider-flagd": "0.1.5",
4+
"providers/openfeature-provider-ofrep": "0.1.0"
45
}

providers/openfeature-provider-flagd/src/openfeature/contrib/provider/flagd/resolvers/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import typing
22

3-
from typing_extensions import Protocol
4-
53
from openfeature.evaluation_context import EvaluationContext
64
from openfeature.flag_evaluation import FlagResolutionDetails
75

86
from .grpc import GrpcResolver
97
from .in_process import InProcessResolver
108

119

12-
class AbstractResolver(Protocol):
10+
class AbstractResolver(typing.Protocol):
1311
def shutdown(self) -> None: ...
1412

1513
def resolve_boolean_details(

providers/openfeature-provider-flagd/src/openfeature/contrib/provider/flagd/resolvers/process/custom_ops.py

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
import typing
3+
from dataclasses import dataclass
34

45
import mmh3
56
import semver
@@ -10,6 +11,12 @@
1011
logger = logging.getLogger("openfeature.contrib")
1112

1213

14+
@dataclass
15+
class Fraction:
16+
variant: str
17+
weight: int = 1
18+
19+
1320
def fractional(data: dict, *args: JsonLogicArg) -> typing.Optional[str]:
1421
if not args:
1522
logger.error("No arguments provided to fractional operator.")
@@ -32,28 +39,51 @@ def fractional(data: dict, *args: JsonLogicArg) -> typing.Optional[str]:
3239
return None
3340

3441
hash_ratio = abs(mmh3.hash(bucket_by)) / (2**31 - 1)
35-
bucket = int(hash_ratio * 100)
42+
bucket = hash_ratio * 100
3643

44+
total_weight = 0
45+
fractions = []
3746
for arg in args:
38-
if (
39-
not isinstance(arg, (tuple, list))
40-
or len(arg) != 2
41-
or not isinstance(arg[0], str)
42-
or not isinstance(arg[1], int)
43-
):
44-
logger.error("Fractional variant weights must be (str, int) tuple")
45-
return None
46-
variant_weights: typing.Tuple[typing.Tuple[str, int]] = args # type: ignore[assignment]
47-
48-
range_end = 0
49-
for variant, weight in variant_weights:
50-
range_end += weight
47+
fraction = _parse_fraction(arg)
48+
if fraction:
49+
fractions.append(fraction)
50+
total_weight += fraction.weight
51+
52+
range_end: float = 0
53+
for fraction in fractions:
54+
range_end += fraction.weight * 100 / total_weight
5155
if bucket < range_end:
52-
return variant
56+
return fraction.variant
5357

5458
return None
5559

5660

61+
def _parse_fraction(arg: JsonLogicArg) -> typing.Optional[Fraction]:
62+
if not isinstance(arg, (tuple, list)) or not arg:
63+
logger.error(
64+
"Fractional variant weights must be (str, int) tuple or [str] list"
65+
)
66+
return None
67+
68+
if not isinstance(arg[0], str):
69+
logger.error(
70+
"Fractional variant identifier (first element) isn't of type 'str'"
71+
)
72+
return None
73+
74+
if len(arg) >= 2 and not isinstance(arg[1], int):
75+
logger.error(
76+
"Fractional variant weight value (second element) isn't of type 'int'"
77+
)
78+
return None
79+
80+
fraction = Fraction(variant=arg[0])
81+
if len(arg) >= 2:
82+
fraction.weight = arg[1]
83+
84+
return fraction
85+
86+
5787
def starts_with(data: dict, *args: JsonLogicArg) -> typing.Optional[bool]:
5888
def f(s1: str, s2: str) -> bool:
5989
return s1.startswith(s2)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"flags": {
3+
"basic-flag": {
4+
"state": "ENABLED",
5+
"variants": {
6+
"default": "default",
7+
"true": "true",
8+
"false": "false"
9+
},
10+
"defaultVariant": "default",
11+
"targeting": {
12+
"fractional": [[]]
13+
}
14+
}
15+
}
16+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"flags": {
3+
"basic-flag": {
4+
"state": "ENABLED",
5+
"variants": {
6+
"default": "default",
7+
"true": "true",
8+
"false": "false"
9+
},
10+
"defaultVariant": "default",
11+
"targeting": {
12+
"fractional": [
13+
["a", "one"],
14+
["b", "one"]
15+
]
16+
}
17+
}
18+
}
19+
}

providers/openfeature-provider-flagd/tests/test_errors.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ def test_file_load_errors(file_name: str):
4848
"invalid-semver-args.json",
4949
"invalid-stringcomp-args.json",
5050
"invalid-fractional-args.json",
51+
"invalid-fractional-args-wrong-content.json",
5152
"invalid-fractional-weights.json",
53+
"invalid-fractional-weights-strings.json",
5254
],
5355
)
5456
def test_json_logic_parse_errors(file_name: str):
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,11 @@
11
# Changelog
2+
3+
## 0.1.0 (2024-10-02)
4+
5+
6+
### ✨ New Features
7+
8+
* add initial skeleton for OFREP provider ([#86](https://github.com/open-feature/python-sdk-contrib/issues/86)) ([00a5a18](https://github.com/open-feature/python-sdk-contrib/commit/00a5a18a76ef1435de67f312e384a97823bd185b))
9+
* implement basic functionality of OFREP provider ([#88](https://github.com/open-feature/python-sdk-contrib/issues/88)) ([cb42cc0](https://github.com/open-feature/python-sdk-contrib/commit/cb42cc0001e19793f391351a1ce5bafe1831025f))
10+
11+
## Changelog

providers/openfeature-provider-ofrep/pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ classifiers = [
1818
keywords = []
1919
dependencies = [
2020
"openfeature-sdk>=0.7.0",
21+
"requests"
2122
]
2223
requires-python = ">=3.8"
2324

@@ -30,6 +31,8 @@ Homepage = "https://github.com/open-feature/python-sdk-contrib"
3031
dependencies = [
3132
"coverage[toml]>=6.5",
3233
"pytest",
34+
"requests-mock",
35+
"types-requests",
3336
]
3437

3538
[tool.hatch.envs.default.scripts]

0 commit comments

Comments
 (0)