port-ocean 0.29.9__py3-none-any.whl → 0.30.0__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.
@@ -13,7 +13,6 @@ from port_ocean.core.handlers.webhook.processor_manager import (
13
13
  LiveEventsProcessorManager,
14
14
  )
15
15
  from port_ocean.context.ocean import ocean
16
- from port_ocean.core.models import IntegrationFeatureFlag
17
16
  from port_ocean.exceptions.execution_manager import (
18
17
  DuplicateActionExecutorError,
19
18
  PartitionKeyNotFoundError,
@@ -132,13 +131,6 @@ class ExecutionManager:
132
131
  """
133
132
  Start polling and processing action runs for all registered actions.
134
133
  """
135
- flags = await ocean.port_client.get_organization_feature_flags()
136
- if IntegrationFeatureFlag.OCEAN_ACTIONS_PROCESSING_ENABLED not in flags:
137
- logger.warning(
138
- "Actions processing is not allowed for your organization, skipping actions processing"
139
- )
140
- return
141
-
142
134
  if not await ocean.port_client.auth.is_machine_user():
143
135
  logger.warning(
144
136
  "Actions processing is allowed only for machine users, skipping actions processing"
@@ -103,22 +103,42 @@ def can_expression_run_with_no_input(selector_query: str) -> bool:
103
103
 
104
104
  def _can_expression_run_on_single_item(expr: str, key: str) -> bool:
105
105
  """
106
- Detect `.key` outside of quotes, as a standalone path segment beginning
107
- after a non-word boundary (start, space, |, (, [, {, , or :) and not part
108
- of `.something.key`.
109
- assuming key = 'item'
110
- Examples:
111
- - .item.yaeli => true
112
- - map(.item.yaeli) => true
113
- - .body.item => false
106
+ Return True only if all top-level jq paths in the expression
107
+ reference `.key...` and nothing outside that tree.
114
108
  """
115
109
  if not key:
116
110
  return False
117
111
 
118
112
  masked = _mask_strings(expr)
119
113
  masked = _mask_numbers(masked)
120
- pattern = re.compile(rf"(?<![A-Za-z0-9_])\.{re.escape(key)}(?![A-Za-z0-9_])")
121
- return bool(pattern.search(masked))
114
+
115
+ # 🚫 Reject expressions that start from a root-level array, e.g. `.[] | ...` or `.[0] | ...`
116
+ # Top-level ".[" = a dot not preceded by [A-Za-z0-9_.])]
117
+ if re.search(r"(?<![A-Za-z0-9_.\]\)])\.\[", masked):
118
+ return False
119
+
120
+ # Match *top-level* paths only:
121
+ # - A dot NOT preceded by [A-Za-z0-9_.])]
122
+ # (so we don't treat `.field` in `.item.field[0].subfield` as a new root)
123
+ # - Followed by an identifier for the first segment
124
+ paths = re.findall(
125
+ r"(?<![A-Za-z0-9_.\]\)])\.[A-Za-z_][A-Za-z0-9_]*",
126
+ masked,
127
+ )
128
+
129
+ if not paths:
130
+ return False
131
+
132
+ allowed_root = f".{key}"
133
+
134
+ for p in paths:
135
+ if p == allowed_root or p.startswith(allowed_root + "."):
136
+ continue
137
+ else:
138
+ # Some other root field like .name, .body, .foo, etc.
139
+ return False
140
+
141
+ return True
122
142
 
123
143
 
124
144
  def classify_input(
port_ocean/core/models.py CHANGED
@@ -134,7 +134,6 @@ class EntityPortDiff:
134
134
  class IntegrationFeatureFlag(StrEnum):
135
135
  USE_PROVISIONED_DEFAULTS = "USE_PROVISIONED_DEFAULTS"
136
136
  LAKEHOUSE_ELIGIBLE = "LAKEHOUSE_ELIGIBLE"
137
- OCEAN_ACTIONS_PROCESSING_ENABLED = "OCEAN_ACTIONS_PROCESSING_ENABLED"
138
137
 
139
138
 
140
139
  class RunStatus(StrEnum):
@@ -266,6 +266,7 @@ class Metrics:
266
266
  router = APIRouter()
267
267
 
268
268
  @router.get("/", response_class=PlainTextResponse)
269
+ @router.get("", response_class=PlainTextResponse)
269
270
  async def prom_metrics() -> str:
270
271
  return self.generate_latest()
271
272
 
@@ -25,7 +25,6 @@ from port_ocean.core.handlers.webhook.processor_manager import (
25
25
  from port_ocean.core.models import (
26
26
  ActionRun,
27
27
  IntegrationActionInvocationPayload,
28
- IntegrationFeatureFlag,
29
28
  RunStatus,
30
29
  )
31
30
  from port_ocean.exceptions.execution_manager import (
@@ -62,9 +61,6 @@ def mock_port_client() -> MagicMock:
62
61
  mock_port_client.get_run_by_external_id = AsyncMock()
63
62
  mock_port_client.patch_run = AsyncMock()
64
63
  mock_port_client.post_run_log = AsyncMock()
65
- mock_port_client.get_organization_feature_flags = AsyncMock(
66
- return_value=[IntegrationFeatureFlag.OCEAN_ACTIONS_PROCESSING_ENABLED]
67
- )
68
64
  mock_port_client.auth = AsyncMock(spec=PortAuthentication)
69
65
  mock_port_client.auth.is_machine_user = AsyncMock(return_value=True)
70
66
  return mock_port_client
@@ -561,13 +561,13 @@ class TestJQEntityProcessor:
561
561
  "function_with_middle_pattern": "map(.body.item.field)", # Function with middle pattern - ALL
562
562
  "select_with_pattern": 'select(.item.status == "active")', # Select with pattern - SINGLE
563
563
  "select_with_middle_pattern": 'select(.data.item.status == "active")', # Select with middle pattern - ALL
564
- "pipe_with_pattern": ".[] | .item.field", # Pipe with pattern - SINGLE
564
+ "pipe_with_pattern": ".[] | .item.field", # Pipe with pattern - ALL
565
565
  "pipe_with_middle_pattern": ".[] | .body.item.field", # Pipe with middle pattern - ALL
566
566
  "array_with_pattern": "[.item.id, .item.name]", # Array with pattern - SINGLE
567
567
  "array_with_middle_pattern": "[.data.item.id, .body.item.name]", # Array with middle pattern - ALL
568
568
  "object_with_pattern": "{id: .item.id, name: .item.name}", # Object with pattern - SINGLE
569
569
  "object_with_middle_pattern": "{id: .data.item.id, name: .body.item.name}", # Object with middle pattern - ALL
570
- "nested_with_pattern": ".data.items[] | .item.field", # Nested with pattern - SINGLE
570
+ "nested_with_pattern": ".data.items[] | .item.field", # Nested with pattern - ALL
571
571
  "nested_with_middle_pattern": ".data.items[] | .body.item.field", # Nested with middle pattern - ALL
572
572
  "conditional_with_pattern": "if .item.exists then .item.value else null end", # Conditional with pattern - SINGLE
573
573
  "conditional_with_middle_pattern": "if .data.item.exists then .body.item.value else null end", # Conditional with middle pattern - ALL
@@ -597,10 +597,8 @@ class TestJQEntityProcessor:
597
597
  "special_chars": ".item.field[0]",
598
598
  "function_with_pattern": "map(.item.field)",
599
599
  "select_with_pattern": 'select(.item.status == "active")',
600
- "pipe_with_pattern": ".[] | .item.field",
601
600
  "array_with_pattern": "[.item.id, .item.name]",
602
601
  "object_with_pattern": "{id: .item.id, name: .item.name}",
603
- "nested_with_pattern": ".data.items[] | .item.field",
604
602
  "conditional_with_pattern": "if .item.exists then .item.value else null end",
605
603
  },
606
604
  "relations": {
@@ -620,9 +618,11 @@ class TestJQEntityProcessor:
620
618
  "function_with_middle_pattern": "map(.body.item.field)",
621
619
  "select_with_middle_pattern": 'select(.data.item.status == "active")',
622
620
  "item_in_string": 'select(.data.string == ".item")',
621
+ "pipe_with_pattern": ".[] | .item.field",
623
622
  "pipe_with_middle_pattern": ".[] | .body.item.field",
624
623
  "array_with_middle_pattern": "[.data.item.id, .body.item.name]",
625
624
  "object_with_middle_pattern": "{id: .data.item.id, name: .body.item.name}",
625
+ "nested_with_pattern": ".data.items[] | .item.field",
626
626
  "nested_with_middle_pattern": ".data.items[] | .body.item.field",
627
627
  "conditional_with_middle_pattern": "if .data.item.exists then .body.item.value else null end",
628
628
  "field_with_null_name": ".is_null",
@@ -664,10 +664,10 @@ class TestJQEntityProcessor:
664
664
  # JQ expressions with functions that contain .item
665
665
  "mapped_property": "map(.item.field)", # Contains .item but starts with map - SINGLE
666
666
  "selected_property": 'select(.item.status == "active")', # Contains .item but starts with select - SINGLE
667
- "filtered_property": '.[] | select(.item.type == "service")', # Contains .item in pipe - SINGLE
667
+ "filtered_property": '.[] | select(.item.type == "service")', # Main thread is based on the main object - ALL
668
668
  "array_literal": "[.item.id, .item.name]", # Contains .item in array - SINGLE
669
669
  "object_literal": "{id: .item.id, name: .item.name}", # Contains .item in object - SINGLE
670
- "nested_access": ".data.items[] | .item.field", # Contains .item in nested access - SINGLE
670
+ "nested_access": ".data.items[] | .item.field", # Contains .item in nested access - ALL
671
671
  "conditional": "if .item.exists then .item.value else null end", # Contains .item in conditional - SINGLE
672
672
  "function_call": "length(.item.array)", # Contains .item in function call - SINGLE
673
673
  "range_expression": "range(.item.start; .item.end)", # Contains .item in range - SINGLE
@@ -790,10 +790,8 @@ class TestJQEntityProcessor:
790
790
  "properties": {
791
791
  "mapped_property": "map(.item.field)",
792
792
  "selected_property": 'select(.item.status == "active")',
793
- "filtered_property": '.[] | select(.item.type == "service")',
794
793
  "array_literal": "[.item.id, .item.name]",
795
794
  "object_literal": "{id: .item.id, name: .item.name}",
796
- "nested_access": ".data.items[] | .item.field",
797
795
  "conditional": "if .item.exists then .item.value else null end",
798
796
  "function_call": "length(.item.array)",
799
797
  "range_expression": "range(.item.start; .item.end)",
@@ -892,6 +890,8 @@ class TestJQEntityProcessor:
892
890
  # ALL mappings - expressions with dots but not containing .item
893
891
  expected_all = {
894
892
  "properties": {
893
+ "filtered_property": '.[] | select(.item.type == "service")',
894
+ "nested_access": ".data.items[] | .item.field",
895
895
  "external_map": "map(.external.field)",
896
896
  "external_select": 'select(.external.status == "active")',
897
897
  "external_array": "[.external.id, .external.name]",
@@ -318,9 +318,13 @@ class TestCanExpressionRunOnSingleItem:
318
318
 
319
319
  def test_key_in_pipe(self) -> None:
320
320
  """Test key in pipe operations"""
321
- assert _can_expression_run_on_single_item(".[] | .item.field", "item") is True
321
+ assert _can_expression_run_on_single_item(".[] | .item.field", "item") is False
322
322
  assert (
323
- _can_expression_run_on_single_item(".data[] | .item.field", "item") is True
323
+ _can_expression_run_on_single_item(".data[] | .item.field", "item") is False
324
+ )
325
+ assert (
326
+ _can_expression_run_on_single_item("[1,2,3,4] | .item.field", "item")
327
+ is True
324
328
  )
325
329
 
326
330
  def test_key_in_array(self) -> None:
@@ -409,7 +413,7 @@ class TestCanExpressionRunOnSingleItem:
409
413
  """Test key in complex expressions"""
410
414
  assert (
411
415
  _can_expression_run_on_single_item(".data.items[] | .item.field", "item")
412
- is True
416
+ is False
413
417
  )
414
418
  assert (
415
419
  _can_expression_run_on_single_item(
@@ -473,9 +477,7 @@ class TestClassifyInput:
473
477
  classify_input("select(.item.status)", "item")
474
478
  == InputClassifyingResult.SINGLE
475
479
  )
476
- assert (
477
- classify_input(".[] | .item.field", "item") == InputClassifyingResult.SINGLE
478
- )
480
+ assert classify_input(".[] | .item.field", "item") == InputClassifyingResult.ALL
479
481
  assert (
480
482
  classify_input("[.item.id, .item.name]", "item")
481
483
  == InputClassifyingResult.SINGLE
@@ -538,7 +540,7 @@ class TestClassifyInput:
538
540
  # Complex single input expressions
539
541
  assert (
540
542
  classify_input(".data.items[] | .item.field", "item")
541
- == InputClassifyingResult.SINGLE
543
+ == InputClassifyingResult.ALL
542
544
  )
543
545
  assert (
544
546
  classify_input("reduce .item.items[] as $item (0; . + $item.value)", "item")
@@ -835,9 +837,7 @@ class TestIntegration:
835
837
  classify_input('select(.item.status == "active")', "item")
836
838
  == InputClassifyingResult.SINGLE
837
839
  )
838
- assert (
839
- classify_input(".[] | .item.field", "item") == InputClassifyingResult.SINGLE
840
- )
840
+ assert classify_input(".[] | .item.field", "item") == InputClassifyingResult.ALL
841
841
  assert (
842
842
  classify_input("[.item.id, .item.name]", "item")
843
843
  == InputClassifyingResult.SINGLE
@@ -0,0 +1,53 @@
1
+ from fastapi import FastAPI
2
+ from fastapi.testclient import TestClient
3
+ from unittest.mock import Mock
4
+ from port_ocean.helpers.metric.metric import Metrics
5
+
6
+
7
+ def test_metrics_endpoints() -> None:
8
+ """Test that both /metrics and /metrics/ endpoints work correctly."""
9
+ # Create mock settings
10
+ metrics_settings = Mock()
11
+ metrics_settings.enabled = True
12
+
13
+ integration_settings = Mock()
14
+ integration_settings.type = "test"
15
+ integration_settings.identifier = "test-integration"
16
+
17
+ port_client = Mock()
18
+
19
+ # Create metrics instance
20
+ metrics = Metrics(
21
+ metrics_settings=metrics_settings,
22
+ integration_configuration=integration_settings,
23
+ port_client=port_client,
24
+ multiprocessing_enabled=False,
25
+ )
26
+
27
+ # Create FastAPI app with the metrics router using the same pattern as Ocean
28
+ app = FastAPI()
29
+ app.include_router(metrics.create_mertic_router(), prefix="/metrics")
30
+
31
+ # Create test client
32
+ client = TestClient(app)
33
+
34
+ # Test both endpoints
35
+ response_no_slash = client.get("/metrics")
36
+ response_with_slash = client.get("/metrics/")
37
+
38
+ # Both should return 200
39
+ assert (
40
+ response_no_slash.status_code == 200
41
+ ), f"Expected 200, got {response_no_slash.status_code}"
42
+ assert (
43
+ response_with_slash.status_code == 200
44
+ ), f"Expected 200, got {response_with_slash.status_code}"
45
+
46
+ # Both should return the same content
47
+ assert (
48
+ response_no_slash.text == response_with_slash.text
49
+ ), "Endpoints should return identical content"
50
+
51
+ # Verify content type is text/plain (prometheus format)
52
+ assert response_no_slash.headers["content-type"] == "text/plain; charset=utf-8"
53
+ assert response_with_slash.headers["content-type"] == "text/plain; charset=utf-8"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: port-ocean
3
- Version: 0.29.9
3
+ Version: 0.30.0
4
4
  Summary: Port Ocean is a CLI tool for managing your Port projects.
5
5
  Home-page: https://app.getport.io
6
6
  Keywords: ocean,port-ocean,port
@@ -96,7 +96,7 @@ port_ocean/core/event_listener/webhooks_only.py,sha256=No4nNR7fb4ZtivzCFWzpYq4cg
96
96
  port_ocean/core/handlers/__init__.py,sha256=d7ShmS90gLRzGKJA6oNy2Zs_dF2yjkmYZInRhBnO9Rw,572
97
97
  port_ocean/core/handlers/actions/__init__.py,sha256=GNNfYb7C5cw5wPNVSFSmPENbvMZ1nXGhILWz04oasc4,223
98
98
  port_ocean/core/handlers/actions/abstract_executor.py,sha256=4elvJuImKFO36D6fNJIgMho-bdPow-MBpMXSqtBvu2w,6189
99
- port_ocean/core/handlers/actions/execution_manager.py,sha256=iDHMkBiJFhunnSXEbQDD9tUKnhMpWUQvCs9gljyudP0,19382
99
+ port_ocean/core/handlers/actions/execution_manager.py,sha256=kr2yOnStobCEj5em6eWo6KrAXqLYyinR90zXw5hvwUk,19005
100
100
  port_ocean/core/handlers/base.py,sha256=cTarblazu8yh8xz2FpB-dzDKuXxtoi143XJgPbV_DcM,157
101
101
  port_ocean/core/handlers/entities_state_applier/__init__.py,sha256=kgLZDCeCEzi4r-0nzW9k78haOZNf6PX7mJOUr34A4c8,173
102
102
  port_ocean/core/handlers/entities_state_applier/base.py,sha256=5wHL0icfFAYRPqk8iV_wN49GdJ3aRUtO8tumSxBi4Wo,2268
@@ -107,7 +107,7 @@ port_ocean/core/handlers/entities_state_applier/port/order_by_entities_dependenc
107
107
  port_ocean/core/handlers/entity_processor/__init__.py,sha256=FvFCunFg44wNQoqlybem9MthOs7p1Wawac87uSXz9U8,156
108
108
  port_ocean/core/handlers/entity_processor/base.py,sha256=PsnpNRqjHth9xwOvDRe7gKu8cjnVV0XGmTIHGvOelX0,1867
109
109
  port_ocean/core/handlers/entity_processor/jq_entity_processor.py,sha256=Z0njO1z2FUh8hX4GTdH7CmO0Afv-WeYRtxPs34mxKWE,32181
110
- port_ocean/core/handlers/entity_processor/jq_input_evaluator.py,sha256=hInrBMQBbOqZApB53CMLyTgLtC7FltRtqK9PqD0CgM0,4803
110
+ port_ocean/core/handlers/entity_processor/jq_input_evaluator.py,sha256=R88wf69RVtBl8t5m2IKGTmgt4JEQSbct_AmHI_tUOjg,5350
111
111
  port_ocean/core/handlers/port_app_config/__init__.py,sha256=8AAT5OthiVM7KCcM34iEgEeXtn2pRMrT4Dze5r1Ixbk,134
112
112
  port_ocean/core/handlers/port_app_config/api.py,sha256=r_Th66NEw38IpRdnXZcRvI8ACfvxW_A6V62WLwjWXlQ,1044
113
113
  port_ocean/core/handlers/port_app_config/base.py,sha256=Sup4-X_a7JGa27rMy_OgqGIjFHMlKBpKevicaK3AeHU,2919
@@ -131,7 +131,7 @@ port_ocean/core/integrations/mixins/live_events.py,sha256=zM24dhNc7uHx9XYZ6toVhD
131
131
  port_ocean/core/integrations/mixins/sync.py,sha256=Vm_898pLKBwfVewtwouDWsXoxcOLicnAy6pzyqqk6U8,4053
132
132
  port_ocean/core/integrations/mixins/sync_raw.py,sha256=kcL7flnQ25E3KKyo6L3aL9wSzgBtoWYzgQjS4uRbDOs,42612
133
133
  port_ocean/core/integrations/mixins/utils.py,sha256=JegPuIQGBXMnywHBIX30i7gYz0gY7_bW_Jx5LUuQM9c,13718
134
- port_ocean/core/models.py,sha256=sN7viTJbqEEy7j8VEgeffusML31cQWgzI7k8JP64Mbg,3769
134
+ port_ocean/core/models.py,sha256=8ZNEmM3Nq0VSB3fYJVgEdJVjJmaGjMnng-bm-ZBbTNg,3695
135
135
  port_ocean/core/ocean_types.py,sha256=bkLlTd8XfJK6_JDl0eXUHfE_NygqgiInSMwJ4YJH01Q,1399
136
136
  port_ocean/core/utils/entity_topological_sorter.py,sha256=MDUjM6OuDy4Xj68o-7InNN0w1jqjxeDfeY8U02vySNI,3081
137
137
  port_ocean/core/utils/utils.py,sha256=6ySxua6JgVxcjESPL5MScdkpaUj5XR9srorGHHb0B2o,7157
@@ -148,7 +148,7 @@ port_ocean/exceptions/utils.py,sha256=gjOqpi-HpY1l4WlMFsGA9yzhxDhajhoGGdDDyGbLnq
148
148
  port_ocean/exceptions/webhook_processor.py,sha256=4SnkVzVwiacH_Ip4qs1hRHa6GanhnojW_TLTdQQtm7Y,363
149
149
  port_ocean/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
150
150
  port_ocean/helpers/async_client.py,sha256=M8gKUjX8ZwRbmJ-U6KNq-p-nfGr0CwHdS0eN_pbZAJ0,2103
151
- port_ocean/helpers/metric/metric.py,sha256=kBRMCSBrCmwloBt4qnlJWZoZWU-b9hm3Mvm7rCjhtDs,14568
151
+ port_ocean/helpers/metric/metric.py,sha256=9pxpDT-nP0nTZ2kIutCTFuF7IwOQcSJ3dkBA1CVSurc,14626
152
152
  port_ocean/helpers/metric/utils.py,sha256=1lAgrxnZLuR_wUNDyPOPzLrm32b8cDdioob2lvnPQ1A,1619
153
153
  port_ocean/helpers/retry.py,sha256=UiOUo89hUrY0VVLL8sMR8GAYg-UVf2Y3yJ-8hBU1I7E,20285
154
154
  port_ocean/helpers/stream.py,sha256=_UwsThzXynxWzL8OlBT1pmb2evZBi9HaaqeAGNuTuOI,2338
@@ -176,10 +176,10 @@ port_ocean/tests/conftest.py,sha256=JXASSS0IY0nnR6bxBflhzxS25kf4iNaABmThyZ0mZt8,
176
176
  port_ocean/tests/core/conftest.py,sha256=0Oql7R1iTbjPyNdUoO6M21IKknLwnCIgDRz2JQ7nf0w,7748
177
177
  port_ocean/tests/core/defaults/test_common.py,sha256=sR7RqB3ZYV6Xn6NIg-c8k5K6JcGsYZ2SCe_PYX5vLYM,5560
178
178
  port_ocean/tests/core/event_listener/test_kafka.py,sha256=RN_JOCy4aRDUNvyQocO6WFvUMH2XeAZy-PIWHOYnD9M,2888
179
- port_ocean/tests/core/handlers/actions/test_execution_manager.py,sha256=nIS2WwZzxmM3QOr75IfNEfNRhy453eaViLpdbN9wPic,30931
179
+ port_ocean/tests/core/handlers/actions/test_execution_manager.py,sha256=5bOlcQ9qcXF_leoSFtw3FzTa7C1awUPo6TSss5e_76w,30753
180
180
  port_ocean/tests/core/handlers/entities_state_applier/test_applier.py,sha256=7XWgwUB9uVYRov4VbIz1A-7n2YLbHTTYT-4rKJxjB0A,10711
181
- port_ocean/tests/core/handlers/entity_processor/test_jq_entity_processor.py,sha256=7TpqaWcOYLb25SL7e282DmwryCUBllwi387dGHhCMqI,58493
182
- port_ocean/tests/core/handlers/entity_processor/test_jq_input_evaluator.py,sha256=rCXen2k77BnA-p2E6ga2P3Tqo0SU5tQuMYKhB1v92d8,42076
181
+ port_ocean/tests/core/handlers/entity_processor/test_jq_entity_processor.py,sha256=-kLAOGuoA5yN1TT_T3SIPgGnsOqg1iK0qjVOQ9KiU3c,58498
182
+ port_ocean/tests/core/handlers/entity_processor/test_jq_input_evaluator.py,sha256=xNlDK8d8YQOplgjZGSBq4rZYZx_atg2R5YyQnH0qfI4,42151
183
183
  port_ocean/tests/core/handlers/mixins/test_live_events.py,sha256=Sbv9IZAGQoZDhf27xDjMMVYxUSie9mHltDtxLSqckmM,12548
184
184
  port_ocean/tests/core/handlers/mixins/test_sync_raw.py,sha256=-Jd2rUG63fZM8LuyKtCp1tt4WEqO2m5woESjs1c91sU,44428
185
185
  port_ocean/tests/core/handlers/port_app_config/test_api.py,sha256=eJZ6SuFBLz71y4ca3DNqKag6d6HUjNJS0aqQPwiLMTI,1999
@@ -203,6 +203,7 @@ port_ocean/tests/helpers/smoke_test.py,sha256=_9aJJFRfuGJEg2D2YQJVJRmpreS6gEPHHQ
203
203
  port_ocean/tests/helpers/test_retry.py,sha256=w1p0flGunT0NxrUVtlR5FvSDg_vXGrlWyg_e6tJRVn4,20435
204
204
  port_ocean/tests/log/test_handlers.py,sha256=x2P2Hd6Cb3sQafIE3TRGltbbHeiFHaiEjwRn9py_03g,2165
205
205
  port_ocean/tests/test_metric.py,sha256=gDdeJcqJDQ_o3VrYrW23iZyw2NuUsyATdrygSXhcDuQ,8096
206
+ port_ocean/tests/test_metrics_endpoints.py,sha256=cOljs3NweC1hyP03iEaPKGv1Vt_y0O4tKA-Fh2PsL4I,1771
206
207
  port_ocean/tests/test_ocean.py,sha256=bsXKGTVEjwLSbR7-qSmI4GZ-EzDo0eBE3TNSMsWzYxM,1502
207
208
  port_ocean/tests/test_smoke.py,sha256=uix2uIg_yOm8BHDgHw2hTFPy1fiIyxBGW3ENU_KoFlo,2557
208
209
  port_ocean/tests/utils/test_async_iterators.py,sha256=3PLk1emEXekb8LcC5GgVh3OicaX15i5WyaJT_eFnu_4,1336
@@ -218,8 +219,8 @@ port_ocean/utils/repeat.py,sha256=U2OeCkHPWXmRTVoPV-VcJRlQhcYqPWI5NfmPlb1JIbc,32
218
219
  port_ocean/utils/signal.py,sha256=J1sI-e_32VHP_VUa5bskLMFoJjJOAk5isrnewKDikUI,2125
219
220
  port_ocean/utils/time.py,sha256=pufAOH5ZQI7gXvOvJoQXZXZJV-Dqktoj9Qp9eiRwmJ4,1939
220
221
  port_ocean/version.py,sha256=UsuJdvdQlazzKGD3Hd5-U7N69STh8Dq9ggJzQFnu9fU,177
221
- port_ocean-0.29.9.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
222
- port_ocean-0.29.9.dist-info/METADATA,sha256=TDdqu33zG35WNLxcyfuKpOKRIWQXSLRZZObRrjAKW_c,7054
223
- port_ocean-0.29.9.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
224
- port_ocean-0.29.9.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
225
- port_ocean-0.29.9.dist-info/RECORD,,
222
+ port_ocean-0.30.0.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
223
+ port_ocean-0.30.0.dist-info/METADATA,sha256=uglxgjupYpTwJ-w_rUz6Tf17jeaTcdvT4xz1QNCsFpc,7054
224
+ port_ocean-0.30.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
225
+ port_ocean-0.30.0.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
226
+ port_ocean-0.30.0.dist-info/RECORD,,