示例#1
0
    async def test_session_exists_profile_exists_conflict():
        # Create Profile for Tracker
        tracker_profile = Profile.new()
        await tracker_profile.storage().save()

        # Create Profile for Session
        session_profile = Profile.new()
        await session_profile.storage().save()

        # Create Session
        session_id = str(uuid4())
        session = Session(id=session_id)
        session.profile = session_profile
        await session.storage().save()

        tracker_payload = TrackerPayload(session=Entity(id=session.id),
                                         profile=Entity(id=tracker_profile.id),
                                         source=Entity(id="scope"))

        profile, session = await tracker_payload._get_profile_and_session()

        assert isinstance(profile, Profile)
        assert isinstance(session, Session)

        assert profile.id == session_profile.id  # profile id must be form session
        assert session.id == session_id

        # Remove
        await session.storage().delete()
        await tracker_profile.storage().delete()
        await session_profile.storage().delete()
示例#2
0
def test_value_read():
    profile = Profile(id="1")
    session = Session(id="2")
    payload = {"a": 3}
    source = Source(id="3", type="event")
    context = Context()
    event = Event(id="event-id", type="type", source=source, context=context, profile=profile, session=session)
    flow = Flow(id="flow-id", name="flow")
    dot = DotAccessor(profile, session, payload, event, flow)

    assert dot['profile@id'] == "1"
    assert dot['session@id'] == "2"
    assert dot['payload@a'] == 3
    assert dot['flow@id'] == "flow-id"
    assert dot['event@id'] == "event-id"

    try:
        _ = dot['profile@none']
        assert False
    except KeyError:
        assert True

    dot['payload@b'] = 2
    assert dot['payload@b'] == 2

    dot['[email protected]'] = 2
    assert dot['[email protected]'] == 2

    assert dot.profile['other']['a'] == 2
示例#3
0
    async def run(self, payload: dict):

        dot = DotAccessor(self.profile, self.session, payload, self.event,
                          self.flow)
        for destination, value in self.mapping.items():
            if destination in dot:
                if not isinstance(dot[destination], list):
                    dot[destination] = [dot[destination]]

                if value not in dot[destination]:
                    dot[destination].append(value)
            else:
                dot[destination] = value

        if not isinstance(dot.profile['traits']['private'], dict):
            raise ValueError(
                "Error when appending [email protected] to value `{}`. Private must have key:value pair. "
                "E.g. `name`: `{}`".format(dot.profile['traits']['private'],
                                           dot.profile['traits']['private']))

        if not isinstance(dot.profile['traits']['public'], dict):
            raise ValueError(
                "Error when appending [email protected] to value `{}`. Public must have key:value pair. "
                "E.g. `name`: `{}`".format(dot.profile['traits']['public'],
                                           dot.profile['traits']['public']))

        profile = Profile(**dot.profile)
        event = Event(**dot.event)
        session = Session(**dot.session)

        self.profile.replace(profile)
        self.session.replace(session)
        self.event.replace(event)

        return Result(port="payload", value=payload)
示例#4
0
    async def run(self, payload):

        dot = DotAccessor(self.profile, self.session, payload, self.event,
                          self.flow)

        try:

            value = dot[self.field]

            if value is None:
                value = 0

        except KeyError:
            value = 0

        if type(value) != int:
            raise ValueError("Filed `{}` value is not numeric.".format(
                self.field))

        value += self.increment

        dot[self.field] = value

        self.profile.replace(Profile(**dot.profile))

        return Result(port="payload", value=payload)
示例#5
0
 def __init__(self, profile: Profile, session: Session, payload: dict,
              event: Event, flow: Flow):
     self.flow = dotty(flow.dict())
     self.event = dotty(event.dict())
     self.payload = dotty(payload)
     self.session = dotty(session.dict())
     self.profile = dotty(profile.dict())
示例#6
0
    async def test_session_exists_profile_not_exists():
        non_existent_profile_id = str(uuid4())

        # Create Session
        session_id = str(uuid4())
        session = Session(id=session_id)
        await session.storage().save()

        # Profile does not exist
        session.profile = Profile(id=non_existent_profile_id)

        # Session exists and has profile equal to some random profile that do not exists
        tracker_payload = TrackerPayload(session=Entity(id=session_id),
                                         profile=None,
                                         source=Entity(id="scope"))

        profile, session = await tracker_payload._get_profile_and_session()

        assert isinstance(profile, Profile)
        assert isinstance(session, Session)

        assert profile.id != non_existent_profile_id  # profile can not be generated from non existent profile_id
        assert session.id == session_id

        await session.storage().delete()
        await profile.storage().delete()
示例#7
0
    async def test_session_not_exists_profile_exists():
        # Session does not exist
        # Profile exists

        # Create Profile for Session
        profile_id = str(uuid4())
        profile = Profile(id=profile_id)
        await profile.storage().save()

        # Create Session
        session_id = str(uuid4())
        session = Session(id=session_id)
        session.profile = profile

        tracker_payload = TrackerPayload(session=Entity(id=session.id),
                                         profile=Entity(id=profile.id),
                                         source=Entity(id="scope"))

        profile, session = await tracker_payload._get_profile_and_session()

        assert isinstance(profile, Profile)
        assert isinstance(session, Session)

        assert profile.id == profile_id
        assert session.id == session_id

        # Remove
        await session.storage().delete()
        await profile.storage().delete()
示例#8
0
async def test_save_events():
    tracker_payload = TrackerPayload(
        session=Entity(id="12345"),
        profile=Profile.new(),
        source=Entity(id="scope"),
        events=[
            EventPayload(type="click",
                         properties={"btn": [1, 2, 3]},
                         options={"save": True}),
            EventPayload(type="click",
                         properties={"btn": [3, 4, 5]},
                         options={"save": True})
        ])
    events = tracker_payload.get_events(Session.new(), Profile.new())
    result = await events.bulk().save()
    assert result.saved == 2  # profile id must be form session

    for id in result.ids:
        entity = Entity(id=id)
        await entity.storage("event").delete()
示例#9
0
def test_value_exists():
    profile = Profile(id="1")
    session = Session(id="2")
    payload = {"a": 3}
    source = Source(id="3", type="event")
    context = Context()
    event = Event(id="event-id", type="type", source=source, context=context, profile=profile, session=session)
    flow = Flow(id="flow-id", name="flow")
    dot = DotAccessor(profile, session, payload, event, flow)

    assert 'profile@id' in dot
    assert 'profile@missing' not in dot
示例#10
0
    async def run(self, payload: dict):

        dot = DotAccessor(self.profile, self.session, payload, self.event,
                          self.flow)

        for value in self.delete:
            del dot[value]

        profile = Profile(**dot.profile)

        self.profile.replace(profile)

        return Result(port="payload", value=payload)
示例#11
0
    async def test_session_not_exists_profile_not_exists():
        # Create Profile for Session
        profile_id = str(uuid4())
        profile = Profile(id=profile_id)

        # Create Session
        session_id = str(uuid4())
        session = Session(id=session_id)
        session.profile = profile

        tracker_payload = TrackerPayload(session=Entity(id=session.id),
                                         profile=Entity(id=profile.id),
                                         source=Entity(id="scope"))

        profile, session = await tracker_payload._get_profile_and_session()

        assert profile.id != profile_id  # Must generate new profile, this may be forged
        assert session.id == session_id

        # Remove
        await session.storage().delete()
        await profile.storage().delete()
示例#12
0
def test_profile_merge():
    p1 = Profile(
        id="1",
        stats=ProfileStats(views=1, visits=2),
        traits={
            "private": {
                "a": 1,
                "b": 2
            },
            "public": {
                "a": 1,
                "b": 2
            }
        },
        pii=PII(
            name="john",
            surname="doe"
        ),
        segments=['segment-1'],
        consents={"all": "granted"}
    )

    p2 = Profile(
        id="2",
        stats=ProfileStats(views=2, visits=4),
        traits={
            "private": {
                "a": 2,
                "c": 1
            }
        },
        pii=PII(
            name="jonathan",
            surname="doe"
        )
    )

    p3 = Profile(
        id="3",
        traits={
            "private": {
                "a": [3],
                "c": 1
            },
            "public": {
                "a": 1,
                "b": 3
            }
        },
        segments=['segment-2'],
        consents={"all": "not-granted"}
    )

    profiles = [p1, p2]
    p = Profiles.merge(profiles, p3)

    assert p.consents == {'all': 'not-granted'}
    assert p.traits.private == {'b': 2, 'a': [1, 2, 3], 'c': 1}
    assert p.traits.public == {'b': [2, 3], 'a': 1}
    assert set(p.pii.name).intersection({'john', 'jonathan'}) == {'john', 'jonathan'}
    assert p.pii.surname == 'doe'
    assert p.mergedWith is None
    assert p.stats.views == 3
    assert p.stats.visits == 6
示例#13
0
    async def main():
        source = NamedEntity(id="mobile-app", name="mobile-app")

        # Create profile, rule needs it
        p = Profile.new()
        await p.storage().save()
        profile = await p.storage().load()
        assert p.id == profile.id
        assert isinstance(profile, Profile)

        flow_record = FlowRecord(id="1", name="flow-1")
        await flow_record.storage().save()

        rule = Rule(id="string",
                    source=source,
                    name="my-rule",
                    event=Type(type="xxx1"),
                    flow=flow_record)
        await rule.storage().save()

        saved_rule = await rule.storage().load()
        assert saved_rule.id == rule.id
        x = await RulesEngine.load_rules("xxx2")
        pprint(x)

        payload = {
            "id": str(uuid4()),
            "event_server": Context(),
            "source": source.dict(),
            "profile": p.dict(),
            "context": {},
            "session": {
                "id": "0e6121a5-3ea0-45ed-a9ad-552e1765167f",
                "event_server": {
                    "page": {
                        "url": "http://localhost:8002/tracker/",
                        "path": "/tracker/",
                        "hash": "",
                        "title": "My title",
                        "referer": {
                            "host": None,
                            "query": None
                        },
                        "history": {
                            "length": 2
                        }
                    }
                },
            },
            "properties": {
                "a": "tak"
            },
            "type": "xxx1",
            "user": {
                "id": "user-id-2"
            }
        }

        event = Event(**payload)
        events = Events()
        events.append(event)
        events.append(event)
        session = Session(id="session-id")
        profile = Profile(id="profile-id")

        rules_engine = RulesEngine(session, profile, events)

        flow_result, segmentation_result = await rules_engine.execute(source.id
                                                                      )
        # print(stats.to_json())
        print(flow_result, segmentation_result)

        await rule.storage().delete()
示例#14
0
            "target": "763cbc92-5236-4d30-bff2-a10dbbf8c83f",
            "targetHandle": "payload",
            "id": "reactflow__edge-9f95ad82-9d7c-4f61-a439-580ba4c730e3payload-763cbc92-5236-4d30-bff2-a10dbbf8c83fpayload",
            "type": "default"
        }
    ]
}

converter = FlowGraphConverter(flow)
x = converter.convert_to_dag_graph()
print(x)
dag = DagProcessor(x)
exec_dag = dag.make_execution_dag()
# print(exec_dag.data)
print()
print(exec_dag.serialize())
print()
# exit()
event = Event(
    id="event-id",
    source=Entity(id="1"),
    session=Entity(id="2"),
    context=Context(),
    type="xxx"
)
session = Session(id="session-id")
profile = Profile(id="profile-id")
init = exec_dag.init(event, session, profile)
asyncio.run(exec_dag.run({}, "flow-1", "event-1"))