ayon-python-api 1.2.22__tar.gz → 1.2.23__tar.gz

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.
Files changed (49) hide show
  1. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/PKG-INFO +1 -1
  2. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/__init__.py +2 -0
  3. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api.py +57 -9
  4. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/activities.py +7 -3
  5. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/base.py +1 -0
  6. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/links.py +101 -3
  7. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/lists.py +4 -4
  8. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/operations.py +27 -4
  9. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/server_api.py +16 -7
  10. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/typing.py +16 -1
  11. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/version.py +1 -1
  12. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_python_api.egg-info/PKG-INFO +1 -1
  13. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/pyproject.toml +2 -2
  14. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/LICENSE +0 -0
  15. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/README.md +0 -0
  16. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/__init__.py +0 -0
  17. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/actions.py +0 -0
  18. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/attributes.py +0 -0
  19. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/bundles_addons.py +0 -0
  20. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/dependency_packages.py +0 -0
  21. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/events.py +0 -0
  22. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/folders.py +0 -0
  23. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/installers.py +0 -0
  24. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/products.py +0 -0
  25. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/projects.py +0 -0
  26. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/representations.py +0 -0
  27. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/secrets.py +0 -0
  28. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/tasks.py +0 -0
  29. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/thumbnails.py +0 -0
  30. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/versions.py +0 -0
  31. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/_api_helpers/workfiles.py +0 -0
  32. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/constants.py +0 -0
  33. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/entity_hub.py +0 -0
  34. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/events.py +0 -0
  35. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/exceptions.py +0 -0
  36. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/graphql.py +0 -0
  37. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/graphql_queries.py +0 -0
  38. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_api/utils.py +0 -0
  39. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_python_api.egg-info/SOURCES.txt +0 -0
  40. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_python_api.egg-info/dependency_links.txt +0 -0
  41. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_python_api.egg-info/requires.txt +0 -0
  42. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/ayon_python_api.egg-info/top_level.txt +0 -0
  43. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/setup.cfg +0 -0
  44. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/setup.py +0 -0
  45. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/tests/test_entity_hub.py +0 -0
  46. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/tests/test_folder_hierarchy.py +0 -0
  47. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/tests/test_get_events.py +0 -0
  48. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/tests/test_graphql_queries.py +0 -0
  49. {ayon_python_api-1.2.22 → ayon_python_api-1.2.23}/tests/test_server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ayon_python_api
3
- Version: 1.2.22
3
+ Version: 1.2.23
4
4
  Summary: AYON Python API
5
5
  Home-page: https://github.com/ynput/ayon-python-api
6
6
  Author: ynput.io
@@ -275,6 +275,7 @@ from ._api import (
275
275
  delete_link_type,
276
276
  make_sure_link_type_exists,
277
277
  create_link,
278
+ create_links,
278
279
  delete_link,
279
280
  get_entities_links,
280
281
  get_folders_links,
@@ -594,6 +595,7 @@ __all__ = (
594
595
  "delete_link_type",
595
596
  "make_sure_link_type_exists",
596
597
  "create_link",
598
+ "create_links",
597
599
  "delete_link",
598
600
  "get_entities_links",
599
601
  "get_folders_links",
@@ -53,6 +53,8 @@ if typing.TYPE_CHECKING:
53
53
  BackgroundOperationTask,
54
54
  LinkDirection,
55
55
  CreateLinkData,
56
+ CreateLinkResponseData,
57
+ CreateLinksResponseItem,
56
58
  EventFilter,
57
59
  EventStatus,
58
60
  EnrollEventData,
@@ -1620,7 +1622,9 @@ def get_rest_entity_by_id(
1620
1622
  def send_batch_operations(
1621
1623
  project_name: str,
1622
1624
  operations: list[dict[str, Any]],
1625
+ *,
1623
1626
  can_fail: bool = False,
1627
+ wait_for_events: bool = False,
1624
1628
  raise_on_fail: bool = True,
1625
1629
  ) -> list[dict[str, Any]]:
1626
1630
  """Post multiple CRUD operations to server.
@@ -1635,6 +1639,7 @@ def send_batch_operations(
1635
1639
  operations (list[dict[str, Any]]): Operations to be processed.
1636
1640
  can_fail (bool): Server will try to process all
1637
1641
  operations even if one of them fails.
1642
+ wait_for_events (bool): Wait for events to be processed on server.
1638
1643
  raise_on_fail (bool): Raise exception if an operation
1639
1644
  fails. You can handle failed operations on your own
1640
1645
  when set to 'False'.
@@ -1653,6 +1658,7 @@ def send_batch_operations(
1653
1658
  project_name=project_name,
1654
1659
  operations=operations,
1655
1660
  can_fail=can_fail,
1661
+ wait_for_events=wait_for_events,
1656
1662
  raise_on_fail=raise_on_fail,
1657
1663
  )
1658
1664
 
@@ -1662,8 +1668,9 @@ def send_background_batch_operations(
1662
1668
  operations: list[dict[str, Any]],
1663
1669
  *,
1664
1670
  can_fail: bool = False,
1665
- wait: bool = False,
1671
+ wait_for_events: bool = False,
1666
1672
  raise_on_fail: bool = True,
1673
+ wait: bool = False,
1667
1674
  ) -> BackgroundOperationTask:
1668
1675
  """Post multiple CRUD operations to server.
1669
1676
 
@@ -1686,10 +1693,11 @@ def send_background_batch_operations(
1686
1693
  operations (list[dict[str, Any]]): Operations to be processed.
1687
1694
  can_fail (bool): Server will try to process all
1688
1695
  operations even if one of them fails.
1689
- wait (bool): Wait for operations to end.
1696
+ wait_for_events (bool): Wait for events to be processed on server.
1690
1697
  raise_on_fail (bool): Raise exception if an operation
1691
1698
  fails. You can handle failed operations on your own
1692
1699
  when set to 'False'. Used when 'wait' is enabled.
1700
+ wait (bool): Wait for operations to end.
1693
1701
 
1694
1702
  Raises:
1695
1703
  ValueError: Operations can't be converted to json string.
@@ -1705,8 +1713,9 @@ def send_background_batch_operations(
1705
1713
  project_name=project_name,
1706
1714
  operations=operations,
1707
1715
  can_fail=can_fail,
1708
- wait=wait,
1716
+ wait_for_events=wait_for_events,
1709
1717
  raise_on_fail=raise_on_fail,
1718
+ wait=wait,
1710
1719
  )
1711
1720
 
1712
1721
 
@@ -2708,7 +2717,9 @@ def set_entity_watchers(
2708
2717
  def send_activities_batch_operations(
2709
2718
  project_name: str,
2710
2719
  operations: list[dict[str, Any]],
2720
+ *,
2711
2721
  can_fail: bool = False,
2722
+ wait_for_events: bool = False,
2712
2723
  raise_on_fail: bool = True,
2713
2724
  ) -> list[dict[str, Any]]:
2714
2725
  """Post multiple CRUD activities operations to server.
@@ -2723,6 +2734,7 @@ def send_activities_batch_operations(
2723
2734
  operations (list[dict[str, Any]]): Operations to be processed.
2724
2735
  can_fail (Optional[bool]): Server will try to process all
2725
2736
  operations even if one of them fails.
2737
+ wait_for_events (bool): Wait for events to be processed on server.
2726
2738
  raise_on_fail (Optional[bool]): Raise exception if an operation
2727
2739
  fails. You can handle failed operations on your own
2728
2740
  when set to 'False'.
@@ -2741,6 +2753,7 @@ def send_activities_batch_operations(
2741
2753
  project_name=project_name,
2742
2754
  operations=operations,
2743
2755
  can_fail=can_fail,
2756
+ wait_for_events=wait_for_events,
2744
2757
  raise_on_fail=raise_on_fail,
2745
2758
  )
2746
2759
 
@@ -7504,7 +7517,7 @@ def create_link(
7504
7517
  output_type: str,
7505
7518
  link_name: Optional[str] = None,
7506
7519
  data: Optional[dict[str, Any]] = None,
7507
- ) -> CreateLinkData:
7520
+ ) -> CreateLinkResponseData:
7508
7521
  """Create link between 2 entities.
7509
7522
 
7510
7523
  Link has a type which must already exists on a project.
@@ -7527,7 +7540,7 @@ def create_link(
7527
7540
  with the link.
7528
7541
 
7529
7542
  Returns:
7530
- CreateLinkData: Information about link.
7543
+ CreateLinkResponseData: Information about link.
7531
7544
 
7532
7545
  Raises:
7533
7546
  HTTPRequestError: Server error happened.
@@ -7546,6 +7559,41 @@ def create_link(
7546
7559
  )
7547
7560
 
7548
7561
 
7562
+ def create_links(
7563
+ project_name: str,
7564
+ links: list[CreateLinkData],
7565
+ ) -> list[CreateLinksResponseItem]:
7566
+ """Create multiple links in a single request.
7567
+
7568
+ Example of link data::
7569
+ [
7570
+ {
7571
+ "input": "59a212c0d2e211eda0e20242ac120001",
7572
+ "output": "59a212c0d2e211eda0e20242ac120002",
7573
+ "linkType": "reference|folder|folder",
7574
+ "name": "my_link",
7575
+ "data": {"key": "value"}
7576
+ }
7577
+ ]
7578
+
7579
+ Args:
7580
+ project_name (str): Project where links are created.
7581
+ links (list[CreateLinkData]): List of link data.
7582
+
7583
+ Returns:
7584
+ list[CreateLinksResponseItem]: Information about created links.
7585
+
7586
+ Raises:
7587
+ ValueError: Link data is invalid.
7588
+
7589
+ """
7590
+ con = get_server_api_connection()
7591
+ return con.create_links(
7592
+ project_name=project_name,
7593
+ links=links,
7594
+ )
7595
+
7596
+
7549
7597
  def delete_link(
7550
7598
  project_name: str,
7551
7599
  link_id: str,
@@ -8003,8 +8051,8 @@ def create_entity_list(
8003
8051
  *,
8004
8052
  list_type: Optional[str] = None,
8005
8053
  access: Optional[dict[str, Any]] = None,
8006
- attrib: Optional[list[dict[str, Any]]] = None,
8007
- data: Optional[list[dict[str, Any]]] = None,
8054
+ attrib: Optional[dict[str, Any]] = None,
8055
+ data: Optional[dict[str, Any]] = None,
8008
8056
  tags: Optional[list[str]] = None,
8009
8057
  template: Optional[dict[str, Any]] = None,
8010
8058
  entity_list_folder_id: Optional[str] = None,
@@ -8060,8 +8108,8 @@ def update_entity_list(
8060
8108
  *,
8061
8109
  label: Optional[str] = None,
8062
8110
  access: Optional[dict[str, Any]] = None,
8063
- attrib: Optional[list[dict[str, Any]]] = None,
8064
- data: Optional[list[dict[str, Any]]] = None,
8111
+ attrib: Optional[dict[str, Any]] = None,
8112
+ data: Optional[dict[str, Any]] = None,
8065
8113
  tags: Optional[list[str]] = None,
8066
8114
  entity_list_folder_id: str | None | type[NOT_SET] = NOT_SET,
8067
8115
  owner: Optional[str] = None,
@@ -370,8 +370,10 @@ class ActivitiesAPI(BaseServerAPI):
370
370
  self,
371
371
  project_name: str,
372
372
  operations: list[dict[str, Any]],
373
+ *,
373
374
  can_fail: bool = False,
374
- raise_on_fail: bool = True
375
+ wait_for_events: bool = False,
376
+ raise_on_fail: bool = True,
375
377
  ) -> list[dict[str, Any]]:
376
378
  """Post multiple CRUD activities operations to server.
377
379
 
@@ -385,6 +387,7 @@ class ActivitiesAPI(BaseServerAPI):
385
387
  operations (list[dict[str, Any]]): Operations to be processed.
386
388
  can_fail (Optional[bool]): Server will try to process all
387
389
  operations even if one of them fails.
390
+ wait_for_events (bool): Wait for events to be processed on server.
388
391
  raise_on_fail (Optional[bool]): Raise exception if an operation
389
392
  fails. You can handle failed operations on your own
390
393
  when set to 'False'.
@@ -401,6 +404,7 @@ class ActivitiesAPI(BaseServerAPI):
401
404
  return self._send_batch_operations(
402
405
  f"projects/{project_name}/operations/activities",
403
406
  operations,
404
- can_fail,
405
- raise_on_fail,
407
+ can_fail=can_fail,
408
+ wait_for_events=wait_for_events,
409
+ raise_on_fail=raise_on_fail,
406
410
  )
@@ -167,6 +167,7 @@ class BaseServerAPI:
167
167
  uri: str,
168
168
  operations: list[dict[str, Any]],
169
169
  can_fail: bool,
170
+ wait_for_events: bool,
170
171
  raise_on_fail: bool
171
172
  ) -> list[dict[str, Any]]:
172
173
  raise NotImplementedError()
@@ -15,7 +15,12 @@ from ayon_api.graphql_queries import (
15
15
  from .base import BaseServerAPI
16
16
 
17
17
  if typing.TYPE_CHECKING:
18
- from ayon_api.typing import LinkDirection, CreateLinkData
18
+ from ayon_api.typing import (
19
+ LinkDirection,
20
+ CreateLinkData,
21
+ CreateLinkResponseData,
22
+ CreateLinksResponseItem,
23
+ )
19
24
 
20
25
 
21
26
  class LinksAPI(BaseServerAPI):
@@ -200,7 +205,7 @@ class LinksAPI(BaseServerAPI):
200
205
  output_type: str,
201
206
  link_name: Optional[str] = None,
202
207
  data: Optional[dict[str, Any]] = None,
203
- ) -> CreateLinkData:
208
+ ) -> CreateLinkResponseData:
204
209
  """Create link between 2 entities.
205
210
 
206
211
  Link has a type which must already exists on a project.
@@ -223,7 +228,7 @@ class LinksAPI(BaseServerAPI):
223
228
  with the link.
224
229
 
225
230
  Returns:
226
- CreateLinkData: Information about link.
231
+ CreateLinkResponseData: Information about link.
227
232
 
228
233
  Raises:
229
234
  HTTPRequestError: Server error happened.
@@ -249,6 +254,70 @@ class LinksAPI(BaseServerAPI):
249
254
  response.raise_for_status()
250
255
  return response.data
251
256
 
257
+ def create_links(
258
+ self,
259
+ project_name: str,
260
+ links: list[CreateLinkData],
261
+ ) -> list[CreateLinksResponseItem]:
262
+ """Create multiple links in a single request.
263
+
264
+ Example of link data::
265
+ [
266
+ {
267
+ "input": "59a212c0d2e211eda0e20242ac120001",
268
+ "output": "59a212c0d2e211eda0e20242ac120002",
269
+ "linkType": "reference|folder|folder",
270
+ "name": "my_link",
271
+ "data": {"key": "value"}
272
+ }
273
+ ]
274
+
275
+ Args:
276
+ project_name (str): Project where links are created.
277
+ links (list[CreateLinkData]): List of link data.
278
+
279
+ Returns:
280
+ list[CreateLinksResponseItem]: Information about created links.
281
+
282
+ Raises:
283
+ ValueError: Link data is invalid.
284
+
285
+ """
286
+ if not links:
287
+ return []
288
+
289
+ for link in links:
290
+ self._validate_link_data(link)
291
+
292
+ if self.get_server_version_tuple() < (1, 15, 8):
293
+ created_links = []
294
+ for link in links:
295
+ link_type, in_type, out_type = link["linkType"].split("|")
296
+ data = self.create_link(
297
+ project_name,
298
+ link_type,
299
+ link["input"],
300
+ in_type,
301
+ link["output"],
302
+ out_type,
303
+ link_name=link.get("name") or None,
304
+ data=link.get("data") or None,
305
+ )
306
+ created_links.append({
307
+ "id": data["id"],
308
+ "input": link["input"],
309
+ "output": link["output"],
310
+ "linkType": link["linkType"]
311
+ })
312
+ return created_links
313
+
314
+ response = self.post(
315
+ f"projects/{project_name}/links/bulk",
316
+ links=links
317
+ )
318
+ response.raise_for_status()
319
+ return response.data["created"]
320
+
252
321
  def delete_link(self, project_name: str, link_id: str) -> None:
253
322
  """Remove link by id.
254
323
 
@@ -619,6 +688,35 @@ class LinksAPI(BaseServerAPI):
619
688
  project_name, [representation_id], link_types, link_direction
620
689
  )[representation_id]
621
690
 
691
+ def _validate_link_data(self, link_data: dict[str, Any]) -> None:
692
+ """Validate link data before sending to server.
693
+
694
+ Args:
695
+ link_data (dict[str, Any]): Link data to validate.
696
+
697
+ Raises:
698
+ ValueError: Link data is invalid.
699
+
700
+ """
701
+ required_keys = {"input", "output", "linkType"}
702
+ missing_keys = required_keys - link_data.keys()
703
+ if missing_keys:
704
+ mk = ", ".join(f"'{key}'" for key in sorted(missing_keys))
705
+ raise ValueError(f"Missing required keys in link data: {mk}")
706
+
707
+ link_type = link_data["linkType"]
708
+ if not isinstance(link_type, str):
709
+ raise ValueError(
710
+ f"Invalid linkType type: {type(link_type)}. Expected 'str'"
711
+ )
712
+
713
+ link_type_parts = link_type.split("|")
714
+ if len(link_type_parts) != 3:
715
+ raise ValueError(
716
+ f"Invalid linkType format: {link_type}. Expected format:"
717
+ " 'link_type|input_type|output_type'"
718
+ )
719
+
622
720
  def _prepare_link_filters(
623
721
  self,
624
722
  filters: dict[str, Any],
@@ -157,8 +157,8 @@ class ListsAPI(BaseServerAPI):
157
157
  *,
158
158
  list_type: Optional[str] = None,
159
159
  access: Optional[dict[str, Any]] = None,
160
- attrib: Optional[list[dict[str, Any]]] = None,
161
- data: Optional[list[dict[str, Any]]] = None,
160
+ attrib: Optional[dict[str, Any]] = None,
161
+ data: Optional[dict[str, Any]] = None,
162
162
  tags: Optional[list[str]] = None,
163
163
  template: Optional[dict[str, Any]] = None,
164
164
  entity_list_folder_id: Optional[str] = None,
@@ -225,8 +225,8 @@ class ListsAPI(BaseServerAPI):
225
225
  *,
226
226
  label: Optional[str] = None,
227
227
  access: Optional[dict[str, Any]] = None,
228
- attrib: Optional[list[dict[str, Any]]] = None,
229
- data: Optional[list[dict[str, Any]]] = None,
228
+ attrib: Optional[dict[str, Any]] = None,
229
+ data: Optional[dict[str, Any]] = None,
230
230
  tags: Optional[list[str]] = None,
231
231
  entity_list_folder_id: str | None | type[NOT_SET] = NOT_SET,
232
232
  owner: Optional[str] = None,
@@ -741,12 +741,21 @@ class OperationsSession(object):
741
741
  Args:
742
742
  con (Optional[ServerAPI]): Connection to server. Global connection
743
743
  is used if not passed.
744
+ wait_for_events (bool): Wait for events to be processed on server.
745
+ Default value of the argument. Can be changed when 'commit'
746
+ is called.
744
747
 
745
748
  """
746
- def __init__(self, con: Optional[ServerAPI] = None) -> None:
749
+ def __init__(
750
+ self,
751
+ con: Optional[ServerAPI] = None,
752
+ *,
753
+ wait_for_events: bool = False,
754
+ ) -> None:
747
755
  if con is None:
748
756
  con = get_server_api_connection()
749
757
  self._con = con
758
+ self._wait_for_events = wait_for_events
750
759
  self._project_cache = {}
751
760
  self._operations = []
752
761
  self._nested_operations = collections.defaultdict(list)
@@ -817,8 +826,15 @@ class OperationsSession(object):
817
826
  for operation in self._operations
818
827
  ]
819
828
 
820
- def commit(self) -> None:
821
- """Commit session operations."""
829
+ def commit(self, *, wait_for_events: bool | None = None) -> None:
830
+ """Commit session operations.
831
+
832
+ Args:
833
+ wait_for_events (bool | None): Wait for events to be processed
834
+ on server. Use 'None' to use the default value defined on
835
+ OperationsSession object.
836
+
837
+ """
822
838
  operations, self._operations = self._operations, []
823
839
  if not operations:
824
840
  return
@@ -827,6 +843,9 @@ class OperationsSession(object):
827
843
  for operation in operations:
828
844
  operations_by_project[operation.project_name].append(operation)
829
845
 
846
+ if wait_for_events is None:
847
+ wait_for_events = self._wait_for_events
848
+
830
849
  for project_name, operations in operations_by_project.items():
831
850
  operations_body = []
832
851
  for operation in operations:
@@ -835,7 +854,11 @@ class OperationsSession(object):
835
854
  operations_body.append(body)
836
855
 
837
856
  self._con.send_background_batch_operations(
838
- project_name, operations_body, wait=True, can_fail=False
857
+ project_name,
858
+ operations_body,
859
+ can_fail=False,
860
+ wait_for_events=wait_for_events,
861
+ wait=True,
839
862
  )
840
863
 
841
864
  def create_entity(
@@ -2475,7 +2475,9 @@ class ServerAPI(
2475
2475
  self,
2476
2476
  project_name: str,
2477
2477
  operations: list[dict[str, Any]],
2478
+ *,
2478
2479
  can_fail: bool = False,
2480
+ wait_for_events: bool = False,
2479
2481
  raise_on_fail: bool = True,
2480
2482
  ) -> list[dict[str, Any]]:
2481
2483
  """Post multiple CRUD operations to server.
@@ -2490,6 +2492,7 @@ class ServerAPI(
2490
2492
  operations (list[dict[str, Any]]): Operations to be processed.
2491
2493
  can_fail (bool): Server will try to process all
2492
2494
  operations even if one of them fails.
2495
+ wait_for_events (bool): Wait for events to be processed on server.
2493
2496
  raise_on_fail (bool): Raise exception if an operation
2494
2497
  fails. You can handle failed operations on your own
2495
2498
  when set to 'False'.
@@ -2506,8 +2509,9 @@ class ServerAPI(
2506
2509
  return self._send_batch_operations(
2507
2510
  f"projects/{project_name}/operations",
2508
2511
  operations,
2509
- can_fail,
2510
- raise_on_fail,
2512
+ can_fail=can_fail,
2513
+ wait_for_events=wait_for_events,
2514
+ raise_on_fail=raise_on_fail,
2511
2515
  )
2512
2516
 
2513
2517
  def send_background_batch_operations(
@@ -2516,8 +2520,9 @@ class ServerAPI(
2516
2520
  operations: list[dict[str, Any]],
2517
2521
  *,
2518
2522
  can_fail: bool = False,
2519
- wait: bool = False,
2523
+ wait_for_events: bool = False,
2520
2524
  raise_on_fail: bool = True,
2525
+ wait: bool = False,
2521
2526
  ) -> BackgroundOperationTask:
2522
2527
  """Post multiple CRUD operations to server.
2523
2528
 
@@ -2540,10 +2545,11 @@ class ServerAPI(
2540
2545
  operations (list[dict[str, Any]]): Operations to be processed.
2541
2546
  can_fail (bool): Server will try to process all
2542
2547
  operations even if one of them fails.
2543
- wait (bool): Wait for operations to end.
2548
+ wait_for_events (bool): Wait for events to be processed on server.
2544
2549
  raise_on_fail (bool): Raise exception if an operation
2545
2550
  fails. You can handle failed operations on your own
2546
2551
  when set to 'False'. Used when 'wait' is enabled.
2552
+ wait (bool): Wait for operations to end.
2547
2553
 
2548
2554
  Raises:
2549
2555
  ValueError: Operations can't be converted to json string.
@@ -2558,7 +2564,8 @@ class ServerAPI(
2558
2564
  response = self.post(
2559
2565
  f"projects/{project_name}/operations/background",
2560
2566
  operations=operations_body,
2561
- canFail=can_fail
2567
+ canFail=can_fail,
2568
+ waitForEvents=wait_for_events,
2562
2569
  )
2563
2570
  response.raise_for_status()
2564
2571
  if not wait:
@@ -2631,7 +2638,8 @@ class ServerAPI(
2631
2638
  uri: str,
2632
2639
  operations: list[dict[str, Any]],
2633
2640
  can_fail: bool,
2634
- raise_on_fail: bool
2641
+ wait_for_events: bool,
2642
+ raise_on_fail: bool,
2635
2643
  ) -> list[dict[str, Any]]:
2636
2644
  if not operations:
2637
2645
  return []
@@ -2643,7 +2651,8 @@ class ServerAPI(
2643
2651
  response = self.post(
2644
2652
  uri,
2645
2653
  operations=operations_body,
2646
- canFail=can_fail
2654
+ canFail=can_fail,
2655
+ waitForEvents=wait_for_events,
2647
2656
  )
2648
2657
 
2649
2658
  op_results = response.get("operations")
@@ -127,8 +127,23 @@ AttributeType = Literal[
127
127
  LinkDirection = Literal["in", "out"]
128
128
 
129
129
 
130
- class CreateLinkData(TypedDict):
130
+ class CreateLinkResponseData(TypedDict):
131
+ id: str
132
+
133
+
134
+ class CreateLinksResponseItem(TypedDict):
131
135
  id: str
136
+ input: str
137
+ output: str
138
+ linkType: str
139
+
140
+
141
+ class CreateLinkData(TypedDict):
142
+ input: str
143
+ output: str
144
+ linkType: str
145
+ data: NotRequired[dict[str, Any] | None]
146
+ name: NotRequired[str | None]
132
147
 
133
148
 
134
149
  class AttributeEnumItemDict(TypedDict):
@@ -1,2 +1,2 @@
1
1
  """Package declaring Python API for AYON server."""
2
- __version__ = "1.2.22"
2
+ __version__ = "1.2.23"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ayon_python_api
3
- Version: 1.2.22
3
+ Version: 1.2.23
4
4
  Summary: AYON Python API
5
5
  Home-page: https://github.com/ynput/ayon-python-api
6
6
  Author: ynput.io
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ayon_python_api"
3
- version = "1.2.22"
3
+ version = "1.2.23"
4
4
  description = "AYON Python API"
5
5
  license = {file = "LICENSE"}
6
6
  readme = {file = "README.md", content-type = "text/markdown"}
@@ -28,7 +28,7 @@ build-backend = "poetry.core.masonry.api"
28
28
 
29
29
  [tool.poetry]
30
30
  name = "ayon_python_api"
31
- version = "1.2.22"
31
+ version = "1.2.23"
32
32
  description = "AYON Python API"
33
33
  authors = [
34
34
  "ynput.io <info@ynput.io>"