port-ocean 0.19.3__py3-none-any.whl → 0.20.1__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- port_ocean/clients/port/mixins/integrations.py +18 -7
- port_ocean/context/ocean.py +2 -7
- port_ocean/core/handlers/webhook/abstract_webhook_processor.py +18 -2
- port_ocean/core/handlers/webhook/processor_manager.py +107 -65
- port_ocean/core/handlers/webhook/webhook_event.py +71 -8
- port_ocean/core/integrations/mixins/live_events.py +88 -0
- port_ocean/ocean.py +4 -2
- port_ocean/tests/core/handlers/mixins/test_live_events.py +404 -0
- port_ocean/tests/core/handlers/webhook/test_abstract_webhook_processor.py +88 -97
- port_ocean/tests/core/handlers/webhook/test_processor_manager.py +1161 -288
- port_ocean/tests/core/handlers/webhook/test_webhook_event.py +97 -56
- {port_ocean-0.19.3.dist-info → port_ocean-0.20.1.dist-info}/METADATA +1 -1
- {port_ocean-0.19.3.dist-info → port_ocean-0.20.1.dist-info}/RECORD +16 -14
- {port_ocean-0.19.3.dist-info → port_ocean-0.20.1.dist-info}/LICENSE.md +0 -0
- {port_ocean-0.19.3.dist-info → port_ocean-0.20.1.dist-info}/WHEEL +0 -0
- {port_ocean-0.19.3.dist-info → port_ocean-0.20.1.dist-info}/entry_points.txt +0 -0
@@ -4,62 +4,103 @@ from port_ocean.core.handlers.webhook.webhook_event import (
|
|
4
4
|
EventHeaders,
|
5
5
|
EventPayload,
|
6
6
|
WebhookEvent,
|
7
|
+
LiveEventTimestamp,
|
7
8
|
)
|
8
9
|
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
11
|
+
@pytest.fixture
|
12
|
+
def sample_payload() -> EventPayload:
|
13
|
+
return {"test": "data", "nested": {"value": 123}}
|
14
|
+
|
15
|
+
|
16
|
+
@pytest.fixture
|
17
|
+
def sample_headers() -> EventHeaders:
|
18
|
+
return {"content-type": "application/json", "x-test-header": "test-value"}
|
19
|
+
|
20
|
+
|
21
|
+
@pytest.fixture
|
22
|
+
def mock_request(sample_payload: EventPayload, sample_headers: EventHeaders) -> Request:
|
23
|
+
scope = {
|
24
|
+
"type": "http",
|
25
|
+
"headers": [(k.encode(), v.encode()) for k, v in sample_headers.items()],
|
26
|
+
}
|
27
|
+
mock_request = Request(scope)
|
28
|
+
mock_request._json = sample_payload
|
29
|
+
return mock_request
|
30
|
+
|
31
|
+
|
32
|
+
@pytest.fixture
|
33
|
+
def webhook_event(
|
34
|
+
sample_payload: EventPayload, sample_headers: EventHeaders
|
35
|
+
) -> WebhookEvent:
|
36
|
+
return WebhookEvent(
|
37
|
+
trace_id="test-trace-id",
|
38
|
+
payload=sample_payload,
|
39
|
+
headers=sample_headers,
|
40
|
+
)
|
41
|
+
|
42
|
+
|
43
|
+
async def test_fromRequest_createdSuccessfully(mock_request: Request) -> None:
|
44
|
+
"""Test creating WebhookEvent from a request."""
|
45
|
+
event = await WebhookEvent.from_request(mock_request)
|
46
|
+
|
47
|
+
assert event.trace_id is not None
|
48
|
+
assert len(event.trace_id) > 0
|
49
|
+
assert event.headers == dict(mock_request.headers)
|
50
|
+
assert event._original_request == mock_request
|
51
|
+
|
52
|
+
|
53
|
+
def test_fromDict_createdSuccessfully(
|
54
|
+
sample_payload: EventPayload, sample_headers: EventHeaders
|
55
|
+
) -> None:
|
56
|
+
"""Test creating WebhookEvent from a dictionary."""
|
57
|
+
data = {
|
58
|
+
"trace_id": "test-trace-id",
|
59
|
+
"payload": sample_payload,
|
60
|
+
"headers": sample_headers,
|
61
|
+
}
|
62
|
+
|
63
|
+
event = WebhookEvent.from_dict(data)
|
64
|
+
|
65
|
+
assert event.trace_id == "test-trace-id"
|
66
|
+
assert event.payload == sample_payload
|
67
|
+
assert event.headers == sample_headers
|
68
|
+
assert event._original_request is None
|
69
|
+
|
70
|
+
|
71
|
+
def test_clone_createsExactCopy(
|
72
|
+
sample_payload: EventPayload, sample_headers: EventHeaders
|
73
|
+
) -> None:
|
74
|
+
"""Test cloning a WebhookEvent creates an exact copy."""
|
75
|
+
original = WebhookEvent(
|
76
|
+
trace_id="test-trace-id",
|
77
|
+
payload=sample_payload,
|
78
|
+
headers=sample_headers,
|
79
|
+
original_request=None,
|
80
|
+
)
|
81
|
+
|
82
|
+
cloned = original.clone()
|
83
|
+
|
84
|
+
assert cloned.trace_id == original.trace_id
|
85
|
+
assert cloned.payload == original.payload
|
86
|
+
assert cloned.headers == original.headers
|
87
|
+
assert cloned._original_request == original._original_request
|
88
|
+
assert cloned is not original # Verify it's a new instance
|
89
|
+
|
90
|
+
|
91
|
+
def test_setTimestamp_setsTimestampCorrectly(
|
92
|
+
sample_payload: EventPayload, sample_headers: EventHeaders
|
93
|
+
) -> None:
|
94
|
+
"""Test that setting a timestamp logs the event and stores the timestamp."""
|
95
|
+
event = WebhookEvent(
|
96
|
+
trace_id="test-trace-id",
|
97
|
+
payload=sample_payload,
|
98
|
+
headers=sample_headers,
|
99
|
+
original_request=None,
|
100
|
+
)
|
101
|
+
|
102
|
+
event.set_timestamp(LiveEventTimestamp.StartedProcessing)
|
103
|
+
assert event._timestamp == LiveEventTimestamp.StartedProcessing
|
104
|
+
|
105
|
+
event.set_timestamp(LiveEventTimestamp.FinishedProcessingSuccessfully)
|
106
|
+
assert event._timestamp == LiveEventTimestamp.FinishedProcessingSuccessfully
|
@@ -53,7 +53,7 @@ port_ocean/clients/port/client.py,sha256=OaNeN3U7Hw0tK4jYE6ESJEPKbTf9nGp2jcJVq00
|
|
53
53
|
port_ocean/clients/port/mixins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
54
|
port_ocean/clients/port/mixins/blueprints.py,sha256=POBl4uDocrgJBw4rvCAzwRcD4jk-uBL6pDAuKMTajdg,4633
|
55
55
|
port_ocean/clients/port/mixins/entities.py,sha256=PJzVZTBW_OheFRGPRCZ6yPbVGEAKsMO9CNDNJUI1l48,10770
|
56
|
-
port_ocean/clients/port/mixins/integrations.py,sha256=
|
56
|
+
port_ocean/clients/port/mixins/integrations.py,sha256=qvUnW-n8PqAVOTO7FZpof-724CUK4SK-UQoigxuHetU,9526
|
57
57
|
port_ocean/clients/port/mixins/migrations.py,sha256=A6896oJF6WbFL2WroyTkMzr12yhVyWqGoq9dtLNSKBY,1457
|
58
58
|
port_ocean/clients/port/mixins/organization.py,sha256=fCo_ZS8UlQXsyIx-odTuWkbnfcYmVnQfIsSyJuPOPjM,1031
|
59
59
|
port_ocean/clients/port/retry_transport.py,sha256=PtIZOAZ6V-ncpVysRUsPOgt8Sf01QLnTKB5YeKBxkJk,1861
|
@@ -67,7 +67,7 @@ port_ocean/consumers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
|
|
67
67
|
port_ocean/consumers/kafka_consumer.py,sha256=N8KocjBi9aR0BOPG8hgKovg-ns_ggpEjrSxqSqF_BSo,4710
|
68
68
|
port_ocean/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
69
69
|
port_ocean/context/event.py,sha256=QK2ben4fJtxdorq_yRroATttP0DRc4wLtlUJ1as5D58,6208
|
70
|
-
port_ocean/context/ocean.py,sha256
|
70
|
+
port_ocean/context/ocean.py,sha256=Yt3G9CbcmFhxFTdxUhjkiZSfm92VKmzs7m-BMSGaU54,6316
|
71
71
|
port_ocean/context/resource.py,sha256=yDj63URzQelj8zJPh4BAzTtPhpKr9Gw9DRn7I_0mJ1s,1692
|
72
72
|
port_ocean/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
73
73
|
port_ocean/core/defaults/__init__.py,sha256=8qCZg8n06WAdMu9s_FiRtDYLGPGHbOuS60vapeUoAks,142
|
@@ -103,14 +103,15 @@ port_ocean/core/handlers/queue/local_queue.py,sha256=EzqsGIX43xbVAcePwTcCg5QDrXA
|
|
103
103
|
port_ocean/core/handlers/resync_state_updater/__init__.py,sha256=kG6y-JQGpPfuTHh912L_bctIDCzAK4DN-d00S7rguWU,81
|
104
104
|
port_ocean/core/handlers/resync_state_updater/updater.py,sha256=Yg9ET6ZV5B9GW7u6zZA6GlB_71kmvxvYX2FWgQNzMvo,3182
|
105
105
|
port_ocean/core/handlers/webhook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
106
|
-
port_ocean/core/handlers/webhook/abstract_webhook_processor.py,sha256=
|
107
|
-
port_ocean/core/handlers/webhook/processor_manager.py,sha256=
|
108
|
-
port_ocean/core/handlers/webhook/webhook_event.py,sha256=
|
106
|
+
port_ocean/core/handlers/webhook/abstract_webhook_processor.py,sha256=YRMr4M1m0XNZbxNGU0bzB3hEkPat1HCom66EU9NRffU,3879
|
107
|
+
port_ocean/core/handlers/webhook/processor_manager.py,sha256=RoPV3cHjAv7jJ_vpC9y2fF2v9eb41h0VM6bNAPuzKdg,11779
|
108
|
+
port_ocean/core/handlers/webhook/webhook_event.py,sha256=Iuw6IX3PPjwHECUeFgrJl6K249mJ-DPAGhP8OMxbc1c,4096
|
109
109
|
port_ocean/core/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
110
110
|
port_ocean/core/integrations/base.py,sha256=eS0WDOfCTim1UOQQrNuP14I6hvT_fr8dof_cr1ls01s,3107
|
111
111
|
port_ocean/core/integrations/mixins/__init__.py,sha256=FA1FEKMM6P-L2_m7Q4L20mFa4_RgZnwSRmTCreKcBVM,220
|
112
112
|
port_ocean/core/integrations/mixins/events.py,sha256=0jKRsBw6lU8Mqs7MaQK4n-t_H6Z4NEkXZ5VWzqTrKEc,2396
|
113
113
|
port_ocean/core/integrations/mixins/handler.py,sha256=mZ7-0UlG3LcrwJttFbMe-R4xcOU2H_g33tZar7PwTv8,3771
|
114
|
+
port_ocean/core/integrations/mixins/live_events.py,sha256=8HklZmlyffYY_LeDe8xbt3Tb08rlLkqVhFF-2NQeJP4,4126
|
114
115
|
port_ocean/core/integrations/mixins/sync.py,sha256=GHiFbnw0XrBfl7aCTH_w67f_N7EZbcUgssc-0fPujNU,4047
|
115
116
|
port_ocean/core/integrations/mixins/sync_raw.py,sha256=7kk2p5lLKq9oivqqintZumuaIHSbcSmoUfWrE346l7g,24821
|
116
117
|
port_ocean/core/integrations/mixins/utils.py,sha256=oN4Okz6xlaefpid1_Pud8HPSw9BwwjRohyNsknq-Myg,2309
|
@@ -136,7 +137,7 @@ port_ocean/log/handlers.py,sha256=ncVjgqrZRh6BhyRrA6DQG86Wsbxph1yWYuEC0cWfe-Q,36
|
|
136
137
|
port_ocean/log/logger_setup.py,sha256=CoEDowe5OwNOL_5clU6Z4faktfh0VWaOTS0VLmyhHjw,2404
|
137
138
|
port_ocean/log/sensetive.py,sha256=lVKiZH6b7TkrZAMmhEJRhcl67HNM94e56x12DwFgCQk,2920
|
138
139
|
port_ocean/middlewares.py,sha256=9wYCdyzRZGK1vjEJ28FY_DkfwDNENmXp504UKPf5NaQ,2727
|
139
|
-
port_ocean/ocean.py,sha256=
|
140
|
+
port_ocean/ocean.py,sha256=qOaTxwQsY_t8rilOAWR2Gl6IWlmbW8QCMHmj8YKWM-Q,6717
|
140
141
|
port_ocean/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
141
142
|
port_ocean/run.py,sha256=COoRSmLG4hbsjIW5DzhV0NYVegI9xHd1POv6sg4U1No,2217
|
142
143
|
port_ocean/sonar-project.properties,sha256=X_wLzDOkEVmpGLRMb2fg9Rb0DxWwUFSvESId8qpvrPI,73
|
@@ -150,13 +151,14 @@ port_ocean/tests/conftest.py,sha256=JXASSS0IY0nnR6bxBflhzxS25kf4iNaABmThyZ0mZt8,
|
|
150
151
|
port_ocean/tests/core/defaults/test_common.py,sha256=sR7RqB3ZYV6Xn6NIg-c8k5K6JcGsYZ2SCe_PYX5vLYM,5560
|
151
152
|
port_ocean/tests/core/handlers/entities_state_applier/test_applier.py,sha256=R9bqyJocUWTh0NW0s-5ttD_SYYeM5EbYILgVmgWa7qA,2776
|
152
153
|
port_ocean/tests/core/handlers/entity_processor/test_jq_entity_processor.py,sha256=FnEnaDjuoAbKvKyv6xJ46n3j0ZcaT70Sg2zc7oy7HAA,13596
|
154
|
+
port_ocean/tests/core/handlers/mixins/test_live_events.py,sha256=iAwVpr3n3PIkXQLw7hxd-iB_SR_vyfletVXJLOmyz28,12480
|
153
155
|
port_ocean/tests/core/handlers/mixins/test_sync_raw.py,sha256=gxQ4e9hQuMS8-o5UbiUSt1I1uaK0DCO3yCFDVigpZvo,31740
|
154
156
|
port_ocean/tests/core/handlers/port_app_config/test_api.py,sha256=eJZ6SuFBLz71y4ca3DNqKag6d6HUjNJS0aqQPwiLMTI,1999
|
155
157
|
port_ocean/tests/core/handlers/port_app_config/test_base.py,sha256=tdjpFUnUZ6TNMxc3trKkzmMTGTb7oKIeu3rRXv_fV3g,6872
|
156
158
|
port_ocean/tests/core/handlers/queue/test_local_queue.py,sha256=9Ly0HzZXbs6Rbl_bstsIdInC3h2bgABU3roP9S_PnJM,2582
|
157
|
-
port_ocean/tests/core/handlers/webhook/test_abstract_webhook_processor.py,sha256=
|
158
|
-
port_ocean/tests/core/handlers/webhook/test_processor_manager.py,sha256=
|
159
|
-
port_ocean/tests/core/handlers/webhook/test_webhook_event.py,sha256=
|
159
|
+
port_ocean/tests/core/handlers/webhook/test_abstract_webhook_processor.py,sha256=lLOVjjUCI973d9Ps_hugWOjyxNgEiPjqZVqN3qC2Rhs,3328
|
160
|
+
port_ocean/tests/core/handlers/webhook/test_processor_manager.py,sha256=jwoimtQqrzro2Q2wBUmtKWN2bg9013GRpm7LEPCix80,44109
|
161
|
+
port_ocean/tests/core/handlers/webhook/test_webhook_event.py,sha256=oR4dEHLO65mp6rkfNfszZcfFoRZlB8ZWee4XetmsuIk,3181
|
160
162
|
port_ocean/tests/core/test_utils.py,sha256=Z3kdhb5V7Svhcyy3EansdTpgHL36TL6erNtU-OPwAcI,2647
|
161
163
|
port_ocean/tests/core/utils/test_entity_topological_sorter.py,sha256=zuq5WSPy_88PemG3mOUIHTxWMR_js1R7tOzUYlgBd68,3447
|
162
164
|
port_ocean/tests/core/utils/test_resolve_entities_diff.py,sha256=4kTey1c0dWKbLXjJ-9m2GXrHyAWZeLQ2asdtYRRUdRs,16573
|
@@ -182,8 +184,8 @@ port_ocean/utils/repeat.py,sha256=U2OeCkHPWXmRTVoPV-VcJRlQhcYqPWI5NfmPlb1JIbc,32
|
|
182
184
|
port_ocean/utils/signal.py,sha256=mMVq-1Ab5YpNiqN4PkiyTGlV_G0wkUDMMjTZp5z3pb0,1514
|
183
185
|
port_ocean/utils/time.py,sha256=pufAOH5ZQI7gXvOvJoQXZXZJV-Dqktoj9Qp9eiRwmJ4,1939
|
184
186
|
port_ocean/version.py,sha256=UsuJdvdQlazzKGD3Hd5-U7N69STh8Dq9ggJzQFnu9fU,177
|
185
|
-
port_ocean-0.
|
186
|
-
port_ocean-0.
|
187
|
-
port_ocean-0.
|
188
|
-
port_ocean-0.
|
189
|
-
port_ocean-0.
|
187
|
+
port_ocean-0.20.1.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
188
|
+
port_ocean-0.20.1.dist-info/METADATA,sha256=uk3Ox7V4NI3zG4nzt9MSS-mIIAGWAHo6XRDs7lfHpRk,6669
|
189
|
+
port_ocean-0.20.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
190
|
+
port_ocean-0.20.1.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
|
191
|
+
port_ocean-0.20.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|