openfeature-provider-flagd 0.2.2__tar.gz → 0.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/CHANGELOG.md +42 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/PKG-INFO +1 -1
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/pyproject.toml +2 -2
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/config.py +1 -1
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/provider.py +10 -10
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/resolvers/grpc.py +39 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/resolvers/in_process.py +29 -3
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/resolvers/process/connector/file_watcher.py +15 -4
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/resolvers/process/connector/grpc_watcher.py +38 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/resolvers/process/flags.py +39 -1
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2.py +3 -3
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2_grpc.py +1 -1
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2.py +3 -3
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2_grpc.py +1 -1
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/schema/v1/schema_pb2.py +3 -3
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/schema/v1/schema_pb2_grpc.py +1 -1
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/sync/v1/sync_service_pb2.py +3 -3
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/sync/v1/sync_service_pb2_grpc.py +1 -1
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/rpc/conftest.py +1 -1
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/step/event_steps.py +1 -1
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/step/flag_step.py +13 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/step/provider_steps.py +17 -6
- openfeature_provider_flagd-0.2.4/tests/flags/basic-flag-combined-metadata.json +29 -0
- openfeature_provider_flagd-0.2.4/tests/flags/basic-flag-metadata.json +19 -0
- openfeature_provider_flagd-0.2.4/tests/flags/basic-flag-set-metadata.json +19 -0
- openfeature_provider_flagd-0.2.4/tests/flags/invalid-flag-metadata-list.json +14 -0
- openfeature_provider_flagd-0.2.4/tests/flags/invalid-flag-metadata.json +24 -0
- openfeature_provider_flagd-0.2.4/tests/flags/invalid-flag-set-metadata-list.json +14 -0
- openfeature_provider_flagd-0.2.4/tests/flags/invalid-flag-set-metadata.json +21 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/test_errors.py +1 -1
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/test_file_store.py +33 -0
- openfeature_provider_flagd-0.2.4/tests/test_metadata.py +148 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/.gitignore +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/LICENSE +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/README.md +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/pytest.ini +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/__init__.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/flag_type.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/resolvers/__init__.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/resolvers/process/connector/__init__.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/resolvers/process/custom_ops.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/resolvers/process/targeting.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/resolvers/protocol.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/contrib/provider/flagd/sync_metadata_hook.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2.pyi +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation_pb2_grpc.pyi +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2.pyi +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/flagd/sync/v1/sync_pb2_grpc.pyi +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/schema/v1/schema_pb2.pyi +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/schema/v1/schema_pb2_grpc.pyi +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/sync/v1/sync_service_pb2.pyi +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/src/openfeature/schemas/protobuf/sync/v1/sync_service_pb2_grpc.pyi +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/__init__.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/conftest.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/__init__.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/conftest.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/file/__init__.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/file/conftest.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/file/test_flaqd.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/flagd_container.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/inprocess/__init__.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/inprocess/conftest.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/inprocess/test_flaqd.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/parsers.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/paths.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/rpc/__init__.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/rpc/test_flaqd.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/step/_utils.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/step/config_steps.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/step/context_steps.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/testfilter.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/basic-flag-broken-default.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/basic-flag-broken-state.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/basic-flag-broken-targeting.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/basic-flag-broken-variants.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/basic-flag-disabled.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/basic-flag-invalid.not-json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/basic-flag-no-state.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/basic-flag-wrong-structure.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/basic-flag-wrong-variant.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/basic-flag.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/basic-flag.yaml +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/invalid-fractional-args-wrong-content.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/invalid-fractional-args.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/invalid-fractional-weights-strings.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/invalid-fractional-weights.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/invalid-semver-args.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/invalid-semver-op.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/flags/invalid-stringcomp-args.json +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/test_config.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/test_flagd.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/test_in_process.py +0 -0
- {openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/test_targeting.py +0 -0
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.4](https://github.com/open-feature/python-sdk-contrib/compare/openfeature-provider-flagd/v0.2.3...openfeature-provider-flagd/v0.2.4) (2025-06-10)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### 🐛 Bug Fixes
|
|
7
|
+
|
|
8
|
+
* add retry policy to grpc calls. ([#261](https://github.com/open-feature/python-sdk-contrib/issues/261)) ([07ee909](https://github.com/open-feature/python-sdk-contrib/commit/07ee90925126817b6e17387182656a2a0f5603e3))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### 🧹 Chore
|
|
12
|
+
|
|
13
|
+
* **deps:** update dependency grpcio-health-checking to v1.72.1 ([#258](https://github.com/open-feature/python-sdk-contrib/issues/258)) ([e087353](https://github.com/open-feature/python-sdk-contrib/commit/e0873538bf34ec773fb5dc8af60b422c111492e9))
|
|
14
|
+
* **deps:** update dependency grpcio-health-checking to v1.73.0 ([#259](https://github.com/open-feature/python-sdk-contrib/issues/259)) ([7a080b0](https://github.com/open-feature/python-sdk-contrib/commit/7a080b077dc50d3b2512a967bb845fee5af05460))
|
|
15
|
+
* **deps:** update dependency providers/openfeature-provider-flagd/openfeature/test-harness to v2.7.4 ([#237](https://github.com/open-feature/python-sdk-contrib/issues/237)) ([65f70d2](https://github.com/open-feature/python-sdk-contrib/commit/65f70d2dde6e5bdbfd110ac4ec4e4f9cb4793c9c))
|
|
16
|
+
* **deps:** update dependency providers/openfeature-provider-flagd/openfeature/test-harness to v2.8.0 ([#239](https://github.com/open-feature/python-sdk-contrib/issues/239)) ([709ed25](https://github.com/open-feature/python-sdk-contrib/commit/709ed25dfa23ae85aebb5b1dfed1f7ba06b60e39))
|
|
17
|
+
* **deps:** update providers/openfeature-provider-flagd/openfeature/spec digest to 18cde17 ([#233](https://github.com/open-feature/python-sdk-contrib/issues/233)) ([bf9ef82](https://github.com/open-feature/python-sdk-contrib/commit/bf9ef82b73c8b14784c9a3bc1e27681d8445005d))
|
|
18
|
+
* **deps:** update providers/openfeature-provider-flagd/openfeature/spec digest to 36944c6 ([#240](https://github.com/open-feature/python-sdk-contrib/issues/240)) ([030c6ed](https://github.com/open-feature/python-sdk-contrib/commit/030c6edfd9439e3e8c61492936c450ca9a5a062e))
|
|
19
|
+
* **deps:** update providers/openfeature-provider-flagd/openfeature/spec digest to bb2dc2c ([#256](https://github.com/open-feature/python-sdk-contrib/issues/256)) ([34979b6](https://github.com/open-feature/python-sdk-contrib/commit/34979b61793a3e60e36da9e010ff606ede392b63))
|
|
20
|
+
* **deps:** update providers/openfeature-provider-flagd/openfeature/spec digest to cbfa0a9 ([#260](https://github.com/open-feature/python-sdk-contrib/issues/260)) ([d0ec36f](https://github.com/open-feature/python-sdk-contrib/commit/d0ec36feb113f5ad11c49c49821527e70be2afd0))
|
|
21
|
+
* **deps:** update providers/openfeature-provider-flagd/openfeature/spec digest to d27e000 ([#242](https://github.com/open-feature/python-sdk-contrib/issues/242)) ([fd97b35](https://github.com/open-feature/python-sdk-contrib/commit/fd97b35ca91ffdcf7a7a2d6962ca0e1b87b66dd3))
|
|
22
|
+
* **deps:** update providers/openfeature-provider-flagd/openfeature/spec digest to edf0deb ([#248](https://github.com/open-feature/python-sdk-contrib/issues/248)) ([1771423](https://github.com/open-feature/python-sdk-contrib/commit/1771423afa23c4fa6b430c5d22686fa7c36fb1e8))
|
|
23
|
+
* **deps:** update providers/openfeature-provider-flagd/openfeature/spec digest to f014806 ([#253](https://github.com/open-feature/python-sdk-contrib/issues/253)) ([067f19f](https://github.com/open-feature/python-sdk-contrib/commit/067f19f5e56e48c8d2866691397b2082c396936f))
|
|
24
|
+
|
|
25
|
+
## [0.2.3](https://github.com/open-feature/python-sdk-contrib/compare/openfeature-provider-flagd/v0.2.2...openfeature-provider-flagd/v0.2.3) (2025-04-11)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### 🐛 Bug Fixes
|
|
29
|
+
|
|
30
|
+
* **flagd:** fix parameter name inconsistency with SDK version 0.8.1 ([#232](https://github.com/open-feature/python-sdk-contrib/issues/232)) ([55ee420](https://github.com/open-feature/python-sdk-contrib/commit/55ee42087bd9a948a130b08671395138baa33621))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### ✨ New Features
|
|
34
|
+
|
|
35
|
+
* add support for flagd flag metadata ([#215](https://github.com/open-feature/python-sdk-contrib/issues/215)) ([6dc72c0](https://github.com/open-feature/python-sdk-contrib/commit/6dc72c0e16b01cd40e6c103884a2d457e95871d1))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
### 🧹 Chore
|
|
39
|
+
|
|
40
|
+
* **deps:** update dependency providers/openfeature-provider-flagd/openfeature/test-harness to v2.7.3 ([#226](https://github.com/open-feature/python-sdk-contrib/issues/226)) ([9a0971c](https://github.com/open-feature/python-sdk-contrib/commit/9a0971c1fd67998259903a3ea4b42772413fc259))
|
|
41
|
+
* **deps:** update providers/openfeature-provider-flagd/openfeature/spec digest to 130df3e ([#222](https://github.com/open-feature/python-sdk-contrib/issues/222)) ([fa7f429](https://github.com/open-feature/python-sdk-contrib/commit/fa7f4293e060a3d56b204db851c19a668076e7a7))
|
|
42
|
+
* **deps:** update providers/openfeature-provider-flagd/openfeature/spec digest to 27e4461 ([#223](https://github.com/open-feature/python-sdk-contrib/issues/223)) ([9bf2e42](https://github.com/open-feature/python-sdk-contrib/commit/9bf2e421e52922516afa2e5b8648b52a035a038d))
|
|
43
|
+
* **deps:** update providers/openfeature-provider-flagd/openfeature/spec digest to aad6193 ([#194](https://github.com/open-feature/python-sdk-contrib/issues/194)) ([277ad0e](https://github.com/open-feature/python-sdk-contrib/commit/277ad0e744764bbc4eb5c5ebb773287bc2607ac3))
|
|
44
|
+
|
|
3
45
|
## [0.2.2](https://github.com/open-feature/python-sdk-contrib/compare/openfeature-provider-flagd/v0.2.1...openfeature-provider-flagd/v0.2.2) (2025-03-18)
|
|
4
46
|
|
|
5
47
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openfeature-provider-flagd
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: OpenFeature provider for the flagd flag evaluation engine
|
|
5
5
|
Project-URL: Homepage, https://github.com/open-feature/python-sdk-contrib
|
|
6
6
|
Author-email: OpenFeature <openfeature-core@groups.io>
|
|
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
|
|
|
5
5
|
|
|
6
6
|
[project]
|
|
7
7
|
name = "openfeature-provider-flagd"
|
|
8
|
-
version = "0.2.
|
|
8
|
+
version = "0.2.4"
|
|
9
9
|
description = "OpenFeature provider for the flagd flag evaluation engine"
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
authors = [{ name = "OpenFeature", email = "openfeature-core@groups.io" }]
|
|
@@ -40,7 +40,7 @@ dependencies = [
|
|
|
40
40
|
"pytest-bdd",
|
|
41
41
|
"testcontainers",
|
|
42
42
|
"asserts",
|
|
43
|
-
"grpcio-health-checking==1.
|
|
43
|
+
"grpcio-health-checking==1.73.0",
|
|
44
44
|
]
|
|
45
45
|
pre-install-commands = [
|
|
46
46
|
"hatch build",
|
|
@@ -47,7 +47,7 @@ ENV_VAR_RETRY_BACKOFF_MS = "FLAGD_RETRY_BACKOFF_MS"
|
|
|
47
47
|
ENV_VAR_RETRY_BACKOFF_MAX_MS = "FLAGD_RETRY_BACKOFF_MAX_MS"
|
|
48
48
|
ENV_VAR_RETRY_GRACE_PERIOD_SECONDS = "FLAGD_RETRY_GRACE_PERIOD"
|
|
49
49
|
ENV_VAR_SELECTOR = "FLAGD_SOURCE_SELECTOR"
|
|
50
|
-
ENV_VAR_PROVIDER_ID = "
|
|
50
|
+
ENV_VAR_PROVIDER_ID = "FLAGD_PROVIDER_ID"
|
|
51
51
|
ENV_VAR_STREAM_DEADLINE_MS = "FLAGD_STREAM_DEADLINE_MS"
|
|
52
52
|
ENV_VAR_TLS = "FLAGD_TLS"
|
|
53
53
|
ENV_VAR_TLS_CERT = "FLAGD_SERVER_CERT_PATH"
|
|
@@ -158,52 +158,52 @@ class FlagdProvider(AbstractProvider):
|
|
|
158
158
|
|
|
159
159
|
def resolve_boolean_details(
|
|
160
160
|
self,
|
|
161
|
-
|
|
161
|
+
flag_key: str,
|
|
162
162
|
default_value: bool,
|
|
163
163
|
evaluation_context: typing.Optional[EvaluationContext] = None,
|
|
164
164
|
) -> FlagResolutionDetails[bool]:
|
|
165
165
|
return self.resolver.resolve_boolean_details(
|
|
166
|
-
|
|
166
|
+
flag_key, default_value, evaluation_context
|
|
167
167
|
)
|
|
168
168
|
|
|
169
169
|
def resolve_string_details(
|
|
170
170
|
self,
|
|
171
|
-
|
|
171
|
+
flag_key: str,
|
|
172
172
|
default_value: str,
|
|
173
173
|
evaluation_context: typing.Optional[EvaluationContext] = None,
|
|
174
174
|
) -> FlagResolutionDetails[str]:
|
|
175
175
|
return self.resolver.resolve_string_details(
|
|
176
|
-
|
|
176
|
+
flag_key, default_value, evaluation_context
|
|
177
177
|
)
|
|
178
178
|
|
|
179
179
|
def resolve_float_details(
|
|
180
180
|
self,
|
|
181
|
-
|
|
181
|
+
flag_key: str,
|
|
182
182
|
default_value: float,
|
|
183
183
|
evaluation_context: typing.Optional[EvaluationContext] = None,
|
|
184
184
|
) -> FlagResolutionDetails[float]:
|
|
185
185
|
return self.resolver.resolve_float_details(
|
|
186
|
-
|
|
186
|
+
flag_key, default_value, evaluation_context
|
|
187
187
|
)
|
|
188
188
|
|
|
189
189
|
def resolve_integer_details(
|
|
190
190
|
self,
|
|
191
|
-
|
|
191
|
+
flag_key: str,
|
|
192
192
|
default_value: int,
|
|
193
193
|
evaluation_context: typing.Optional[EvaluationContext] = None,
|
|
194
194
|
) -> FlagResolutionDetails[int]:
|
|
195
195
|
return self.resolver.resolve_integer_details(
|
|
196
|
-
|
|
196
|
+
flag_key, default_value, evaluation_context
|
|
197
197
|
)
|
|
198
198
|
|
|
199
199
|
def resolve_object_details(
|
|
200
200
|
self,
|
|
201
|
-
|
|
201
|
+
flag_key: str,
|
|
202
202
|
default_value: typing.Union[dict, list],
|
|
203
203
|
evaluation_context: typing.Optional[EvaluationContext] = None,
|
|
204
204
|
) -> FlagResolutionDetails[typing.Union[dict, list]]:
|
|
205
205
|
return self.resolver.resolve_object_details(
|
|
206
|
-
|
|
206
|
+
flag_key, default_value, evaluation_context
|
|
207
207
|
)
|
|
208
208
|
|
|
209
209
|
def emit_provider_ready_with_context(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import logging
|
|
2
3
|
import threading
|
|
3
4
|
import time
|
|
@@ -80,6 +81,44 @@ class GrpcResolver:
|
|
|
80
81
|
("grpc.initial_reconnect_backoff_ms", config.retry_backoff_ms),
|
|
81
82
|
("grpc.max_reconnect_backoff_ms", config.retry_backoff_max_ms),
|
|
82
83
|
("grpc.min_reconnect_backoff_ms", config.deadline_ms),
|
|
84
|
+
(
|
|
85
|
+
"grpc.service_config",
|
|
86
|
+
json.dumps(
|
|
87
|
+
{
|
|
88
|
+
"methodConfig": [
|
|
89
|
+
{
|
|
90
|
+
"name": [
|
|
91
|
+
{"service": "flagd.sync.v1.FlagSyncService"},
|
|
92
|
+
{"service": "flagd.evaluation.v1.Service"},
|
|
93
|
+
],
|
|
94
|
+
"retryPolicy": {
|
|
95
|
+
"maxAttempts": 3,
|
|
96
|
+
"initialBackoff": "1s",
|
|
97
|
+
"maxBackoff": "5s",
|
|
98
|
+
"backoffMultiplier": 2.0,
|
|
99
|
+
"retryableStatusCodes": [
|
|
100
|
+
"CANCELLED",
|
|
101
|
+
"UNKNOWN",
|
|
102
|
+
"INVALID_ARGUMENT",
|
|
103
|
+
"NOT_FOUND",
|
|
104
|
+
"ALREADY_EXISTS",
|
|
105
|
+
"PERMISSION_DENIED",
|
|
106
|
+
"RESOURCE_EXHAUSTED",
|
|
107
|
+
"FAILED_PRECONDITION",
|
|
108
|
+
"ABORTED",
|
|
109
|
+
"OUT_OF_RANGE",
|
|
110
|
+
"UNIMPLEMENTED",
|
|
111
|
+
"INTERNAL",
|
|
112
|
+
"UNAVAILABLE",
|
|
113
|
+
"DATA_LOSS",
|
|
114
|
+
"UNAUTHENTICATED",
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
),
|
|
121
|
+
),
|
|
83
122
|
]
|
|
84
123
|
if config.tls:
|
|
85
124
|
channel_args = {
|
|
@@ -17,6 +17,23 @@ from .process.targeting import targeting
|
|
|
17
17
|
T = typing.TypeVar("T")
|
|
18
18
|
|
|
19
19
|
|
|
20
|
+
def _merge_metadata(
|
|
21
|
+
flag_metadata: typing.Optional[
|
|
22
|
+
typing.Mapping[str, typing.Union[float, int, str, bool]]
|
|
23
|
+
],
|
|
24
|
+
flag_set_metadata: typing.Optional[
|
|
25
|
+
typing.Mapping[str, typing.Union[float, int, str, bool]]
|
|
26
|
+
],
|
|
27
|
+
) -> typing.Mapping[str, typing.Union[float, int, str, bool]]:
|
|
28
|
+
metadata = {} if flag_set_metadata is None else dict(flag_set_metadata)
|
|
29
|
+
|
|
30
|
+
if flag_metadata is not None:
|
|
31
|
+
for key, value in flag_metadata.items():
|
|
32
|
+
metadata[key] = value
|
|
33
|
+
|
|
34
|
+
return metadata
|
|
35
|
+
|
|
36
|
+
|
|
20
37
|
class InProcessResolver:
|
|
21
38
|
def __init__(
|
|
22
39
|
self,
|
|
@@ -103,18 +120,26 @@ class InProcessResolver:
|
|
|
103
120
|
if not flag:
|
|
104
121
|
raise FlagNotFoundError(f"Flag with key {key} not present in flag store.")
|
|
105
122
|
|
|
123
|
+
metadata = _merge_metadata(flag.metadata, self.flag_store.flag_set_metadata)
|
|
124
|
+
|
|
106
125
|
if flag.state == "DISABLED":
|
|
107
|
-
return FlagResolutionDetails(
|
|
126
|
+
return FlagResolutionDetails(
|
|
127
|
+
default_value, flag_metadata=metadata, reason=Reason.DISABLED
|
|
128
|
+
)
|
|
108
129
|
|
|
109
130
|
if not flag.targeting:
|
|
110
131
|
variant, value = flag.default
|
|
111
|
-
return FlagResolutionDetails(
|
|
132
|
+
return FlagResolutionDetails(
|
|
133
|
+
value, variant=variant, flag_metadata=metadata, reason=Reason.STATIC
|
|
134
|
+
)
|
|
112
135
|
|
|
113
136
|
variant = targeting(flag.key, flag.targeting, evaluation_context)
|
|
114
137
|
|
|
115
138
|
if variant is None:
|
|
116
139
|
variant, value = flag.default
|
|
117
|
-
return FlagResolutionDetails(
|
|
140
|
+
return FlagResolutionDetails(
|
|
141
|
+
value, variant=variant, flag_metadata=metadata, reason=Reason.DEFAULT
|
|
142
|
+
)
|
|
118
143
|
if not isinstance(variant, (str, bool)):
|
|
119
144
|
raise ParseError(
|
|
120
145
|
"Parsed JSONLogic targeting did not return a string or bool"
|
|
@@ -128,4 +153,5 @@ class InProcessResolver:
|
|
|
128
153
|
value,
|
|
129
154
|
variant=variant,
|
|
130
155
|
reason=Reason.TARGETING_MATCH,
|
|
156
|
+
flag_metadata=metadata,
|
|
131
157
|
)
|
|
@@ -14,7 +14,7 @@ from openfeature.contrib.provider.flagd.resolvers.process.connector import (
|
|
|
14
14
|
from openfeature.contrib.provider.flagd.resolvers.process.flags import FlagStore
|
|
15
15
|
from openfeature.evaluation_context import EvaluationContext
|
|
16
16
|
from openfeature.event import ProviderEventDetails
|
|
17
|
-
from openfeature.exception import ParseError, ProviderNotReadyError
|
|
17
|
+
from openfeature.exception import ErrorCode, ParseError, ProviderNotReadyError
|
|
18
18
|
|
|
19
19
|
logger = logging.getLogger("openfeature.contrib")
|
|
20
20
|
|
|
@@ -76,8 +76,15 @@ class FileWatcher(FlagStateConnector):
|
|
|
76
76
|
self.handle_error("Could not parse JSON flag data from file")
|
|
77
77
|
except yaml.error.YAMLError:
|
|
78
78
|
self.handle_error("Could not parse YAML flag data from file")
|
|
79
|
-
except ParseError:
|
|
80
|
-
self.handle_error(
|
|
79
|
+
except ParseError as e:
|
|
80
|
+
self.handle_error(
|
|
81
|
+
"Could not parse flag data using flagd syntax: "
|
|
82
|
+
+ (
|
|
83
|
+
"no error message provided"
|
|
84
|
+
if e is None or e.error_message is None
|
|
85
|
+
else e.error_message
|
|
86
|
+
)
|
|
87
|
+
)
|
|
81
88
|
except Exception:
|
|
82
89
|
self.handle_error("Could not read flags from file")
|
|
83
90
|
|
|
@@ -104,4 +111,8 @@ class FileWatcher(FlagStateConnector):
|
|
|
104
111
|
def handle_error(self, error_message: str) -> None:
|
|
105
112
|
logger.exception(error_message)
|
|
106
113
|
self.should_emit_ready_on_success = True
|
|
107
|
-
self.emit_provider_error(
|
|
114
|
+
self.emit_provider_error(
|
|
115
|
+
ProviderEventDetails(
|
|
116
|
+
message=error_message, error_code=ErrorCode.PARSE_ERROR
|
|
117
|
+
)
|
|
118
|
+
)
|
|
@@ -62,6 +62,44 @@ class GrpcWatcher(FlagStateConnector):
|
|
|
62
62
|
("grpc.initial_reconnect_backoff_ms", config.retry_backoff_ms),
|
|
63
63
|
("grpc.max_reconnect_backoff_ms", config.retry_backoff_max_ms),
|
|
64
64
|
("grpc.min_reconnect_backoff_ms", config.stream_deadline_ms),
|
|
65
|
+
(
|
|
66
|
+
"grpc.service_config",
|
|
67
|
+
json.dumps(
|
|
68
|
+
{
|
|
69
|
+
"methodConfig": [
|
|
70
|
+
{
|
|
71
|
+
"name": [
|
|
72
|
+
{"service": "flagd.sync.v1.FlagSyncService"},
|
|
73
|
+
{"service": "flagd.evaluation.v1.Service"},
|
|
74
|
+
],
|
|
75
|
+
"retryPolicy": {
|
|
76
|
+
"maxAttempts": 3,
|
|
77
|
+
"initialBackoff": "1s",
|
|
78
|
+
"maxBackoff": "5s",
|
|
79
|
+
"backoffMultiplier": 2.0,
|
|
80
|
+
"retryableStatusCodes": [
|
|
81
|
+
"CANCELLED",
|
|
82
|
+
"UNKNOWN",
|
|
83
|
+
"INVALID_ARGUMENT",
|
|
84
|
+
"NOT_FOUND",
|
|
85
|
+
"ALREADY_EXISTS",
|
|
86
|
+
"PERMISSION_DENIED",
|
|
87
|
+
"RESOURCE_EXHAUSTED",
|
|
88
|
+
"FAILED_PRECONDITION",
|
|
89
|
+
"ABORTED",
|
|
90
|
+
"OUT_OF_RANGE",
|
|
91
|
+
"UNIMPLEMENTED",
|
|
92
|
+
"INTERNAL",
|
|
93
|
+
"UNAVAILABLE",
|
|
94
|
+
"DATA_LOSS",
|
|
95
|
+
"UNAUTHENTICATED",
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
),
|
|
102
|
+
),
|
|
65
103
|
]
|
|
66
104
|
if config.default_authority is not None:
|
|
67
105
|
options.append(("grpc.default_authority", config.default_authority))
|
|
@@ -7,6 +7,21 @@ from openfeature.event import ProviderEventDetails
|
|
|
7
7
|
from openfeature.exception import ParseError
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
def _validate_metadata(key: str, value: typing.Union[float, int, str, bool]) -> None:
|
|
11
|
+
if key is None:
|
|
12
|
+
raise ParseError("Metadata key must be set")
|
|
13
|
+
elif not isinstance(key, str):
|
|
14
|
+
raise ParseError(f"Metadata key {key} must be of type str, but is {type(key)}")
|
|
15
|
+
elif not key:
|
|
16
|
+
raise ParseError("key must not be empty")
|
|
17
|
+
if value is None:
|
|
18
|
+
raise ParseError(f"Metadata value for key {key} must be set")
|
|
19
|
+
elif not isinstance(value, (float, int, str, bool)):
|
|
20
|
+
raise ParseError(
|
|
21
|
+
f"Metadata value {value} for key {key} must be of type float, int, str or bool, but is {type(value)}"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
10
25
|
class FlagStore:
|
|
11
26
|
def __init__(
|
|
12
27
|
self,
|
|
@@ -16,12 +31,16 @@ class FlagStore:
|
|
|
16
31
|
):
|
|
17
32
|
self.emit_provider_configuration_changed = emit_provider_configuration_changed
|
|
18
33
|
self.flags: typing.Mapping[str, Flag] = {}
|
|
34
|
+
self.flag_set_metadata: typing.Mapping[
|
|
35
|
+
str, typing.Union[float, int, str, bool]
|
|
36
|
+
] = {}
|
|
19
37
|
|
|
20
38
|
def get_flag(self, key: str) -> typing.Optional["Flag"]:
|
|
21
39
|
return self.flags.get(key)
|
|
22
40
|
|
|
23
41
|
def update(self, flags_data: dict) -> None:
|
|
24
42
|
flags = flags_data.get("flags", {})
|
|
43
|
+
metadata = flags_data.get("metadata", {})
|
|
25
44
|
evaluators: typing.Optional[dict] = flags_data.get("$evaluators")
|
|
26
45
|
if evaluators:
|
|
27
46
|
transposed = json.dumps(flags)
|
|
@@ -33,10 +52,18 @@ class FlagStore:
|
|
|
33
52
|
|
|
34
53
|
if not isinstance(flags, dict):
|
|
35
54
|
raise ParseError("`flags` key of configuration must be a dictionary")
|
|
55
|
+
if not isinstance(metadata, dict):
|
|
56
|
+
raise ParseError("`metadata` key of configuration must be a dictionary")
|
|
57
|
+
for key, value in metadata.items():
|
|
58
|
+
_validate_metadata(key, value)
|
|
59
|
+
|
|
36
60
|
self.flags = {key: Flag.from_dict(key, data) for key, data in flags.items()}
|
|
61
|
+
self.flag_set_metadata = metadata
|
|
37
62
|
|
|
38
63
|
self.emit_provider_configuration_changed(
|
|
39
|
-
ProviderEventDetails(
|
|
64
|
+
ProviderEventDetails(
|
|
65
|
+
flags_changed=list(self.flags.keys()), metadata=metadata
|
|
66
|
+
)
|
|
40
67
|
)
|
|
41
68
|
|
|
42
69
|
|
|
@@ -47,6 +74,9 @@ class Flag:
|
|
|
47
74
|
variants: typing.Mapping[str, typing.Any]
|
|
48
75
|
default_variant: typing.Union[bool, str]
|
|
49
76
|
targeting: typing.Optional[dict] = None
|
|
77
|
+
metadata: typing.Optional[
|
|
78
|
+
typing.Mapping[str, typing.Union[float, int, str, bool]]
|
|
79
|
+
] = None
|
|
50
80
|
|
|
51
81
|
def __post_init__(self) -> None:
|
|
52
82
|
if not self.state or not isinstance(self.state, str):
|
|
@@ -66,6 +96,12 @@ class Flag:
|
|
|
66
96
|
if self.default_variant not in self.variants:
|
|
67
97
|
raise ParseError("Default variant does not match set of variants")
|
|
68
98
|
|
|
99
|
+
if self.metadata:
|
|
100
|
+
if not isinstance(self.metadata, dict):
|
|
101
|
+
raise ParseError("Flag metadata is not a valid json object")
|
|
102
|
+
for key, value in self.metadata.items():
|
|
103
|
+
_validate_metadata(key, value)
|
|
104
|
+
|
|
69
105
|
@classmethod
|
|
70
106
|
def from_dict(cls, key: str, data: dict) -> "Flag":
|
|
71
107
|
if "defaultVariant" in data:
|
|
@@ -77,6 +113,8 @@ class Flag:
|
|
|
77
113
|
try:
|
|
78
114
|
flag = cls(key=key, **data)
|
|
79
115
|
return flag
|
|
116
|
+
except ParseError as parseError:
|
|
117
|
+
raise parseError
|
|
80
118
|
except Exception as err:
|
|
81
119
|
raise ParseError from err
|
|
82
120
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
3
|
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
4
|
# source: openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation.proto
|
|
5
|
-
# Protobuf Python Version:
|
|
5
|
+
# Protobuf Python Version: 6.31.0
|
|
6
6
|
"""Generated protocol buffer code."""
|
|
7
7
|
from google.protobuf import descriptor as _descriptor
|
|
8
8
|
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
@@ -11,8 +11,8 @@ from google.protobuf import symbol_database as _symbol_database
|
|
|
11
11
|
from google.protobuf.internal import builder as _builder
|
|
12
12
|
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
13
|
_runtime_version.Domain.PUBLIC,
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
6,
|
|
15
|
+
31,
|
|
16
16
|
0,
|
|
17
17
|
'',
|
|
18
18
|
'openfeature/schemas/protobuf/flagd/evaluation/v1/evaluation.proto'
|
|
@@ -5,7 +5,7 @@ import warnings
|
|
|
5
5
|
|
|
6
6
|
from openfeature.schemas.protobuf.flagd.evaluation.v1 import evaluation_pb2 as openfeature_dot_schemas_dot_protobuf_dot_flagd_dot_evaluation_dot_v1_dot_evaluation__pb2
|
|
7
7
|
|
|
8
|
-
GRPC_GENERATED_VERSION = '1.
|
|
8
|
+
GRPC_GENERATED_VERSION = '1.73.0'
|
|
9
9
|
GRPC_VERSION = grpc.__version__
|
|
10
10
|
_version_not_supported = False
|
|
11
11
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
3
|
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
4
|
# source: openfeature/schemas/protobuf/flagd/sync/v1/sync.proto
|
|
5
|
-
# Protobuf Python Version:
|
|
5
|
+
# Protobuf Python Version: 6.31.0
|
|
6
6
|
"""Generated protocol buffer code."""
|
|
7
7
|
from google.protobuf import descriptor as _descriptor
|
|
8
8
|
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
@@ -11,8 +11,8 @@ from google.protobuf import symbol_database as _symbol_database
|
|
|
11
11
|
from google.protobuf.internal import builder as _builder
|
|
12
12
|
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
13
|
_runtime_version.Domain.PUBLIC,
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
6,
|
|
15
|
+
31,
|
|
16
16
|
0,
|
|
17
17
|
'',
|
|
18
18
|
'openfeature/schemas/protobuf/flagd/sync/v1/sync.proto'
|
|
@@ -5,7 +5,7 @@ import warnings
|
|
|
5
5
|
|
|
6
6
|
from openfeature.schemas.protobuf.flagd.sync.v1 import sync_pb2 as openfeature_dot_schemas_dot_protobuf_dot_flagd_dot_sync_dot_v1_dot_sync__pb2
|
|
7
7
|
|
|
8
|
-
GRPC_GENERATED_VERSION = '1.
|
|
8
|
+
GRPC_GENERATED_VERSION = '1.73.0'
|
|
9
9
|
GRPC_VERSION = grpc.__version__
|
|
10
10
|
_version_not_supported = False
|
|
11
11
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
3
|
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
4
|
# source: openfeature/schemas/protobuf/schema/v1/schema.proto
|
|
5
|
-
# Protobuf Python Version:
|
|
5
|
+
# Protobuf Python Version: 6.31.0
|
|
6
6
|
"""Generated protocol buffer code."""
|
|
7
7
|
from google.protobuf import descriptor as _descriptor
|
|
8
8
|
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
@@ -11,8 +11,8 @@ from google.protobuf import symbol_database as _symbol_database
|
|
|
11
11
|
from google.protobuf.internal import builder as _builder
|
|
12
12
|
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
13
|
_runtime_version.Domain.PUBLIC,
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
6,
|
|
15
|
+
31,
|
|
16
16
|
0,
|
|
17
17
|
'',
|
|
18
18
|
'openfeature/schemas/protobuf/schema/v1/schema.proto'
|
|
@@ -5,7 +5,7 @@ import warnings
|
|
|
5
5
|
|
|
6
6
|
from openfeature.schemas.protobuf.schema.v1 import schema_pb2 as openfeature_dot_schemas_dot_protobuf_dot_schema_dot_v1_dot_schema__pb2
|
|
7
7
|
|
|
8
|
-
GRPC_GENERATED_VERSION = '1.
|
|
8
|
+
GRPC_GENERATED_VERSION = '1.73.0'
|
|
9
9
|
GRPC_VERSION = grpc.__version__
|
|
10
10
|
_version_not_supported = False
|
|
11
11
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
3
|
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
4
|
# source: openfeature/schemas/protobuf/sync/v1/sync_service.proto
|
|
5
|
-
# Protobuf Python Version:
|
|
5
|
+
# Protobuf Python Version: 6.31.0
|
|
6
6
|
"""Generated protocol buffer code."""
|
|
7
7
|
from google.protobuf import descriptor as _descriptor
|
|
8
8
|
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
@@ -11,8 +11,8 @@ from google.protobuf import symbol_database as _symbol_database
|
|
|
11
11
|
from google.protobuf.internal import builder as _builder
|
|
12
12
|
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
13
|
_runtime_version.Domain.PUBLIC,
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
6,
|
|
15
|
+
31,
|
|
16
16
|
0,
|
|
17
17
|
'',
|
|
18
18
|
'openfeature/schemas/protobuf/sync/v1/sync_service.proto'
|
|
@@ -5,7 +5,7 @@ import warnings
|
|
|
5
5
|
|
|
6
6
|
from openfeature.schemas.protobuf.sync.v1 import sync_service_pb2 as openfeature_dot_schemas_dot_protobuf_dot_sync_dot_v1_dot_sync__service__pb2
|
|
7
7
|
|
|
8
|
-
GRPC_GENERATED_VERSION = '1.
|
|
8
|
+
GRPC_GENERATED_VERSION = '1.73.0'
|
|
9
9
|
GRPC_VERSION = grpc.__version__
|
|
10
10
|
_version_not_supported = False
|
|
11
11
|
|
{openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/rpc/conftest.py
RENAMED
|
@@ -4,7 +4,7 @@ from openfeature.contrib.provider.flagd.config import ResolverType
|
|
|
4
4
|
from tests.e2e.testfilter import TestFilter
|
|
5
5
|
|
|
6
6
|
resolver = ResolverType.RPC
|
|
7
|
-
feature_list = ["~targetURI", "~unixsocket", "~sync"]
|
|
7
|
+
feature_list = ["~targetURI", "~unixsocket", "~sync", "~metadata"]
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def pytest_collection_modifyitems(config, items):
|
{openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/step/event_steps.py
RENAMED
|
@@ -44,7 +44,7 @@ def add_event_handler(client: OpenFeatureClient, event_type: str, event_handles:
|
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
def assert_handlers(handles, event_type: str, max_wait: int = 2):
|
|
47
|
-
poll_interval =
|
|
47
|
+
poll_interval = 0.2
|
|
48
48
|
while max_wait > 0:
|
|
49
49
|
found = any(h["type"] == event_type for h in handles)
|
|
50
50
|
if not found:
|
{openfeature_provider_flagd-0.2.2 → openfeature_provider_flagd-0.2.4}/tests/e2e/step/flag_step.py
RENAMED
|
@@ -94,3 +94,16 @@ def resolve_details_reason(
|
|
|
94
94
|
reason: str,
|
|
95
95
|
):
|
|
96
96
|
assert_equal(details.reason, Reason(reason))
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@then(parsers.cfparse("the resolved metadata should contain"))
|
|
100
|
+
def metadata_contains(details: FlagEvaluationDetails[JsonPrimitive], datatable):
|
|
101
|
+
assert_equal(len(details.flag_metadata), len(datatable) - 1) # skip table header
|
|
102
|
+
for i in range(1, len(datatable)):
|
|
103
|
+
key, metadata_type, expected = datatable[i]
|
|
104
|
+
assert_equal(details.flag_metadata[key], type_cast[metadata_type](expected))
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@then("the resolved metadata is empty")
|
|
108
|
+
def empty_metadata(details: FlagEvaluationDetails[JsonPrimitive]):
|
|
109
|
+
assert_equal(len(details.flag_metadata), 0)
|