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

@@ -82,12 +82,10 @@ class BlueprintClientMixin:
82
82
  handle_status_code(response, should_raise)
83
83
  return response.json().get("migrationId", "")
84
84
 
85
- async def create_action(
86
- self, blueprint_identifier: str, action: dict[str, Any]
87
- ) -> None:
85
+ async def create_action(self, action: dict[str, Any]) -> None:
88
86
  logger.info(f"Creating action: {action}")
89
87
  response = await self.client.post(
90
- f"{self.auth.api_url}/blueprints/{blueprint_identifier}/actions",
88
+ f"{self.auth.api_url}/actions",
91
89
  json=action,
92
90
  headers=await self.auth.headers(),
93
91
  )
@@ -29,7 +29,7 @@ class EntityClientMixin:
29
29
  request_options: RequestOptions,
30
30
  user_agent_type: UserAgentType | None = None,
31
31
  should_raise: bool = True,
32
- ) -> None:
32
+ ) -> Entity:
33
33
  validation_only = request_options["validation_only"]
34
34
  async with self.semaphore:
35
35
  logger.debug(
@@ -57,6 +57,12 @@ class EntityClientMixin:
57
57
  f"blueprint: {entity.blueprint}"
58
58
  )
59
59
  handle_status_code(response, should_raise)
60
+ result = response.json()
61
+ result_entity = Entity.parse_obj(result)
62
+ # Set the results of the search relation and identifier to the entity
63
+ entity.identifier = result_entity.identifier or entity.identifier
64
+ entity.relations = result_entity.relations or entity.relations
65
+ return entity
60
66
 
61
67
  async def batch_upsert_entities(
62
68
  self,
@@ -64,8 +70,8 @@ class EntityClientMixin:
64
70
  request_options: RequestOptions,
65
71
  user_agent_type: UserAgentType | None = None,
66
72
  should_raise: bool = True,
67
- ) -> None:
68
- await asyncio.gather(
73
+ ) -> list[Entity]:
74
+ modified_entities_results = await asyncio.gather(
69
75
  *(
70
76
  self.upsert_entity(
71
77
  entity,
@@ -75,8 +81,19 @@ class EntityClientMixin:
75
81
  )
76
82
  for entity in entities
77
83
  ),
78
- return_exceptions=True,
84
+ return_exceptions=should_raise,
79
85
  )
86
+ entity_results = [
87
+ entity for entity in modified_entities_results if isinstance(entity, Entity)
88
+ ]
89
+ if not should_raise:
90
+ return entity_results
91
+
92
+ for entity_result in modified_entities_results:
93
+ if isinstance(entity_result, Exception):
94
+ raise entity_result
95
+
96
+ return entity_results
80
97
 
81
98
  async def delete_entity(
82
99
  self,
@@ -24,7 +24,7 @@ class Preset(TypedDict):
24
24
 
25
25
  class Defaults(BaseModel):
26
26
  blueprints: list[dict[str, Any]] = []
27
- actions: list[Preset] = []
27
+ actions: list[dict[str, Any]] = []
28
28
  scorecards: list[Preset] = []
29
29
  pages: list[dict[str, Any]] = []
30
30
  port_app_config: Optional[PortAppConfig] = Field(
@@ -21,7 +21,7 @@ from port_ocean.exceptions.port_defaults import (
21
21
 
22
22
 
23
23
  def deconstruct_blueprints_to_creation_steps(
24
- raw_blueprints: list[dict[str, Any]]
24
+ raw_blueprints: list[dict[str, Any]],
25
25
  ) -> tuple[list[dict[str, Any]], ...]:
26
26
  """
27
27
  Deconstructing the blueprint into stages so the api wont fail to create a blueprint if there is a conflict
@@ -154,11 +154,7 @@ async def _create_resources(
154
154
  )
155
155
 
156
156
  await asyncio.gather(
157
- *(
158
- port_client.create_action(blueprint_actions["blueprint"], action)
159
- for blueprint_actions in defaults.actions
160
- for action in blueprint_actions["data"]
161
- )
157
+ *(port_client.create_action(action) for action in defaults.actions)
162
158
  )
163
159
 
164
160
  await asyncio.gather(
@@ -47,12 +47,15 @@ class BaseEntitiesStateApplier(BaseHandler):
47
47
  @abstractmethod
48
48
  async def upsert(
49
49
  self, entities: list[Entity], user_agent_type: UserAgentType
50
- ) -> None:
50
+ ) -> list[Entity]:
51
51
  """Upsert (insert or update) the given entities into the state.
52
52
 
53
53
  Args:
54
54
  entities (list[Entity]): The entities to be upserted.
55
55
  user_agent_type (UserAgentType): The user agent responsible for the upsert.
56
+
57
+ Returns:
58
+ list[Entity]: The upserted entities.
56
59
  """
57
60
  pass
58
61
 
@@ -71,9 +71,9 @@ class HttpEntitiesStateApplier(BaseEntitiesStateApplier):
71
71
  logger.info(
72
72
  f"Updating entity diff (created: {len(diff.created)}, deleted: {len(diff.deleted)}, modified: {len(diff.modified)})"
73
73
  )
74
- await self.upsert(kept_entities, user_agent_type)
74
+ modified_entities = await self.upsert(kept_entities, user_agent_type)
75
75
 
76
- await self._safe_delete(diff.deleted, kept_entities, user_agent_type)
76
+ await self._safe_delete(diff.deleted, modified_entities, user_agent_type)
77
77
 
78
78
  async def delete_diff(
79
79
  self,
@@ -95,10 +95,11 @@ class HttpEntitiesStateApplier(BaseEntitiesStateApplier):
95
95
 
96
96
  async def upsert(
97
97
  self, entities: list[Entity], user_agent_type: UserAgentType
98
- ) -> None:
98
+ ) -> list[Entity]:
99
99
  logger.info(f"Upserting {len(entities)} entities")
100
+ modified_entities: list[Entity] = []
100
101
  if event.port_app_config.create_missing_related_entities:
101
- await self.context.port_client.batch_upsert_entities(
102
+ modified_entities = await self.context.port_client.batch_upsert_entities(
102
103
  entities,
103
104
  event.port_app_config.get_port_request_options(),
104
105
  user_agent_type,
@@ -108,14 +109,16 @@ class HttpEntitiesStateApplier(BaseEntitiesStateApplier):
108
109
  ordered_created_entities = reversed(
109
110
  order_by_entities_dependencies(entities)
110
111
  )
111
-
112
112
  for entity in ordered_created_entities:
113
- await self.context.port_client.upsert_entity(
114
- entity,
115
- event.port_app_config.get_port_request_options(),
116
- user_agent_type,
117
- should_raise=False,
113
+ modified_entities.append(
114
+ await self.context.port_client.upsert_entity(
115
+ entity,
116
+ event.port_app_config.get_port_request_options(),
117
+ user_agent_type,
118
+ should_raise=False,
119
+ )
118
120
  )
121
+ return modified_entities
119
122
 
120
123
  async def delete(
121
124
  self, entities: list[Entity], user_agent_type: UserAgentType
@@ -97,9 +97,11 @@ class SyncMixin(HandlerMixin):
97
97
  """
98
98
  entities_at_port = await ocean.port_client.search_entities(user_agent_type)
99
99
 
100
- await self.entities_state_applier.upsert(entities, user_agent_type)
100
+ modified_entities = await self.entities_state_applier.upsert(
101
+ entities, user_agent_type
102
+ )
101
103
  await self.entities_state_applier.delete_diff(
102
- {"before": entities_at_port, "after": entities}, user_agent_type
104
+ {"before": entities_at_port, "after": modified_entities}, user_agent_type
103
105
  )
104
106
 
105
107
  logger.info("Finished syncing change")
@@ -140,11 +140,13 @@ class SyncRawMixin(HandlerMixin, EventsMixin):
140
140
  objects_diff = await self._calculate_raw(
141
141
  [(resource, results)], parse_all, send_raw_data_examples_amount
142
142
  )
143
- await self.entities_state_applier.upsert(
143
+ modified_objects = await self.entities_state_applier.upsert(
144
144
  objects_diff[0].entity_selector_diff.passed, user_agent_type
145
145
  )
146
-
147
- return objects_diff[0]
146
+ return CalculationResult(
147
+ objects_diff[0].entity_selector_diff._replace(passed=modified_objects),
148
+ errors=objects_diff[0].errors,
149
+ )
148
150
 
149
151
  async def _unregister_resource_raw(
150
152
  self,
@@ -418,6 +420,7 @@ class SyncRawMixin(HandlerMixin, EventsMixin):
418
420
  )
419
421
  logger.info(f"Resync will use the following mappings: {app_config.dict()}")
420
422
  try:
423
+ did_fetched_current_state = True
421
424
  entities_at_port = await ocean.port_client.search_entities(
422
425
  user_agent_type
423
426
  )
@@ -429,7 +432,7 @@ class SyncRawMixin(HandlerMixin, EventsMixin):
429
432
  f"Response status code: {e.response.status_code if isinstance(e, httpx.HTTPStatusError) else None}\n"
430
433
  f"Response content: {e.response.text if isinstance(e, httpx.HTTPStatusError) else None}\n"
431
434
  )
432
- entities_at_port = []
435
+ did_fetched_current_state = False
433
436
 
434
437
  creation_results: list[tuple[list[Entity], list[Exception]]] = []
435
438
 
@@ -448,7 +451,7 @@ class SyncRawMixin(HandlerMixin, EventsMixin):
448
451
  except asyncio.CancelledError as e:
449
452
  logger.warning("Resync aborted successfully")
450
453
  else:
451
- if not entities_at_port:
454
+ if not did_fetched_current_state:
452
455
  logger.warning(
453
456
  "Due to an error before the resync, the previous state of entities at Port is unknown."
454
457
  " Skipping delete phase due to unknown initial state."
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: port-ocean
3
- Version: 0.9.10
3
+ Version: 0.9.13
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
@@ -38,8 +38,8 @@ port_ocean/clients/port/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
38
38
  port_ocean/clients/port/authentication.py,sha256=t3z6h4vld-Tzkpth15sstaMJg0rccX-pXXjNtOa-nCY,2949
39
39
  port_ocean/clients/port/client.py,sha256=3GYCM0ZkX3pB6sNoOb-7_6dm0Jr5_vqhflD9iltf_As,2640
40
40
  port_ocean/clients/port/mixins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
- port_ocean/clients/port/mixins/blueprints.py,sha256=BiqkhvDFdkySWgL1NHI-LAQ9ieZWazZAojPo9E8d7U4,4575
42
- port_ocean/clients/port/mixins/entities.py,sha256=pMERHqy1keb5w2k2xQsNuyZaKSAZ5ijVA4pzxEbAatY,7365
41
+ port_ocean/clients/port/mixins/blueprints.py,sha256=8ZVC5i8K1WKQMJJiPqZmgcOlF3OyxWz1aAQ_WA5UW3c,4500
42
+ port_ocean/clients/port/mixins/entities.py,sha256=j3YqLb1zMmJrIutYsYsZ_WCT4xh9VXEIH1A0kYMUUtk,8104
43
43
  port_ocean/clients/port/mixins/integrations.py,sha256=Ro6h9BwLxglQWniCVmfC---4oyGuUxk_Qejswl2t-J8,4841
44
44
  port_ocean/clients/port/mixins/migrations.py,sha256=A6896oJF6WbFL2WroyTkMzr12yhVyWqGoq9dtLNSKBY,1457
45
45
  port_ocean/clients/port/retry_transport.py,sha256=PtIZOAZ6V-ncpVysRUsPOgt8Sf01QLnTKB5YeKBxkJk,1861
@@ -58,8 +58,8 @@ port_ocean/context/resource.py,sha256=yDj63URzQelj8zJPh4BAzTtPhpKr9Gw9DRn7I_0mJ1
58
58
  port_ocean/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
59
  port_ocean/core/defaults/__init__.py,sha256=8qCZg8n06WAdMu9s_FiRtDYLGPGHbOuS60vapeUoAks,142
60
60
  port_ocean/core/defaults/clean.py,sha256=S3UAfca-oU89WJKIB4OgGjGjPr0vxBQ2aRZsLTZhQ04,2185
61
- port_ocean/core/defaults/common.py,sha256=QnLFTkT3yIWIRtLQb7fUvvfe5AfInYJy0q5LjlzHkOw,3553
62
- port_ocean/core/defaults/initialize.py,sha256=DSY7kbSHQxs6-4ZAK3QYw-kVRsYq5txX7mUjkUB20Qw,8865
61
+ port_ocean/core/defaults/common.py,sha256=uVUg6VEn4RqtXQwLwMNGfkmT5zYRN_h5USfKw3poVyo,3561
62
+ port_ocean/core/defaults/initialize.py,sha256=U1JWdpG_snAyqBXEikCjA7JzL7UtpOyx5rLfPhrBIZk,8721
63
63
  port_ocean/core/event_listener/__init__.py,sha256=mzJ33wRq0kh60fpVdOHVmvMTUQIvz3vxmifyBgwDn0E,889
64
64
  port_ocean/core/event_listener/base.py,sha256=4RujgPz4VfDFlviu4qLGJFnJougSCL-Ewf0rfTQfwgc,1133
65
65
  port_ocean/core/event_listener/factory.py,sha256=AYYfSHPAF7P5H-uQECXT0JVJjKDHrYkWJJBSL4mGkg8,3697
@@ -70,9 +70,9 @@ port_ocean/core/event_listener/polling.py,sha256=3UxjgQJly5y-hA8R798oFWb7bFsYMxS
70
70
  port_ocean/core/handlers/__init__.py,sha256=d7ShmS90gLRzGKJA6oNy2Zs_dF2yjkmYZInRhBnO9Rw,572
71
71
  port_ocean/core/handlers/base.py,sha256=cTarblazu8yh8xz2FpB-dzDKuXxtoi143XJgPbV_DcM,157
72
72
  port_ocean/core/handlers/entities_state_applier/__init__.py,sha256=kgLZDCeCEzi4r-0nzW9k78haOZNf6PX7mJOUr34A4c8,173
73
- port_ocean/core/handlers/entities_state_applier/base.py,sha256=FMsrBOVgaO4o7B1klLDY8fobTUDvyrerCKCICyYtkXs,2193
73
+ port_ocean/core/handlers/entities_state_applier/base.py,sha256=5wHL0icfFAYRPqk8iV_wN49GdJ3aRUtO8tumSxBi4Wo,2268
74
74
  port_ocean/core/handlers/entities_state_applier/port/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
- port_ocean/core/handlers/entities_state_applier/port/applier.py,sha256=G6RyPgBAyUcP41ySKaiXhKQhdrz8NixEEwsnU5q_-0c,5225
75
+ port_ocean/core/handlers/entities_state_applier/port/applier.py,sha256=fZzaz8idbZQhYz_dqohNvoRWGdET_cYHZDenQmnkdCA,5438
76
76
  port_ocean/core/handlers/entities_state_applier/port/get_related_entities.py,sha256=1zncwCbE-Gej0xaWKlzZgoXxOBe9bgs_YxlZ8QW3NdI,1751
77
77
  port_ocean/core/handlers/entities_state_applier/port/order_by_entities_dependencies.py,sha256=82BvU8t5w9uhsxX8hbnwuRPuWhW3cMeuT_5sVIkip1I,1550
78
78
  port_ocean/core/handlers/entity_processor/__init__.py,sha256=FvFCunFg44wNQoqlybem9MthOs7p1Wawac87uSXz9U8,156
@@ -87,8 +87,8 @@ port_ocean/core/integrations/base.py,sha256=KHsRYFZ38ff3AkkqIQu45883ovgKOJn_fZfn
87
87
  port_ocean/core/integrations/mixins/__init__.py,sha256=FA1FEKMM6P-L2_m7Q4L20mFa4_RgZnwSRmTCreKcBVM,220
88
88
  port_ocean/core/integrations/mixins/events.py,sha256=Ddfx2L4FpghV38waF8OfVeOV0bHBxNIgjU-q5ffillI,2341
89
89
  port_ocean/core/integrations/mixins/handler.py,sha256=mZ7-0UlG3LcrwJttFbMe-R4xcOU2H_g33tZar7PwTv8,3771
90
- port_ocean/core/integrations/mixins/sync.py,sha256=TKqRytxXONVhuCo3CB3rDvWNbITnZz33TYTDs3SWWVk,3880
91
- port_ocean/core/integrations/mixins/sync_raw.py,sha256=-51SLY9jlNOBYQP1FWnKheJb3xkKQny9mP0Op_g04Dg,18158
90
+ port_ocean/core/integrations/mixins/sync.py,sha256=B9fEs8faaYLLikH9GBjE_E61vo0bQDjIGQsQ1SRXOlA,3931
91
+ port_ocean/core/integrations/mixins/sync_raw.py,sha256=2vyHhGWyPchVfSUKRRfSJ2XsX55ygLWCFrKDaqkNd0o,18386
92
92
  port_ocean/core/integrations/mixins/utils.py,sha256=7y1rGETZIjOQadyIjFJXIHKkQFKx_SwiP-TrAIsyyLY,2303
93
93
  port_ocean/core/models.py,sha256=4bDvMeydlSpG0YSXjE1Bo2AcZC0aQ2zqFhpsOvZat_A,1190
94
94
  port_ocean/core/ocean_types.py,sha256=3_d8-n626f1kWLQ_Jxw194LEyrOVupz05qs_Y1pvB-A,990
@@ -122,8 +122,8 @@ port_ocean/utils/queue_utils.py,sha256=KWWl8YVnG-glcfIHhM6nefY-2sou_C6DVP1VynQwz
122
122
  port_ocean/utils/repeat.py,sha256=0EFWM9d8lLXAhZmAyczY20LAnijw6UbIECf5lpGbOas,3231
123
123
  port_ocean/utils/signal.py,sha256=K-6kKFQTltcmKDhtyZAcn0IMa3sUpOHGOAUdWKgx0_E,1369
124
124
  port_ocean/version.py,sha256=UsuJdvdQlazzKGD3Hd5-U7N69STh8Dq9ggJzQFnu9fU,177
125
- port_ocean-0.9.10.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
126
- port_ocean-0.9.10.dist-info/METADATA,sha256=dJEiCZBIoy0PErAsLASdKqs8VN-BHcU0qoPUmOLm3zc,6616
127
- port_ocean-0.9.10.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
128
- port_ocean-0.9.10.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
129
- port_ocean-0.9.10.dist-info/RECORD,,
125
+ port_ocean-0.9.13.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
126
+ port_ocean-0.9.13.dist-info/METADATA,sha256=R4G-A12rA_TwQDsgzcL7ppXQAAcsy2tyAnxygAanwk0,6616
127
+ port_ocean-0.9.13.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
128
+ port_ocean-0.9.13.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
129
+ port_ocean-0.9.13.dist-info/RECORD,,