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
10 changes: 8 additions & 2 deletions api/environments/dynamodb/wrappers/identity_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
from boto3.dynamodb.conditions import Attr, Key
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from flag_engine.context.mappers import map_environment_identity_to_context
from flag_engine.environments.models import EnvironmentModel
from flag_engine.identities.models import IdentityModel
from flag_engine.segments.evaluator import get_identity_segments
from flag_engine.segments.evaluator import get_context_segments
from rest_framework.exceptions import NotFound

from edge_api.identities.search import EdgeIdentitySearchData
Expand Down Expand Up @@ -189,7 +190,12 @@ def get_segment_ids(
environment = EnvironmentModel.model_validate(
environment_wrapper.get_item(identity.environment_api_key)
)
segments = get_identity_segments(environment, identity)
context = map_environment_identity_to_context(
environment=environment,
identity=identity,
override_traits=None,
)
segments = get_context_segments(context, environment.project.segments)
return [segment.id for segment in segments]

return []
Expand Down
12 changes: 9 additions & 3 deletions api/environments/identities/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

from django.db import models
from django.db.models import Prefetch, Q
from flag_engine.segments.evaluator import evaluate_identity_in_segment
from flag_engine.context.mappers import map_environment_identity_to_context
from flag_engine.segments.evaluator import is_context_in_segment

from environments.identities.managers import IdentityManager
from environments.identities.traits.models import Trait
Expand Down Expand Up @@ -170,10 +171,15 @@ def get_segments(
for segment in all_segments:
engine_segment = map_segment_to_engine(segment)

if evaluate_identity_in_segment(
context = map_environment_identity_to_context(
environment=self.environment,
identity=engine_identity,
segment=engine_segment,
override_traits=engine_traits,
)

if is_context_in_segment(
context=context,
segment=engine_segment,
):
matching_segments.append(segment)

Expand Down
13 changes: 9 additions & 4 deletions api/integrations/webhook/serializers.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import typing

from django.db.models import Q
from flag_engine.segments.evaluator import evaluate_identity_in_segment
from flag_engine.segments.evaluator import is_context_in_segment
from rest_framework import serializers

from features.serializers import FeatureStateSerializerFull
from integrations.common.serializers import (
BaseEnvironmentIntegrationModelSerializer,
)
from segments.models import Segment
from util.mappers.engine import map_identity_to_engine, map_segment_to_engine
from util.mappers.engine import (
map_engine_identity_to_context,
map_identity_to_engine,
map_segment_to_engine,
)

from .models import WebhookConfiguration

Expand All @@ -33,8 +37,9 @@ def get_member(self, obj: Segment) -> bool:
with_overrides=False,
)
engine_segment = map_segment_to_engine(obj)
return evaluate_identity_in_segment(
identity=engine_identity,
context = map_engine_identity_to_context(engine_identity)
return is_context_in_segment(
context=context,
segment=engine_segment,
)

Expand Down
7 changes: 3 additions & 4 deletions api/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ environs = "^14.1.1"
django-lifecycle = "~1.2.4"
drf-writable-nested = "~0.6.2"
django-filter = "~2.4.0"
flagsmith-flag-engine = "^5.3.0"
flagsmith-flag-engine = "^5.4.3"
boto3 = "~1.35.95"
slack-sdk = "~3.9.0"
asgiref = "~3.8.1"
Expand Down
21 changes: 21 additions & 0 deletions api/util/mappers/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import TYPE_CHECKING, Dict, List, Optional
from uuid import UUID

from flag_engine.context.types import EvaluationContext
from flag_engine.environments.integrations.models import IntegrationModel
from flag_engine.environments.models import (
EnvironmentAPIKeyModel,
Expand Down Expand Up @@ -418,6 +419,26 @@ def map_identity_to_engine(
)


def map_engine_identity_to_context(
identity: IdentityModel,
) -> "EvaluationContext":
"""
A special mapper to produce a minimal EvaluationContext
in an environment-less form.
Used when an environment object is not available, like when evaluating segments for webhooks.
"""
return {
"environment": {"key": identity.environment_api_key, "name": ""},
"identity": {
"identifier": identity.identifier,
"key": str(identity.django_id or identity.composite_key),
"traits": {
trait.trait_key: trait.trait_value for trait in identity.identity_traits
},
},
}


def _get_prioritised_feature_states(
feature_states: Iterable["FeatureState"],
) -> List["FeatureState"]:
Expand Down
Loading