port-ocean 0.5.3rc1__py3-none-any.whl → 0.5.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.

@@ -1,6 +1,5 @@
1
1
  import asyncio
2
2
  import functools
3
- from asyncio import TaskGroup
4
3
  from functools import lru_cache
5
4
  from typing import Any
6
5
 
@@ -22,15 +21,13 @@ class JQEntityProcessor(BaseEntityProcessor):
22
21
  """
23
22
 
24
23
  @lru_cache
25
- async def _compile(self, pattern: str) -> Any:
26
- loop = asyncio.get_event_loop()
27
- compiler = functools.partial(jq.compile, pattern)
28
- return await loop.run_in_executor(None, compiler)
24
+ def _compile(self, pattern: str) -> Any:
25
+ return jq.compile(pattern)
29
26
 
30
27
  async def _search(self, data: dict[str, Any], pattern: str) -> Any:
31
28
  try:
32
29
  loop = asyncio.get_event_loop()
33
- compiled_pattern = await self._compile(pattern)
30
+ compiled_pattern = self._compile(pattern)
34
31
  first_value_callable = functools.partial(compiled_pattern.first, data)
35
32
  return await loop.run_in_executor(None, first_value_callable)
36
33
  except Exception:
@@ -38,7 +35,7 @@ class JQEntityProcessor(BaseEntityProcessor):
38
35
 
39
36
  async def _search_as_bool(self, data: dict[str, Any], pattern: str) -> bool:
40
37
  loop = asyncio.get_event_loop()
41
- compiled_pattern = await self._compile(pattern)
38
+ compiled_pattern = self._compile(pattern)
42
39
  first_value_callable = functools.partial(compiled_pattern.first, data)
43
40
  value = await loop.run_in_executor(None, first_value_callable)
44
41
 
@@ -53,14 +50,13 @@ class JQEntityProcessor(BaseEntityProcessor):
53
50
  self, data: dict[str, Any], obj: dict[str, Any]
54
51
  ) -> dict[str, Any | None]:
55
52
  search_tasks = {}
56
- with TaskGroup() as tg:
57
- for key, value in obj.items():
58
- if isinstance(value, dict):
59
- search_tasks[key] = tg.create_task(
60
- self._search_as_object(data, value)
61
- )
62
- else:
63
- search_tasks[key] = tg.create_task(self._search(data, value))
53
+ for key, value in obj.items():
54
+ if isinstance(value, dict):
55
+ search_tasks[key] = asyncio.create_task(
56
+ self._search_as_object(data, value)
57
+ )
58
+ else:
59
+ search_tasks[key] = asyncio.create_task(self._search(data, value))
64
60
 
65
61
  result: dict[str, Any | None] = {}
66
62
  for key, task in search_tasks.items():
@@ -74,17 +70,16 @@ class JQEntityProcessor(BaseEntityProcessor):
74
70
  async def _calculate_entities(
75
71
  self, mapping: ResourceConfig, raw_data: list[dict[str, Any]]
76
72
  ) -> list[Entity]:
77
- async def calculate_raw(data: dict[str, Any]) -> Entity:
73
+ async def calculate_raw(data: dict[str, Any]) -> dict[str, Any]:
78
74
  should_run = await self._search_as_bool(data, mapping.selector.query)
79
75
  if should_run and mapping.port.entity:
80
- return Entity.parse_obj(
81
- await self._search_as_object(
82
- data, mapping.port.entity.mappings.dict(exclude_unset=True)
83
- )
76
+ return await self._search_as_object(
77
+ data, mapping.port.entity.mappings.dict(exclude_unset=True)
84
78
  )
79
+ return {}
85
80
 
86
81
  entities_tasks = [asyncio.create_task(calculate_raw(data)) for data in raw_data]
87
- entities = asyncio.gather(*entities_tasks)
82
+ entities = await asyncio.gather(*entities_tasks)
88
83
 
89
84
  return [
90
85
  Entity.parse_obj(entity_data)
port_ocean/utils/cache.py CHANGED
@@ -1,14 +1,20 @@
1
1
  import functools
2
+ import hashlib
2
3
  from typing import Callable, AsyncIterator, Any
3
-
4
4
  from port_ocean.context.event import event
5
5
 
6
6
  AsyncIteratorCallable = Callable[..., AsyncIterator[list[Any]]]
7
7
 
8
8
 
9
- def cache_iterator_result(
10
- cache_key: str,
11
- ) -> Callable[[AsyncIteratorCallable], AsyncIteratorCallable]:
9
+ def hash_func(function_name: str, *args: Any, **kwargs: Any) -> str:
10
+ args_str = str(args)
11
+ kwargs_str = str(kwargs)
12
+ concatenated_string = args_str + kwargs_str
13
+ hash_object = hashlib.sha256(concatenated_string.encode())
14
+ return f"{function_name}_{hash_object.hexdigest()}"
15
+
16
+
17
+ def cache_iterator_result() -> Callable[[AsyncIteratorCallable], AsyncIteratorCallable]:
12
18
  """
13
19
  This decorator caches the results of an async iterator function. It checks if the result is already in the cache
14
20
  and if not, it fetches the all the data and caches it at ocean.attributes cache the end of the iteration.
@@ -18,9 +24,12 @@ def cache_iterator_result(
18
24
  For example, you can use this to cache data coming back from the third-party API to avoid making the same request
19
25
  multiple times for each kind.
20
26
 
27
+ The caching mechanism also detects changes in parameters.
28
+ If a function is called with different parameter values, it will be stored in different hash keys for each unique call.
29
+
21
30
  Usage:
22
31
  ```python
23
- @cache_iterator_result("my_cache_key")
32
+ @cache_iterator_result()
24
33
  async def my_async_iterator_function():
25
34
  # Your code here
26
35
  ```
@@ -29,6 +38,9 @@ def cache_iterator_result(
29
38
  def decorator(func: AsyncIteratorCallable) -> AsyncIteratorCallable:
30
39
  @functools.wraps(func)
31
40
  async def wrapper(*args: Any, **kwargs: Any) -> Any:
41
+ # Create Hash key from function name, args and kwargs
42
+ cache_key = hash_func(func.__name__, *args, **kwargs)
43
+
32
44
  # Check if the result is already in the cache
33
45
  if cache := event.attributes.get(cache_key):
34
46
  yield cache
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: port-ocean
3
- Version: 0.5.3rc1
3
+ Version: 0.5.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
@@ -79,7 +79,7 @@ port_ocean/core/handlers/entities_state_applier/port/order_by_entities_dependenc
79
79
  port_ocean/core/handlers/entities_state_applier/port/validate_entity_relations.py,sha256=nKuQ-RlalGG07olxm6l5NHeOuQT9dEZLoMpD-AN5nq0,1392
80
80
  port_ocean/core/handlers/entity_processor/__init__.py,sha256=FvFCunFg44wNQoqlybem9MthOs7p1Wawac87uSXz9U8,156
81
81
  port_ocean/core/handlers/entity_processor/base.py,sha256=3ucPc-esMI5M6gFl_l2j_ncEqOIe7m1bCH4rAXtGDzg,1710
82
- port_ocean/core/handlers/entity_processor/jq_entity_processor.py,sha256=hl3fPeKBlZBNsXt7oVShRhNDiMzsRaAEh5AS5zoiW10,4122
82
+ port_ocean/core/handlers/entity_processor/jq_entity_processor.py,sha256=R1oejEASXT9LWtJZ-HNKmd-vpPdyWt2HAq_GJTymO2o,3875
83
83
  port_ocean/core/handlers/port_app_config/__init__.py,sha256=8AAT5OthiVM7KCcM34iEgEeXtn2pRMrT4Dze5r1Ixbk,134
84
84
  port_ocean/core/handlers/port_app_config/api.py,sha256=6VbKPwFzsWG0IYsVD81hxSmfqtHUFqrfUuj1DBX5g4w,853
85
85
  port_ocean/core/handlers/port_app_config/base.py,sha256=nnMZ4jH6a-4Of9Cn-apMsU0CgNLD9avd5q0gRmc7nZ8,1495
@@ -117,13 +117,13 @@ port_ocean/run.py,sha256=vyShtqg_jEiE6M4SJpci6c4oRD9k2ztesAXEx_6Sc9M,1906
117
117
  port_ocean/sonar-project.properties,sha256=X_wLzDOkEVmpGLRMb2fg9Rb0DxWwUFSvESId8qpvrPI,73
118
118
  port_ocean/utils/__init__.py,sha256=KMGnCPXZJbNwtgxtyMycapkDz8tpSyw23MSYT3iVeHs,91
119
119
  port_ocean/utils/async_http.py,sha256=arnH458TExn2Dju_Sy6pHas_vF5RMWnOp-jBz5WAAcE,1226
120
- port_ocean/utils/cache.py,sha256=cXDl0mzvMhx-yyJIuk-flcdxSB5CmZg498jKUW19gTs,1640
120
+ port_ocean/utils/cache.py,sha256=3KItZDE2yVrbVDr-hoM8lNna8s2dlpxhP4ICdLjH4LQ,2231
121
121
  port_ocean/utils/misc.py,sha256=2XmO8W0SgPjV0rd9HZvrHhoMlHprIwmMFsINxlAmgyw,1723
122
122
  port_ocean/utils/repeat.py,sha256=0EFWM9d8lLXAhZmAyczY20LAnijw6UbIECf5lpGbOas,3231
123
123
  port_ocean/utils/signal.py,sha256=Fab0049Cjs69TPTQgvEvilaVZKACQr6tGkRdySjNCi8,1515
124
124
  port_ocean/version.py,sha256=UsuJdvdQlazzKGD3Hd5-U7N69STh8Dq9ggJzQFnu9fU,177
125
- port_ocean-0.5.3rc1.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
126
- port_ocean-0.5.3rc1.dist-info/METADATA,sha256=ECwwrFEeYjKhTP-A0qWFhaNFz9scerGDvGIUQao2Y10,6513
127
- port_ocean-0.5.3rc1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
128
- port_ocean-0.5.3rc1.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
129
- port_ocean-0.5.3rc1.dist-info/RECORD,,
125
+ port_ocean-0.5.5.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
126
+ port_ocean-0.5.5.dist-info/METADATA,sha256=626xjgEwjL3tRbdXoUR-P5rQc0eN2Ju0xOjIXznbuAo,6510
127
+ port_ocean-0.5.5.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
128
+ port_ocean-0.5.5.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
129
+ port_ocean-0.5.5.dist-info/RECORD,,