port-ocean 0.17.1__py3-none-any.whl → 0.17.5__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.

Potentially problematic release.


This version of port-ocean might be problematic. Click here for more details.

@@ -22,7 +22,7 @@ endef
22
22
  define install_poetry
23
23
  if ! command -v poetry &> /dev/null; then \
24
24
  pip install --upgrade pip; \
25
- pip install poetry; \
25
+ pip install 'poetry>=1.0.0,<2.0.0'; \
26
26
  else \
27
27
  echo "Poetry is already installed."; \
28
28
  fi
@@ -73,7 +73,7 @@ class PortOceanContext:
73
73
  def on_resync(
74
74
  self,
75
75
  kind: str | None = None,
76
- ) -> Callable[[RESYNC_EVENT_LISTENER], RESYNC_EVENT_LISTENER | None]:
76
+ ) -> Callable[[RESYNC_EVENT_LISTENER | None], RESYNC_EVENT_LISTENER | None]:
77
77
  def wrapper(
78
78
  function: RESYNC_EVENT_LISTENER | None,
79
79
  ) -> RESYNC_EVENT_LISTENER | None:
@@ -3,7 +3,6 @@ from asyncio import Task
3
3
  from dataclasses import dataclass, field
4
4
  from functools import lru_cache
5
5
  from typing import Any, Optional
6
-
7
6
  import jq # type: ignore
8
7
  from loguru import logger
9
8
 
@@ -66,6 +65,22 @@ class JQEntityProcessor(BaseEntityProcessor):
66
65
 
67
66
  return inner
68
67
 
68
+ @staticmethod
69
+ def _notify_mapping_issues(
70
+ entity_misconfigurations: dict[str, str],
71
+ missing_required_fields: bool,
72
+ entity_mapping_fault_counter: int,
73
+ ) -> None:
74
+
75
+ if len(entity_misconfigurations) > 0:
76
+ logger.info(
77
+ f"Unable to find valid data for: {entity_misconfigurations} (null, missing, or misconfigured)"
78
+ )
79
+ if missing_required_fields:
80
+ logger.info(
81
+ f"{entity_mapping_fault_counter} transformations of batch failed due to empty, null or missing values"
82
+ )
83
+
69
84
  async def _search(self, data: dict[str, Any], pattern: str) -> Any:
70
85
  try:
71
86
  loop = asyncio.get_event_loop()
@@ -252,9 +267,12 @@ class JQEntityProcessor(BaseEntityProcessor):
252
267
  examples_to_send: list[dict[str, Any]] = []
253
268
  entity_misconfigurations: dict[str, str] = {}
254
269
  missing_required_fields: bool = False
270
+ entity_mapping_fault_counter: int = 0
271
+
255
272
  for result in calculated_entities_results:
256
273
  if len(result.misconfigurations) > 0:
257
274
  entity_misconfigurations |= result.misconfigurations
275
+
258
276
  if result.entity.get("identifier") and result.entity.get("blueprint"):
259
277
  parsed_entity = Entity.parse_obj(result.entity)
260
278
  if result.did_entity_pass_selector:
@@ -268,10 +286,14 @@ class JQEntityProcessor(BaseEntityProcessor):
268
286
  failed_entities.append(parsed_entity)
269
287
  else:
270
288
  missing_required_fields = True
271
- if len(entity_misconfigurations) > 0:
272
- logger.info(
273
- f"The mapping resulted with invalid values for{" identifier, blueprint," if missing_required_fields else " "} properties. Mapping result: {entity_misconfigurations}"
274
- )
289
+ entity_mapping_fault_counter += 1
290
+
291
+ self._notify_mapping_issues(
292
+ entity_misconfigurations,
293
+ missing_required_fields,
294
+ entity_mapping_fault_counter,
295
+ )
296
+
275
297
  if (
276
298
  not calculated_entities_results
277
299
  and raw_results
@@ -1,6 +1,8 @@
1
1
  from typing import Any
2
2
  from unittest.mock import AsyncMock, Mock
3
+ from loguru import logger
3
4
  import pytest
5
+ from io import StringIO
4
6
 
5
7
  from port_ocean.context.ocean import PortOceanContext
6
8
  from port_ocean.core.handlers.entity_processor.jq_entity_processor import (
@@ -303,3 +305,46 @@ class TestJQEntityProcessor:
303
305
  "url": ".foobar",
304
306
  "defaultBranch": ".bar.baz",
305
307
  }
308
+
309
+ async def test_parse_items_empty_required(
310
+ self, mocked_processor: JQEntityProcessor
311
+ ) -> None:
312
+ stream = StringIO()
313
+ sink_id = logger.add(stream, level="DEBUG")
314
+
315
+ mapping = Mock()
316
+ mapping.port.entity.mappings.dict.return_value = {
317
+ "identifier": ".foo",
318
+ "blueprint": ".bar",
319
+ }
320
+ mapping.port.items_to_parse = None
321
+ mapping.selector.query = "true"
322
+ raw_results: list[dict[Any, Any]] = [
323
+ {"foo": "", "bar": "bluePrintMapped"},
324
+ {"foo": "identifierMapped", "bar": ""},
325
+ ]
326
+ result = await mocked_processor._parse_items(mapping, raw_results)
327
+ assert "identifier" not in result.misonfigured_entity_keys
328
+ assert "blueprint" not in result.misonfigured_entity_keys
329
+
330
+ raw_results = [
331
+ {"foo": "identifierMapped", "bar": None},
332
+ {"foo": None, "bar": ""},
333
+ ]
334
+ result = await mocked_processor._parse_items(mapping, raw_results)
335
+ assert result.misonfigured_entity_keys == {
336
+ "identifier": ".foo",
337
+ "blueprint": ".bar",
338
+ }
339
+
340
+ logger.remove(sink_id)
341
+ logs_captured = stream.getvalue()
342
+
343
+ assert (
344
+ "2 transformations of batch failed due to empty, null or missing values"
345
+ in logs_captured
346
+ )
347
+ assert (
348
+ "{'blueprint': '.bar', 'identifier': '.foo'} (null, missing, or misconfigured)"
349
+ in logs_captured
350
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: port-ocean
3
- Version: 0.17.1
3
+ Version: 0.17.5
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
@@ -3,7 +3,7 @@ integrations/_infra/Dockerfile.alpine,sha256=iauglyEzz5uEPBxsN-9SLFr6qca3Tf4b0DP
3
3
  integrations/_infra/Dockerfile.base.builder,sha256=LwKLfJvQfKksMqacAT_aDQxFMC2Ty5fFKIa0Eu4QcCc,619
4
4
  integrations/_infra/Dockerfile.base.runner,sha256=dsjTWgLQFm4x5gcm-IPhwkDv-M6VRKwdf-qct457h2c,357
5
5
  integrations/_infra/Dockerfile.dockerignore,sha256=CM1Fxt3I2AvSvObuUZRmy5BNLSGC7ylnbpWzFgD4cso,1163
6
- integrations/_infra/Makefile,sha256=zSZJ5ubxR84NCSs74rFFkjaZupo1FUZ90QnRPBKgsUM,2126
6
+ integrations/_infra/Makefile,sha256=ofVvsebe7-inGBjZI976L6ghe1Z3RhKFvQhCf6clHn8,2142
7
7
  integrations/_infra/grpcio.sh,sha256=m924poYznoRZ6Tt7Ct8Cs5AV_cmmOx598yIZ3z4DvZE,616
8
8
  integrations/_infra/init.sh,sha256=nN8lTrOhB286UfFvD6sJ9YJ-9asT9zVSddQB-RAb7Z4,99
9
9
  port_ocean/__init__.py,sha256=J3Mqp7d-CkEe9eMigGG8gSEiVKICY2bf7csNEwVOXk0,294
@@ -63,7 +63,7 @@ port_ocean/consumers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
63
63
  port_ocean/consumers/kafka_consumer.py,sha256=N8KocjBi9aR0BOPG8hgKovg-ns_ggpEjrSxqSqF_BSo,4710
64
64
  port_ocean/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
65
  port_ocean/context/event.py,sha256=tf254jMqBW1GBmYDhfXMCkOqHA7C_chaYp1OY3Dfnsg,5869
66
- port_ocean/context/ocean.py,sha256=ViRfr_E7R575_s01vhk8ta5P0mLvm2FF8K2EXR0eD8Y,4986
66
+ port_ocean/context/ocean.py,sha256=0kgIi0zAsGarF52Qehu4bOxnAFEb0yayzG7xZioMHJc,4993
67
67
  port_ocean/context/resource.py,sha256=yDj63URzQelj8zJPh4BAzTtPhpKr9Gw9DRn7I_0mJ1s,1692
68
68
  port_ocean/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
69
  port_ocean/core/defaults/__init__.py,sha256=8qCZg8n06WAdMu9s_FiRtDYLGPGHbOuS60vapeUoAks,142
@@ -88,7 +88,7 @@ port_ocean/core/handlers/entities_state_applier/port/get_related_entities.py,sha
88
88
  port_ocean/core/handlers/entities_state_applier/port/order_by_entities_dependencies.py,sha256=lyv6xKzhYfd6TioUgR3AVRSJqj7JpAaj1LxxU2xAqeo,1720
89
89
  port_ocean/core/handlers/entity_processor/__init__.py,sha256=FvFCunFg44wNQoqlybem9MthOs7p1Wawac87uSXz9U8,156
90
90
  port_ocean/core/handlers/entity_processor/base.py,sha256=udR0w5TstTOS5xOfTjAZIEdldn4xr6Oyb3DylatYX3Q,1869
91
- port_ocean/core/handlers/entity_processor/jq_entity_processor.py,sha256=X-up0HVdE8pkITxzvB1BC7W8Oq0C14WbT3WqV7p-wJc,11129
91
+ port_ocean/core/handlers/entity_processor/jq_entity_processor.py,sha256=C6zJbS3miKyDeXiEV-0t5vJvkEznOeXRZFFOnwJcNdA,11714
92
92
  port_ocean/core/handlers/port_app_config/__init__.py,sha256=8AAT5OthiVM7KCcM34iEgEeXtn2pRMrT4Dze5r1Ixbk,134
93
93
  port_ocean/core/handlers/port_app_config/api.py,sha256=6VbKPwFzsWG0IYsVD81hxSmfqtHUFqrfUuj1DBX5g4w,853
94
94
  port_ocean/core/handlers/port_app_config/base.py,sha256=4Nxt2g8voEIHJ4Y1Km5NJcaG2iSbCklw5P8-Kus7Y9k,3007
@@ -132,7 +132,7 @@ port_ocean/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
132
132
  port_ocean/tests/clients/port/mixins/test_entities.py,sha256=A9myrnkLhKSQrnOLv1Zz2wiOVSxW65Q9RIUIRbn_V7w,1586
133
133
  port_ocean/tests/conftest.py,sha256=JXASSS0IY0nnR6bxBflhzxS25kf4iNaABmThyZ0mZt8,101
134
134
  port_ocean/tests/core/defaults/test_common.py,sha256=sR7RqB3ZYV6Xn6NIg-c8k5K6JcGsYZ2SCe_PYX5vLYM,5560
135
- port_ocean/tests/core/handlers/entity_processor/test_jq_entity_processor.py,sha256=C2nLgapTdXRrzP5B4xBuHcc14L-NztFpxLIv8Iuv6Gg,12046
135
+ port_ocean/tests/core/handlers/entity_processor/test_jq_entity_processor.py,sha256=FnEnaDjuoAbKvKyv6xJ46n3j0ZcaT70Sg2zc7oy7HAA,13596
136
136
  port_ocean/tests/core/handlers/mixins/test_sync_raw.py,sha256=RPrbw4Zs6bmhL9zMQviq7-qMfgP5_4nJDkfZiAukK-g,15782
137
137
  port_ocean/tests/core/test_utils.py,sha256=Z3kdhb5V7Svhcyy3EansdTpgHL36TL6erNtU-OPwAcI,2647
138
138
  port_ocean/tests/core/utils/test_entity_topological_sorter.py,sha256=zuq5WSPy_88PemG3mOUIHTxWMR_js1R7tOzUYlgBd68,3447
@@ -157,8 +157,8 @@ port_ocean/utils/repeat.py,sha256=0EFWM9d8lLXAhZmAyczY20LAnijw6UbIECf5lpGbOas,32
157
157
  port_ocean/utils/signal.py,sha256=K-6kKFQTltcmKDhtyZAcn0IMa3sUpOHGOAUdWKgx0_E,1369
158
158
  port_ocean/utils/time.py,sha256=pufAOH5ZQI7gXvOvJoQXZXZJV-Dqktoj9Qp9eiRwmJ4,1939
159
159
  port_ocean/version.py,sha256=UsuJdvdQlazzKGD3Hd5-U7N69STh8Dq9ggJzQFnu9fU,177
160
- port_ocean-0.17.1.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
161
- port_ocean-0.17.1.dist-info/METADATA,sha256=0OWjckTIgh6CjguvP_HQccZLFi2DSh5GrTS52PaJuqA,6673
162
- port_ocean-0.17.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
163
- port_ocean-0.17.1.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
164
- port_ocean-0.17.1.dist-info/RECORD,,
160
+ port_ocean-0.17.5.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
161
+ port_ocean-0.17.5.dist-info/METADATA,sha256=MLLVprYgIbrMB7-PJAhNDxR3k18AXhgen-D-rh-5A7w,6673
162
+ port_ocean-0.17.5.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
163
+ port_ocean-0.17.5.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
164
+ port_ocean-0.17.5.dist-info/RECORD,,