ayon-python-api 1.2.7__tar.gz → 1.2.8__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.7/ayon_python_api.egg-info → ayon_python_api-1.2.8}/PKG-INFO +1 -1
  2. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/__init__.py +4 -0
  3. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api.py +76 -0
  4. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/lists.py +44 -5
  5. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/constants.py +1 -4
  6. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/entity_hub.py +2 -0
  7. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/server_api.py +77 -3
  8. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/version.py +1 -1
  9. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8/ayon_python_api.egg-info}/PKG-INFO +1 -1
  10. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/pyproject.toml +1 -1
  11. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/LICENSE +0 -0
  12. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/README.md +0 -0
  13. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/__init__.py +0 -0
  14. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/actions.py +0 -0
  15. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/activities.py +0 -0
  16. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/attributes.py +0 -0
  17. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/base.py +0 -0
  18. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/bundles_addons.py +0 -0
  19. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/dependency_packages.py +0 -0
  20. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/events.py +0 -0
  21. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/folders.py +0 -0
  22. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/installers.py +0 -0
  23. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/links.py +0 -0
  24. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/products.py +0 -0
  25. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/projects.py +0 -0
  26. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/representations.py +0 -0
  27. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/secrets.py +0 -0
  28. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/tasks.py +0 -0
  29. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/thumbnails.py +0 -0
  30. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/versions.py +0 -0
  31. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/_api_helpers/workfiles.py +0 -0
  32. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/events.py +0 -0
  33. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/exceptions.py +0 -0
  34. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/graphql.py +0 -0
  35. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/graphql_queries.py +0 -0
  36. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/operations.py +0 -0
  37. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/typing.py +0 -0
  38. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_api/utils.py +0 -0
  39. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_python_api.egg-info/SOURCES.txt +0 -0
  40. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_python_api.egg-info/dependency_links.txt +0 -0
  41. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_python_api.egg-info/requires.txt +0 -0
  42. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/ayon_python_api.egg-info/top_level.txt +0 -0
  43. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/setup.cfg +0 -0
  44. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/setup.py +0 -0
  45. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/tests/test_entity_hub.py +0 -0
  46. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/tests/test_folder_hierarchy.py +0 -0
  47. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/tests/test_get_events.py +0 -0
  48. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/tests/test_graphql_queries.py +0 -0
  49. {ayon_python_api-1.2.7 → ayon_python_api-1.2.8}/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.7
3
+ Version: 1.2.8
4
4
  Summary: AYON Python API
5
5
  Home-page: https://github.com/ynput/ayon-python-api
6
6
  Author: ynput.io
@@ -70,6 +70,8 @@ from ._api import (
70
70
  delete,
71
71
  download_file_to_stream,
72
72
  download_file,
73
+ download_project_file,
74
+ download_project_file_to_stream,
73
75
  upload_file_from_stream,
74
76
  upload_file,
75
77
  upload_reviewable,
@@ -349,6 +351,8 @@ __all__ = (
349
351
  "delete",
350
352
  "download_file_to_stream",
351
353
  "download_file",
354
+ "download_project_file",
355
+ "download_project_file_to_stream",
352
356
  "upload_file_from_stream",
353
357
  "upload_file",
354
358
  "upload_reviewable",
@@ -992,6 +992,80 @@ def download_file(
992
992
  )
993
993
 
994
994
 
995
+ def download_project_file(
996
+ project_name: str,
997
+ file_id: str,
998
+ filepath: str,
999
+ *,
1000
+ chunk_size: Optional[int] = None,
1001
+ progress: Optional[TransferProgress] = None,
1002
+ ) -> TransferProgress:
1003
+ """Download project file to filepath.
1004
+
1005
+ Project files are usually binary files, such as images, videos,
1006
+ or other media files that can be accessed via api endpoint
1007
+ '{server url}/api/projects/{project_name}/files/{file_id}'.
1008
+
1009
+ Args:
1010
+ project_name (str): Project name.
1011
+ file_id (str): File id.
1012
+ filepath (str): Path where file will be downloaded.
1013
+ chunk_size (Optional[int]): Size of chunks that are received
1014
+ in single loop.
1015
+ progress (Optional[TransferProgress]): Object that gives ability
1016
+ to track download progress.
1017
+
1018
+ Returns:
1019
+ TransferProgress: Progress object.
1020
+
1021
+ """
1022
+ con = get_server_api_connection()
1023
+ return con.download_project_file(
1024
+ project_name=project_name,
1025
+ file_id=file_id,
1026
+ filepath=filepath,
1027
+ chunk_size=chunk_size,
1028
+ progress=progress,
1029
+ )
1030
+
1031
+
1032
+ def download_project_file_to_stream(
1033
+ project_name: str,
1034
+ file_id: str,
1035
+ stream: StreamType,
1036
+ *,
1037
+ chunk_size: Optional[int] = None,
1038
+ progress: Optional[TransferProgress] = None,
1039
+ ) -> TransferProgress:
1040
+ """Download project file to a stream.
1041
+
1042
+ Project files are usually binary files, such as images, videos,
1043
+ or other media files that can be accessed via api endpoint
1044
+ '{server url}/api/projects/{project_name}/files/{file_id}'.
1045
+
1046
+ Args:
1047
+ project_name (str): Project name.
1048
+ file_id (str): File id.
1049
+ stream (StreamType): Stream where output will be stored.
1050
+ chunk_size (Optional[int]): Size of chunks that are received
1051
+ in single loop.
1052
+ progress (Optional[TransferProgress]): Object that gives ability
1053
+ to track download progress.
1054
+
1055
+ Returns:
1056
+ TransferProgress: Progress object.
1057
+
1058
+ """
1059
+ con = get_server_api_connection()
1060
+ return con.download_project_file_to_stream(
1061
+ project_name=project_name,
1062
+ file_id=file_id,
1063
+ stream=stream,
1064
+ chunk_size=chunk_size,
1065
+ progress=progress,
1066
+ )
1067
+
1068
+
995
1069
  def upload_file_from_stream(
996
1070
  endpoint: str,
997
1071
  stream: StreamType,
@@ -4932,6 +5006,8 @@ def get_products(
4932
5006
  Use 'None' if folder is direct child of project.
4933
5007
  product_types (Optional[Iterable[str]]): Product types used for
4934
5008
  filtering.
5009
+ product_base_types (Optional[Iterable[str]]): Product base types
5010
+ used for filtering.
4935
5011
  product_name_regex (Optional[str]): Filter products by name regex.
4936
5012
  product_path_regex (Optional[str]): Filter products by path regex.
4937
5013
  Path starts with folder path and ends with product name.
@@ -26,7 +26,15 @@ class ListsAPI(BaseServerAPI):
26
26
  active: Optional[bool] = None,
27
27
  fields: Optional[Iterable[str]] = None,
28
28
  ) -> Generator[dict[str, Any], None, None]:
29
- """Fetch entity lists from server.
29
+ """Fetch entity lists from AYON server.
30
+
31
+ Warnings:
32
+ You can't get list items for lists with different 'entityType' in
33
+ one call.
34
+
35
+ Notes:
36
+ To get list items, you have to pass 'items' field or
37
+ 'items.{sub-fields you want}' to 'fields' argument.
30
38
 
31
39
  Args:
32
40
  project_name (str): Project name where entity lists are.
@@ -42,7 +50,30 @@ class ListsAPI(BaseServerAPI):
42
50
  """
43
51
  if fields is None:
44
52
  fields = self.get_default_fields_for_type("entityList")
45
- fields = set(fields)
53
+
54
+ # List does not have 'attrib' field but has 'allAttrib' field
55
+ # which is json string and contains only values that are set
56
+ o_fields = tuple(fields)
57
+ fields = set()
58
+ requires_attrib = False
59
+ for field in o_fields:
60
+ if field == "attrib" or field.startswith("attrib."):
61
+ requires_attrib = True
62
+ field = "allAttrib"
63
+ fields.add(field)
64
+
65
+ if "items" in fields:
66
+ fields.discard("items")
67
+ fields |= {
68
+ "items.id",
69
+ "items.entityId",
70
+ "items.entityType",
71
+ "items.position",
72
+ }
73
+
74
+ available_attribs = []
75
+ if requires_attrib:
76
+ available_attribs = self.get_attributes_for_type("list")
46
77
 
47
78
  if active is not None:
48
79
  fields.add("active")
@@ -66,6 +97,15 @@ class ListsAPI(BaseServerAPI):
66
97
  if isinstance(attributes, str):
67
98
  entity_list["attributes"] = json.loads(attributes)
68
99
 
100
+ if requires_attrib:
101
+ all_attrib = json.loads(
102
+ entity_list.get("allAttrib") or "{}"
103
+ )
104
+ entity_list["attrib"] = {
105
+ attrib_name: all_attrib.get(attrib_name)
106
+ for attrib_name in available_attribs
107
+ }
108
+
69
109
  self._convert_entity_data(entity_list)
70
110
 
71
111
  yield entity_list
@@ -170,9 +210,8 @@ class ListsAPI(BaseServerAPI):
170
210
  kwargs[key] = value
171
211
 
172
212
  response = self.post(
173
- f"projects/{project_name}/lists/{list_id}/items",
213
+ f"projects/{project_name}/lists",
174
214
  **kwargs
175
-
176
215
  )
177
216
  response.raise_for_status()
178
217
  return list_id
@@ -343,7 +382,7 @@ class ListsAPI(BaseServerAPI):
343
382
  mode (EntityListItemMode): Mode of items update.
344
383
 
345
384
  """
346
- response = self.post(
385
+ response = self.patch(
347
386
  f"projects/{project_name}/lists/{list_id}/items",
348
387
  items=items,
349
388
  mode=mode,
@@ -247,6 +247,7 @@ DEFAULT_ACTIVITY_FIELDS = {
247
247
  DEFAULT_ENTITY_LIST_FIELDS = {
248
248
  "id",
249
249
  "count",
250
+ "allAttrib",
250
251
  "attributes",
251
252
  "active",
252
253
  "createdBy",
@@ -259,8 +260,4 @@ DEFAULT_ENTITY_LIST_FIELDS = {
259
260
  "tags",
260
261
  "updatedAt",
261
262
  "updatedBy",
262
- "items.id",
263
- "items.entityId",
264
- "items.entityType",
265
- "items.position",
266
263
  }
@@ -1582,6 +1582,8 @@ class BaseEntity(ABC):
1582
1582
  self._tags = copy.deepcopy(tags)
1583
1583
  self._thumbnail_id = thumbnail_id
1584
1584
 
1585
+ if name == label:
1586
+ label = None
1585
1587
  self._orig_name = name
1586
1588
  self._orig_label = label
1587
1589
  self._orig_status = status
@@ -1377,9 +1377,11 @@ class ServerAPI(
1377
1377
  try:
1378
1378
  with get_func(url, **kwargs) as response:
1379
1379
  response.raise_for_status()
1380
- progress.set_content_size(
1381
- response.headers["Content-length"]
1382
- )
1380
+ if progress.get_content_size() is None:
1381
+ progress.set_content_size(
1382
+ response.headers["Content-length"]
1383
+ )
1384
+
1383
1385
  for chunk in response.iter_content(chunk_size=chunk_size):
1384
1386
  stream.write(chunk)
1385
1387
  progress.add_transferred_chunk(len(chunk))
@@ -1496,6 +1498,76 @@ class ServerAPI(
1496
1498
 
1497
1499
  return progress
1498
1500
 
1501
+ def download_project_file(
1502
+ self,
1503
+ project_name: str,
1504
+ file_id: str,
1505
+ filepath: str,
1506
+ *,
1507
+ chunk_size: Optional[int] = None,
1508
+ progress: Optional[TransferProgress] = None,
1509
+ ) -> TransferProgress:
1510
+ """Download project file to filepath.
1511
+
1512
+ Project files are usually binary files, such as images, videos,
1513
+ or other media files that can be accessed via api endpoint
1514
+ '{server url}/api/projects/{project_name}/files/{file_id}'.
1515
+
1516
+ Args:
1517
+ project_name (str): Project name.
1518
+ file_id (str): File id.
1519
+ filepath (str): Path where file will be downloaded.
1520
+ chunk_size (Optional[int]): Size of chunks that are received
1521
+ in single loop.
1522
+ progress (Optional[TransferProgress]): Object that gives ability
1523
+ to track download progress.
1524
+
1525
+ Returns:
1526
+ TransferProgress: Progress object.
1527
+
1528
+ """
1529
+ return self.download_file(
1530
+ f"api/projects/{project_name}/files/{file_id}",
1531
+ filepath,
1532
+ chunk_size=chunk_size,
1533
+ progress=progress,
1534
+ )
1535
+
1536
+ def download_project_file_to_stream(
1537
+ self,
1538
+ project_name: str,
1539
+ file_id: str,
1540
+ stream: StreamType,
1541
+ *,
1542
+ chunk_size: Optional[int] = None,
1543
+ progress: Optional[TransferProgress] = None,
1544
+ ) -> TransferProgress:
1545
+ """Download project file to a stream.
1546
+
1547
+ Project files are usually binary files, such as images, videos,
1548
+ or other media files that can be accessed via api endpoint
1549
+ '{server url}/api/projects/{project_name}/files/{file_id}'.
1550
+
1551
+ Args:
1552
+ project_name (str): Project name.
1553
+ file_id (str): File id.
1554
+ stream (StreamType): Stream where output will be stored.
1555
+ chunk_size (Optional[int]): Size of chunks that are received
1556
+ in single loop.
1557
+ progress (Optional[TransferProgress]): Object that gives ability
1558
+ to track download progress.
1559
+
1560
+ Returns:
1561
+ TransferProgress: Progress object.
1562
+
1563
+ """
1564
+ return self.download_file_to_stream(
1565
+ f"api/projects/{project_name}/files/{file_id}",
1566
+ stream,
1567
+ chunk_size=chunk_size,
1568
+ progress=progress,
1569
+ )
1570
+
1499
1571
  @staticmethod
1500
1572
  def _upload_chunks_iter(
1501
1573
  file_stream: StreamType,
@@ -1884,6 +1956,8 @@ class ServerAPI(
1884
1956
 
1885
1957
  elif entity_type == "entityList":
1886
1958
  entity_type_defaults = set(DEFAULT_ENTITY_LIST_FIELDS)
1959
+ # Attributes scope is 'list'
1960
+ entity_type = "list"
1887
1961
 
1888
1962
  else:
1889
1963
  raise ValueError(f"Unknown entity type \"{entity_type}\"")
@@ -1,2 +1,2 @@
1
1
  """Package declaring Python API for AYON server."""
2
- __version__ = "1.2.7"
2
+ __version__ = "1.2.8"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ayon_python_api
3
- Version: 1.2.7
3
+ Version: 1.2.8
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.7"
3
+ version = "1.2.8"
4
4
  description = "AYON Python API"
5
5
  license = {file = "LICENSE"}
6
6
  readme = {file = "README.md", content-type = "text/markdown"}
File without changes