diff --git a/.flake8 b/.flake8 index fbfd088..0570cc1 100644 --- a/.flake8 +++ b/.flake8 @@ -2,3 +2,6 @@ max-line-length = 120 max-complexity = 10 exclude = .git,__pycache__,.venv +per-file-ignores = + # Step markers must match the spec step text on a single line. + sdk-spec/steps.py: E501 diff --git a/.github/workflows/sdk-spec.yml b/.github/workflows/sdk-spec.yml index 6952fea..28056e0 100644 --- a/.github/workflows/sdk-spec.yml +++ b/.github/workflows/sdk-spec.yml @@ -11,7 +11,7 @@ permissions: jobs: sdk-spec: # Keep the ref in `uses:` and `spec-ref` in sync. - uses: Flagsmith/sdk-spec/.github/workflows/run-spec.yml@v0.3.0 + uses: Flagsmith/sdk-spec/.github/workflows/run-spec.yml@v0.6.0 with: - spec-ref: v0.3.0 + spec-ref: v0.6.0 language: python diff --git a/sdk-spec/steps.py b/sdk-spec/steps.py index 5cd373d..2410848 100644 --- a/sdk-spec/steps.py +++ b/sdk-spec/steps.py @@ -6,18 +6,20 @@ import typing -from flagsmith import Flagsmith -from flagsmith.models import Flags +from flagsmith import EventProcessorConfig, Flagsmith +from flagsmith.models import Flag, Flags from flagsmith.types import TraitMapping SpecFlag = dict[str, typing.Any] +EventValue = typing.Union[str, int, float, bool] + + +def as_spec_flag(flag: Flag) -> SpecFlag: + return {"feature": flag.feature_name, "enabled": flag.enabled, "value": flag.value} def as_spec_flags(flags: Flags) -> list[SpecFlag]: - return [ - {"feature": flag.feature_name, "enabled": flag.enabled, "value": flag.value} - for flag in flags.all_flags() - ] + return [as_spec_flag(flag) for flag in flags.all_flags()] # Create the SDK client @@ -25,6 +27,18 @@ def create_client(environment_key: str, api_url: str) -> Flagsmith: return Flagsmith(environment_key=environment_key, api_url=api_url) +# Create the SDK client with events enabled +def create_client_with_events( + environment_key: str, api_url: str, events_api_url: str +) -> Flagsmith: + return Flagsmith( + environment_key=environment_key, + api_url=api_url, + enable_events=True, + event_processor_config=EventProcessorConfig(events_api_url=events_api_url), + ) + + # When the application gets the environment flags def get_environment_flags(flagsmith: Flagsmith) -> list[SpecFlag]: return as_spec_flags(flagsmith.get_environment_flags()) @@ -35,3 +49,35 @@ def get_identity_flags( flagsmith: Flagsmith, identifier: str, traits: TraitMapping ) -> list[SpecFlag]: return as_spec_flags(flagsmith.get_identity_flags(identifier, traits=traits)) + + +# When the application gets the experiment flag "{feature}" for identity "{identifier}" with traits: +def get_experiment_flag( + flagsmith: Flagsmith, feature: str, identifier: str, traits: TraitMapping +) -> list[SpecFlag]: + flag = flagsmith.get_experiment_flag(feature, identifier, traits) + return [as_spec_flag(flag)] if isinstance(flag, Flag) else [] + + +# When the application tracks event "{event}" for identity "{identifier}" with value {value} and metadata: +def track_event( + flagsmith: Flagsmith, + event: str, + identifier: str, + value: EventValue, + metadata: dict[str, typing.Any], +) -> None: + flagsmith.track_event(event, identifier=identifier, value=value, metadata=metadata) + + +# When the application tracks an exposure of feature "{feature}" for identity "{identifier}" with value {value} and metadata: +def track_exposure_event( + flagsmith: Flagsmith, + feature: str, + identifier: str, + value: EventValue, + metadata: dict[str, typing.Any], +) -> None: + flagsmith.track_exposure_event( + feature, identifier=identifier, value=value, metadata=metadata + )