port-ocean 0.28.0__py3-none-any.whl → 0.28.2__py3-none-any.whl
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.
- port_ocean/core/handlers/resync_state_updater/updater.py +4 -2
- port_ocean/core/integrations/mixins/sync_raw.py +10 -10
- port_ocean/log/logger_setup.py +6 -4
- port_ocean/ocean.py +16 -0
- port_ocean/utils/misc.py +5 -3
- port_ocean/utils/signal.py +23 -8
- {port_ocean-0.28.0.dist-info → port_ocean-0.28.2.dist-info}/METADATA +1 -1
- {port_ocean-0.28.0.dist-info → port_ocean-0.28.2.dist-info}/RECORD +11 -11
- {port_ocean-0.28.0.dist-info → port_ocean-0.28.2.dist-info}/LICENSE.md +0 -0
- {port_ocean-0.28.0.dist-info → port_ocean-0.28.2.dist-info}/WHEEL +0 -0
- {port_ocean-0.28.0.dist-info → port_ocean-0.28.2.dist-info}/entry_points.txt +0 -0
@@ -1,10 +1,11 @@
|
|
1
1
|
import datetime
|
2
2
|
from typing import Any, Literal
|
3
|
+
|
3
4
|
from port_ocean.clients.port.client import PortClient
|
5
|
+
from port_ocean.context.ocean import ocean
|
6
|
+
from port_ocean.helpers.metric.metric import MetricPhase, MetricType
|
4
7
|
from port_ocean.utils.misc import IntegrationStateStatus
|
5
8
|
from port_ocean.utils.time import get_next_occurrence
|
6
|
-
from port_ocean.context.ocean import ocean
|
7
|
-
from port_ocean.helpers.metric.metric import MetricType, MetricPhase
|
8
9
|
|
9
10
|
|
10
11
|
class ResyncStateUpdater:
|
@@ -99,3 +100,4 @@ class ResyncStateUpdater:
|
|
99
100
|
await ocean.metrics.report_sync_metrics(
|
100
101
|
kinds=[ocean.metrics.current_resource_kind()]
|
101
102
|
)
|
103
|
+
ocean.metrics.event_id = ""
|
@@ -455,16 +455,16 @@ class SyncRawMixin(HandlerMixin, EventsMixin):
|
|
455
455
|
],
|
456
456
|
value=number_of_transformed_entities,
|
457
457
|
)
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
458
|
+
if number_of_raw_results > number_of_transformed_entities :
|
459
|
+
ocean.metrics.inc_metric(
|
460
|
+
name=MetricType.OBJECT_COUNT_NAME,
|
461
|
+
labels=[
|
462
|
+
ocean.metrics.current_resource_kind(),
|
463
|
+
MetricPhase.TRANSFORM,
|
464
|
+
MetricPhase.TransformResult.FILTERED_OUT,
|
465
|
+
],
|
466
|
+
value=number_of_raw_results - number_of_transformed_entities,
|
467
|
+
)
|
468
468
|
|
469
469
|
return passed_entities, errors
|
470
470
|
|
port_ocean/log/logger_setup.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
import sys
|
2
1
|
import os
|
2
|
+
import sys
|
3
|
+
import uuid
|
3
4
|
from logging import LogRecord
|
4
5
|
from logging.handlers import QueueHandler, QueueListener
|
5
6
|
from queue import Queue
|
6
|
-
import uuid
|
7
7
|
|
8
8
|
import loguru
|
9
9
|
from loguru import logger
|
@@ -60,8 +60,10 @@ def _http_loguru_handler(level: LogLevelType) -> None:
|
|
60
60
|
logger.configure(patcher=exception_deserializer)
|
61
61
|
|
62
62
|
http_memory_handler = HTTPMemoryHandler()
|
63
|
-
signal_handler.register(
|
64
|
-
|
63
|
+
signal_handler.register(
|
64
|
+
http_memory_handler.wait_for_lingering_threads, priority=-200
|
65
|
+
)
|
66
|
+
signal_handler.register(http_memory_handler.flush, priority=-200)
|
65
67
|
|
66
68
|
queue_listener = QueueListener(queue, http_memory_handler)
|
67
69
|
queue_listener.start()
|
port_ocean/ocean.py
CHANGED
@@ -97,6 +97,22 @@ class Ocean:
|
|
97
97
|
)
|
98
98
|
self.app_initialized = False
|
99
99
|
|
100
|
+
signal_handler.register(self._report_resync_aborted)
|
101
|
+
|
102
|
+
async def _report_resync_aborted(self) -> None:
|
103
|
+
"""
|
104
|
+
Report resync status as aborted when the app receives a kill signal.
|
105
|
+
This ensures Port is notified that the integration was interrupted.
|
106
|
+
"""
|
107
|
+
try:
|
108
|
+
if self.metrics.event_id != "":
|
109
|
+
await self.resync_state_updater.update_after_resync(
|
110
|
+
IntegrationStateStatus.Aborted
|
111
|
+
)
|
112
|
+
logger.info("Resync status reported as aborted due to app shutdown")
|
113
|
+
except Exception as e:
|
114
|
+
logger.warning(f"Failed to report resync status on shutdown: {e}")
|
115
|
+
|
100
116
|
def _get_process_execution_mode(self) -> ProcessExecutionMode:
|
101
117
|
if self.config.process_execution_mode:
|
102
118
|
return self.config.process_execution_mode
|
port_ocean/utils/misc.py
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
from enum import Enum
|
2
1
|
import inspect
|
3
|
-
from
|
2
|
+
from enum import Enum
|
3
|
+
from importlib.util import module_from_spec, spec_from_file_location
|
4
4
|
from pathlib import Path
|
5
5
|
from time import time
|
6
6
|
from types import ModuleType
|
7
|
-
from typing import
|
7
|
+
from typing import Any, Callable
|
8
8
|
from uuid import uuid4
|
9
|
+
|
9
10
|
import tomli
|
10
11
|
import yaml
|
11
12
|
|
@@ -14,6 +15,7 @@ class IntegrationStateStatus(Enum):
|
|
14
15
|
Running = "running"
|
15
16
|
Failed = "failed"
|
16
17
|
Completed = "completed"
|
18
|
+
Aborted = "aborted"
|
17
19
|
|
18
20
|
|
19
21
|
def get_time(seconds_precision: bool = True) -> float:
|
port_ocean/utils/signal.py
CHANGED
@@ -1,37 +1,52 @@
|
|
1
1
|
from asyncio import iscoroutinefunction
|
2
|
-
from typing import
|
2
|
+
from typing import Any, Callable
|
3
3
|
|
4
4
|
from werkzeug.local import LocalProxy, LocalStack
|
5
5
|
|
6
6
|
from port_ocean.exceptions.utils import (
|
7
|
-
SignalHandlerNotInitialized,
|
8
7
|
SignalHandlerAlreadyInitialized,
|
8
|
+
SignalHandlerNotInitialized,
|
9
9
|
)
|
10
10
|
from port_ocean.utils.misc import generate_uuid
|
11
11
|
|
12
12
|
|
13
13
|
class SignalHandler:
|
14
14
|
def __init__(self) -> None:
|
15
|
-
self._handlers: dict[str, Callable[[], Any]] = {}
|
15
|
+
self._handlers: dict[str, tuple[Callable[[], Any], int]] = {}
|
16
16
|
|
17
17
|
async def exit(self) -> None:
|
18
18
|
"""
|
19
19
|
Handles the exit signal.
|
20
|
+
Executes handlers in priority order (highest priority first).
|
20
21
|
"""
|
21
|
-
|
22
|
-
|
22
|
+
# Sort handlers by priority (highest first) and execute them
|
23
|
+
sorted_handlers = sorted(
|
24
|
+
self._handlers.items(), key=lambda x: x[1][1], reverse=True
|
25
|
+
)
|
26
|
+
|
27
|
+
for _id, (handler, _) in sorted_handlers:
|
23
28
|
if iscoroutinefunction(handler):
|
24
29
|
await handler()
|
25
30
|
else:
|
26
31
|
handler()
|
27
32
|
|
28
|
-
def register(self, callback: Callable[[], Any]) -> str:
|
29
|
-
|
30
|
-
|
33
|
+
def register(self, callback: Callable[[], Any], priority: int = 0) -> str:
|
34
|
+
"""
|
35
|
+
Register a callback with a priority.
|
36
|
+
|
37
|
+
Args:
|
38
|
+
callback: The callback function to register
|
39
|
+
priority: Priority level (higher numbers execute first, default: 0)
|
31
40
|
|
41
|
+
Returns:
|
42
|
+
Unique identifier for the registered callback
|
43
|
+
"""
|
44
|
+
_id = generate_uuid()
|
45
|
+
self._handlers[_id] = (callback, priority)
|
32
46
|
return _id
|
33
47
|
|
34
48
|
def unregister(self, _id: str) -> None:
|
49
|
+
"""Unregister a callback by its ID."""
|
35
50
|
del self._handlers[_id]
|
36
51
|
|
37
52
|
|
@@ -111,7 +111,7 @@ port_ocean/core/handlers/queue/abstract_queue.py,sha256=SaivrYbqg8qsX6wtQlJZyxgc
|
|
111
111
|
port_ocean/core/handlers/queue/group_queue.py,sha256=JvvJOwz9z_aI4CjPr7yQX-0rOgqLI5wMdxWk2x5x-34,4989
|
112
112
|
port_ocean/core/handlers/queue/local_queue.py,sha256=Y6qabDbrQ8aOPTN6Ct3lnMU7JnT8O8iTpoxMoVt6lFs,643
|
113
113
|
port_ocean/core/handlers/resync_state_updater/__init__.py,sha256=kG6y-JQGpPfuTHh912L_bctIDCzAK4DN-d00S7rguWU,81
|
114
|
-
port_ocean/core/handlers/resync_state_updater/updater.py,sha256=
|
114
|
+
port_ocean/core/handlers/resync_state_updater/updater.py,sha256=9nv7KY9ueszdGpZKss25foyQ_GYYzpuVZyusEaMNjKU,3850
|
115
115
|
port_ocean/core/handlers/webhook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
116
116
|
port_ocean/core/handlers/webhook/abstract_webhook_processor.py,sha256=5KwZkdkDd5HdVkXPzKiqabodZKl-hOtMypkTKd8Hq3M,3891
|
117
117
|
port_ocean/core/handlers/webhook/processor_manager.py,sha256=0KRPD1ae-7w0na2AZY-rq9_gY0IaMv9LdwEh6y4_OiQ,13282
|
@@ -123,7 +123,7 @@ port_ocean/core/integrations/mixins/events.py,sha256=2L7P3Jhp8XBqddh2_o9Cn4N261n
|
|
123
123
|
port_ocean/core/integrations/mixins/handler.py,sha256=mZ7-0UlG3LcrwJttFbMe-R4xcOU2H_g33tZar7PwTv8,3771
|
124
124
|
port_ocean/core/integrations/mixins/live_events.py,sha256=zM24dhNc7uHx9XYZ6toVhDADPA90EnpOmZxgDegFZbA,4196
|
125
125
|
port_ocean/core/integrations/mixins/sync.py,sha256=Vm_898pLKBwfVewtwouDWsXoxcOLicnAy6pzyqqk6U8,4053
|
126
|
-
port_ocean/core/integrations/mixins/sync_raw.py,sha256=
|
126
|
+
port_ocean/core/integrations/mixins/sync_raw.py,sha256=EJLF0vMFVkQi4zJPQAFtg-VkQJsOGbya3yhEfWu2L1c,40734
|
127
127
|
port_ocean/core/integrations/mixins/utils.py,sha256=ytnFX7Lyv6N3CgBnOXxYaI1cRDq5Z4NDrVFiwE6bn-M,5250
|
128
128
|
port_ocean/core/models.py,sha256=DNbKpStMINI2lIekKprTqBevqkw_wFuFayN19w1aDfQ,2893
|
129
129
|
port_ocean/core/ocean_types.py,sha256=bkLlTd8XfJK6_JDl0eXUHfE_NygqgiInSMwJ4YJH01Q,1399
|
@@ -147,10 +147,10 @@ port_ocean/helpers/retry.py,sha256=QM04mzaevIUlg8HnHjeY9UT_D4k26BHx3hVkCjV_jnY,2
|
|
147
147
|
port_ocean/helpers/stream.py,sha256=_UwsThzXynxWzL8OlBT1pmb2evZBi9HaaqeAGNuTuOI,2338
|
148
148
|
port_ocean/log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
149
149
|
port_ocean/log/handlers.py,sha256=LJ1WAfq7wYCrBpeLPihMKmWjdSahKKXNHFMRYkbk0Co,3630
|
150
|
-
port_ocean/log/logger_setup.py,sha256=
|
150
|
+
port_ocean/log/logger_setup.py,sha256=5JxGlg7TKDbYD2ladgaHufCv6PTJXvdQJ8l6cP3MKFA,2700
|
151
151
|
port_ocean/log/sensetive.py,sha256=lVKiZH6b7TkrZAMmhEJRhcl67HNM94e56x12DwFgCQk,2920
|
152
152
|
port_ocean/middlewares.py,sha256=9wYCdyzRZGK1vjEJ28FY_DkfwDNENmXp504UKPf5NaQ,2727
|
153
|
-
port_ocean/ocean.py,sha256=
|
153
|
+
port_ocean/ocean.py,sha256=erUfBUJLsHs9uAaoHY-cPczqbICG4Gu02luK0nfoJAQ,9556
|
154
154
|
port_ocean/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
155
155
|
port_ocean/run.py,sha256=CmKz14bxfdOooNbQ5QqH1MwX-XLYVG4NgT4KbrzFaqI,2216
|
156
156
|
port_ocean/sonar-project.properties,sha256=X_wLzDOkEVmpGLRMb2fg9Rb0DxWwUFSvESId8qpvrPI,73
|
@@ -202,14 +202,14 @@ port_ocean/utils/async_http.py,sha256=aDsw3gQIMwt6qLegbZtkHqD8em48tKvbITnblsrTY3
|
|
202
202
|
port_ocean/utils/async_iterators.py,sha256=CPXskYWkhkZtAG-ducEwM8537t3z5usPEqXR9vcivzw,3715
|
203
203
|
port_ocean/utils/cache.py,sha256=tRwPomG2VIxx8ZNi4QYH6Yc47d9yYV1A7Hx-L_fX4Dg,4494
|
204
204
|
port_ocean/utils/ipc.py,sha256=eTjTTvsKl6IXYeOkIjP5iyrw-8gLQ9rf15WeyxCqXog,912
|
205
|
-
port_ocean/utils/misc.py,sha256=
|
205
|
+
port_ocean/utils/misc.py,sha256=cQGBWL9IN7ER6s7xyHzeKvj60ntW70WiYIq9MyLe1nY,2123
|
206
206
|
port_ocean/utils/queue_utils.py,sha256=KWWl8YVnG-glcfIHhM6nefY-2sou_C6DVP1VynQwzB4,2762
|
207
207
|
port_ocean/utils/repeat.py,sha256=U2OeCkHPWXmRTVoPV-VcJRlQhcYqPWI5NfmPlb1JIbc,3229
|
208
|
-
port_ocean/utils/signal.py,sha256=
|
208
|
+
port_ocean/utils/signal.py,sha256=J1sI-e_32VHP_VUa5bskLMFoJjJOAk5isrnewKDikUI,2125
|
209
209
|
port_ocean/utils/time.py,sha256=pufAOH5ZQI7gXvOvJoQXZXZJV-Dqktoj9Qp9eiRwmJ4,1939
|
210
210
|
port_ocean/version.py,sha256=UsuJdvdQlazzKGD3Hd5-U7N69STh8Dq9ggJzQFnu9fU,177
|
211
|
-
port_ocean-0.28.
|
212
|
-
port_ocean-0.28.
|
213
|
-
port_ocean-0.28.
|
214
|
-
port_ocean-0.28.
|
215
|
-
port_ocean-0.28.
|
211
|
+
port_ocean-0.28.2.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
212
|
+
port_ocean-0.28.2.dist-info/METADATA,sha256=5T2f0NQsbLtV8Ero37oN7KmSDdG6VY5YbgjCX1S64fo,7015
|
213
|
+
port_ocean-0.28.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
214
|
+
port_ocean-0.28.2.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
|
215
|
+
port_ocean-0.28.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|